forked from OSchip/llvm-project
Modified the LocateMacOSXFilesUsingDebugSymbols(...) function to locate
an executable file if it is right next to a dSYM file that is found using DebugSymbols. The code also looks into a bundle if the dSYM file is right next to a bundle. Modified the MacOSX kernel dynamic loader plug-in to correctly set the load address for kext sections. This is a tad tricky because of how LLDB chooses to treat mach-o segments with no name. Also modified the loader to properly handle the older version 1 kext summary info. Fixed a crasher in the Mach-o object file parser when it is trying to set the section size correctly for dSYM sections. Added packet dumpers to the CommunicationKDP class. We now also properly detect address byte sizes based on the cpu type and subtype that is provided. Added a read memory and read register support to CommunicationKDP. Added a ThreadKDP class that now uses subclasses of the RegisterContextDarwin_XXX for arm, i386 and x86_64. Fixed some register numbering issues in the RegisterContextDarwin_arm class and added ARM GDB numbers to the ARM_GCC_Registers.h file. Change the RegisterContextMach_XXX classes over to subclassing their RegisterContextDarwin_XXX counterparts so we can share the mach register contexts between the user and kernel plug-ins. llvm-svn: 135466
This commit is contained in:
parent
e4e9a590d2
commit
a63d08c9ff
|
@ -12,18 +12,19 @@
|
|||
260E07C8136FAB9200CF21D3 /* OptionGroupFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 260E07C7136FAB9200CF21D3 /* OptionGroupFile.cpp */; };
|
||||
261744781168585B005ADD65 /* SBType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 261744771168585B005ADD65 /* SBType.cpp */; };
|
||||
2617447A11685869005ADD65 /* SBType.h in Headers */ = {isa = PBXBuildFile; fileRef = 2617447911685869005ADD65 /* SBType.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
2628A4D513D4977900F5487A /* ThreadKDP.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2628A4D313D4977900F5487A /* ThreadKDP.cpp */; };
|
||||
262CFC7711A4510000946C6C /* debugserver in Resources */ = {isa = PBXBuildFile; fileRef = 26CE05A0115C31E50022F371 /* debugserver */; };
|
||||
26368A3C126B697600E8659F /* darwin-debug.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26368A3B126B697600E8659F /* darwin-debug.cpp */; };
|
||||
26368AF7126B960500E8659F /* darwin-debug in Resources */ = {isa = PBXBuildFile; fileRef = 26579F68126A25920007C5CB /* darwin-debug */; };
|
||||
263E949F13661AEA00E7D1CE /* UnwindAssembly-x86.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 263E949D13661AE400E7D1CE /* UnwindAssembly-x86.cpp */; };
|
||||
2642FBAE13D003B400ED6808 /* CommunicationKDP.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2642FBA813D003B400ED6808 /* CommunicationKDP.cpp */; };
|
||||
2642FBAF13D003B400ED6808 /* CommunicationKDP.h in Headers */ = {isa = PBXBuildFile; fileRef = 2642FBA913D003B400ED6808 /* CommunicationKDP.h */; };
|
||||
2642FBB013D003B400ED6808 /* ProcessKDP.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2642FBAA13D003B400ED6808 /* ProcessKDP.cpp */; };
|
||||
2642FBB113D003B400ED6808 /* ProcessKDP.h in Headers */ = {isa = PBXBuildFile; fileRef = 2642FBAB13D003B400ED6808 /* ProcessKDP.h */; };
|
||||
2642FBB213D003B400ED6808 /* ProcessKDPLog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2642FBAC13D003B400ED6808 /* ProcessKDPLog.cpp */; };
|
||||
2642FBB313D003B400ED6808 /* ProcessKDPLog.h in Headers */ = {isa = PBXBuildFile; fileRef = 2642FBAD13D003B400ED6808 /* ProcessKDPLog.h */; };
|
||||
264A97BF133918BC0017F0BE /* PlatformRemoteGDBServer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 264A97BD133918BC0017F0BE /* PlatformRemoteGDBServer.cpp */; };
|
||||
264D8D5013661BD7003A368F /* UnwindAssembly.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 264D8D4F13661BD7003A368F /* UnwindAssembly.cpp */; };
|
||||
265205A813D3E3F700132FE2 /* RegisterContextKDP_arm.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 265205A213D3E3F700132FE2 /* RegisterContextKDP_arm.cpp */; };
|
||||
265205AA13D3E3F700132FE2 /* RegisterContextKDP_i386.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 265205A413D3E3F700132FE2 /* RegisterContextKDP_i386.cpp */; };
|
||||
265205AC13D3E3F700132FE2 /* RegisterContextKDP_x86_64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 265205A613D3E3F700132FE2 /* RegisterContextKDP_x86_64.cpp */; };
|
||||
265ABF6310F42EE900531910 /* DebugSymbols.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 265ABF6210F42EE900531910 /* DebugSymbols.framework */; };
|
||||
26651A18133BF9E0005B64B7 /* Opcode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26651A17133BF9DF005B64B7 /* Opcode.cpp */; };
|
||||
266603CA1345B5A8004DA8B6 /* ConnectionSharedMemory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 266603C91345B5A8004DA8B6 /* ConnectionSharedMemory.cpp */; };
|
||||
|
@ -73,6 +74,7 @@
|
|||
2671A0D013482601003A87BB /* ConnectionMachPort.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2671A0CF13482601003A87BB /* ConnectionMachPort.cpp */; };
|
||||
26744EF11338317700EF765A /* GDBRemoteCommunicationClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26744EED1338317700EF765A /* GDBRemoteCommunicationClient.cpp */; };
|
||||
26744EF31338317700EF765A /* GDBRemoteCommunicationServer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26744EEF1338317700EF765A /* GDBRemoteCommunicationServer.cpp */; };
|
||||
2676045A13D49D2300AB1B6A /* ProcessControl-mig.defs in Sources */ = {isa = PBXBuildFile; fileRef = 260C89A110F57C5600BB2B04 /* ProcessControl-mig.defs */; settings = {ATTRIBUTES = (Client, Server, ); }; };
|
||||
267C012B136880DF006E963E /* OptionGroupValueObjectDisplay.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 267C012A136880DF006E963E /* OptionGroupValueObjectDisplay.cpp */; };
|
||||
267C01371368C49C006E963E /* OptionGroupOutputFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BCFC531368B3E4006DC050 /* OptionGroupOutputFile.cpp */; };
|
||||
2686536C1370ACB200D186A3 /* OptionGroupBoolean.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2686536B1370ACB200D186A3 /* OptionGroupBoolean.cpp */; };
|
||||
|
@ -342,6 +344,9 @@
|
|||
268F9D55123AA16600B91E9B /* SBSymbolContextList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 268F9D54123AA16600B91E9B /* SBSymbolContextList.cpp */; };
|
||||
2690B3711381D5C300ECFBAE /* Memory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2690B3701381D5C300ECFBAE /* Memory.cpp */; };
|
||||
2692BA15136610C100F9E14D /* UnwindAssemblyInstEmulation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2692BA13136610C100F9E14D /* UnwindAssemblyInstEmulation.cpp */; };
|
||||
26957D9813D381C900670048 /* RegisterContextDarwin_arm.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26957D9213D381C900670048 /* RegisterContextDarwin_arm.cpp */; };
|
||||
26957D9A13D381C900670048 /* RegisterContextDarwin_i386.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26957D9413D381C900670048 /* RegisterContextDarwin_i386.cpp */; };
|
||||
26957D9C13D381C900670048 /* RegisterContextDarwin_x86_64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26957D9613D381C900670048 /* RegisterContextDarwin_x86_64.cpp */; };
|
||||
2697A54D133A6305004E4240 /* PlatformDarwin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2697A54B133A6305004E4240 /* PlatformDarwin.cpp */; };
|
||||
26A69C5F137A17A500262477 /* RegisterValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C6886E137880C400407EDF /* RegisterValue.cpp */; };
|
||||
26A7A035135E6E4200FB369E /* NamedOptionValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26A7A034135E6E4200FB369E /* NamedOptionValue.cpp */; };
|
||||
|
@ -425,7 +430,6 @@
|
|||
9A3576AA116E9AC700E8ED2F /* SBHostOS.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9A3576A9116E9AC700E8ED2F /* SBHostOS.cpp */; };
|
||||
9A4F35101368A51A00823F52 /* StreamAsynchronousIO.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9A4F350F1368A51A00823F52 /* StreamAsynchronousIO.cpp */; };
|
||||
9A9E1EFF1398086D005AC039 /* InputReaderStack.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9A9E1EFE1398086D005AC039 /* InputReaderStack.cpp */; };
|
||||
9A9E1F0113980943005AC039 /* InputReaderStack.h in Headers */ = {isa = PBXBuildFile; fileRef = 9A9E1F0013980943005AC039 /* InputReaderStack.h */; };
|
||||
9AA69DA61188F52100D753A0 /* PseudoTerminal.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2682F16A115EDA0D00CCFF99 /* PseudoTerminal.cpp */; };
|
||||
9AA69DAF118A023300D753A0 /* SBInputReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 9AA69DAE118A023300D753A0 /* SBInputReader.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
9AA69DB1118A024600D753A0 /* SBInputReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9AA69DB0118A024600D753A0 /* SBInputReader.cpp */; };
|
||||
|
@ -639,6 +643,8 @@
|
|||
26217930133BC8640083B112 /* lldb-private-types.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "lldb-private-types.h"; path = "include/lldb/lldb-private-types.h"; sourceTree = "<group>"; };
|
||||
26217932133BCB850083B112 /* lldb-private-enumerations.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "lldb-private-enumerations.h"; path = "include/lldb/lldb-private-enumerations.h"; sourceTree = "<group>"; };
|
||||
2623096E13D0EFFB006381D9 /* StreamBuffer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = StreamBuffer.h; path = include/lldb/Core/StreamBuffer.h; sourceTree = "<group>"; };
|
||||
2628A4D313D4977900F5487A /* ThreadKDP.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ThreadKDP.cpp; sourceTree = "<group>"; };
|
||||
2628A4D413D4977900F5487A /* ThreadKDP.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ThreadKDP.h; sourceTree = "<group>"; };
|
||||
263664921140A4930075843B /* Debugger.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; name = Debugger.cpp; path = source/Core/Debugger.cpp; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.cpp; };
|
||||
263664941140A4C10075843B /* Debugger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; name = Debugger.h; path = include/lldb/Core/Debugger.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
|
||||
26368A3B126B697600E8659F /* darwin-debug.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "darwin-debug.cpp"; path = "tools/darwin-debug/darwin-debug.cpp"; sourceTree = "<group>"; };
|
||||
|
@ -664,6 +670,12 @@
|
|||
264AD83911095BBD00E0B039 /* CommandObjectLog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CommandObjectLog.h; path = source/Commands/CommandObjectLog.h; sourceTree = "<group>"; };
|
||||
264D8D4E13661BCC003A368F /* UnwindAssembly.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = UnwindAssembly.h; path = include/lldb/Target/UnwindAssembly.h; sourceTree = "<group>"; };
|
||||
264D8D4F13661BD7003A368F /* UnwindAssembly.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = UnwindAssembly.cpp; path = source/Target/UnwindAssembly.cpp; sourceTree = "<group>"; };
|
||||
265205A213D3E3F700132FE2 /* RegisterContextKDP_arm.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RegisterContextKDP_arm.cpp; sourceTree = "<group>"; };
|
||||
265205A313D3E3F700132FE2 /* RegisterContextKDP_arm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RegisterContextKDP_arm.h; sourceTree = "<group>"; };
|
||||
265205A413D3E3F700132FE2 /* RegisterContextKDP_i386.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RegisterContextKDP_i386.cpp; sourceTree = "<group>"; };
|
||||
265205A513D3E3F700132FE2 /* RegisterContextKDP_i386.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RegisterContextKDP_i386.h; sourceTree = "<group>"; };
|
||||
265205A613D3E3F700132FE2 /* RegisterContextKDP_x86_64.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RegisterContextKDP_x86_64.cpp; sourceTree = "<group>"; };
|
||||
265205A713D3E3F700132FE2 /* RegisterContextKDP_x86_64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RegisterContextKDP_x86_64.h; sourceTree = "<group>"; };
|
||||
26579F68126A25920007C5CB /* darwin-debug */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "darwin-debug"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
265ABF6210F42EE900531910 /* DebugSymbols.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = DebugSymbols.framework; path = /System/Library/PrivateFrameworks/DebugSymbols.framework; sourceTree = "<absolute>"; };
|
||||
265E9BE1115C2BAA00D0DCCB /* debugserver.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = debugserver.xcodeproj; path = tools/debugserver/debugserver.xcodeproj; sourceTree = "<group>"; };
|
||||
|
@ -729,6 +741,12 @@
|
|||
2692BA14136610C100F9E14D /* UnwindAssemblyInstEmulation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UnwindAssemblyInstEmulation.h; sourceTree = "<group>"; };
|
||||
269416AD119A024800FF2715 /* CommandObjectTarget.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CommandObjectTarget.cpp; path = source/Commands/CommandObjectTarget.cpp; sourceTree = "<group>"; };
|
||||
269416AE119A024800FF2715 /* CommandObjectTarget.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CommandObjectTarget.h; path = source/Commands/CommandObjectTarget.h; sourceTree = "<group>"; };
|
||||
26957D9213D381C900670048 /* RegisterContextDarwin_arm.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RegisterContextDarwin_arm.cpp; path = Utility/RegisterContextDarwin_arm.cpp; sourceTree = "<group>"; };
|
||||
26957D9313D381C900670048 /* RegisterContextDarwin_arm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RegisterContextDarwin_arm.h; path = Utility/RegisterContextDarwin_arm.h; sourceTree = "<group>"; };
|
||||
26957D9413D381C900670048 /* RegisterContextDarwin_i386.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RegisterContextDarwin_i386.cpp; path = Utility/RegisterContextDarwin_i386.cpp; sourceTree = "<group>"; };
|
||||
26957D9513D381C900670048 /* RegisterContextDarwin_i386.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RegisterContextDarwin_i386.h; path = Utility/RegisterContextDarwin_i386.h; sourceTree = "<group>"; };
|
||||
26957D9613D381C900670048 /* RegisterContextDarwin_x86_64.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RegisterContextDarwin_x86_64.cpp; path = Utility/RegisterContextDarwin_x86_64.cpp; sourceTree = "<group>"; };
|
||||
26957D9713D381C900670048 /* RegisterContextDarwin_x86_64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RegisterContextDarwin_x86_64.h; path = Utility/RegisterContextDarwin_x86_64.h; sourceTree = "<group>"; };
|
||||
2697A54B133A6305004E4240 /* PlatformDarwin.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PlatformDarwin.cpp; sourceTree = "<group>"; };
|
||||
2697A54C133A6305004E4240 /* PlatformDarwin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlatformDarwin.h; sourceTree = "<group>"; };
|
||||
269FF07D12494F7D00225026 /* FuncUnwinders.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FuncUnwinders.h; path = include/lldb/Symbol/FuncUnwinders.h; sourceTree = "<group>"; };
|
||||
|
@ -1746,6 +1764,14 @@
|
|||
2642FBAB13D003B400ED6808 /* ProcessKDP.h */,
|
||||
2642FBAC13D003B400ED6808 /* ProcessKDPLog.cpp */,
|
||||
2642FBAD13D003B400ED6808 /* ProcessKDPLog.h */,
|
||||
265205A213D3E3F700132FE2 /* RegisterContextKDP_arm.cpp */,
|
||||
265205A313D3E3F700132FE2 /* RegisterContextKDP_arm.h */,
|
||||
265205A413D3E3F700132FE2 /* RegisterContextKDP_i386.cpp */,
|
||||
265205A513D3E3F700132FE2 /* RegisterContextKDP_i386.h */,
|
||||
265205A613D3E3F700132FE2 /* RegisterContextKDP_x86_64.cpp */,
|
||||
265205A713D3E3F700132FE2 /* RegisterContextKDP_x86_64.h */,
|
||||
2628A4D313D4977900F5487A /* ThreadKDP.cpp */,
|
||||
2628A4D413D4977900F5487A /* ThreadKDP.h */,
|
||||
);
|
||||
path = "MacOSX-Kernel";
|
||||
sourceTree = "<group>";
|
||||
|
@ -1888,6 +1914,12 @@
|
|||
B28058A2139988C6002D96D0 /* InferiorCallPOSIX.h */,
|
||||
AF68D32F1255A110002FF25B /* UnwindLLDB.cpp */,
|
||||
AF68D3301255A110002FF25B /* UnwindLLDB.h */,
|
||||
26957D9213D381C900670048 /* RegisterContextDarwin_arm.cpp */,
|
||||
26957D9313D381C900670048 /* RegisterContextDarwin_arm.h */,
|
||||
26957D9413D381C900670048 /* RegisterContextDarwin_i386.cpp */,
|
||||
26957D9513D381C900670048 /* RegisterContextDarwin_i386.h */,
|
||||
26957D9613D381C900670048 /* RegisterContextDarwin_x86_64.cpp */,
|
||||
26957D9713D381C900670048 /* RegisterContextDarwin_x86_64.h */,
|
||||
AF68D2541255416E002FF25B /* RegisterContextLLDB.cpp */,
|
||||
AF68D2551255416E002FF25B /* RegisterContextLLDB.h */,
|
||||
26E3EEF811A994E800FBADB6 /* RegisterContextMacOSXFrameBackchain.h */,
|
||||
|
@ -2713,10 +2745,6 @@
|
|||
isa = PBXHeadersBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
9A9E1F0113980943005AC039 /* InputReaderStack.h in Headers */,
|
||||
2642FBAF13D003B400ED6808 /* CommunicationKDP.h in Headers */,
|
||||
2642FBB113D003B400ED6808 /* ProcessKDP.h in Headers */,
|
||||
2642FBB313D003B400ED6808 /* ProcessKDPLog.h in Headers */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
@ -3313,6 +3341,14 @@
|
|||
2642FBAE13D003B400ED6808 /* CommunicationKDP.cpp in Sources */,
|
||||
2642FBB013D003B400ED6808 /* ProcessKDP.cpp in Sources */,
|
||||
2642FBB213D003B400ED6808 /* ProcessKDPLog.cpp in Sources */,
|
||||
26957D9813D381C900670048 /* RegisterContextDarwin_arm.cpp in Sources */,
|
||||
26957D9A13D381C900670048 /* RegisterContextDarwin_i386.cpp in Sources */,
|
||||
26957D9C13D381C900670048 /* RegisterContextDarwin_x86_64.cpp in Sources */,
|
||||
265205A813D3E3F700132FE2 /* RegisterContextKDP_arm.cpp in Sources */,
|
||||
265205AA13D3E3F700132FE2 /* RegisterContextKDP_i386.cpp in Sources */,
|
||||
265205AC13D3E3F700132FE2 /* RegisterContextKDP_x86_64.cpp in Sources */,
|
||||
2628A4D513D4977900F5487A /* ThreadKDP.cpp in Sources */,
|
||||
2676045A13D49D2300AB1B6A /* ProcessControl-mig.defs in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
|
|
@ -746,7 +746,9 @@ ModuleList::GetSharedModule
|
|||
|
||||
// Fixup the incoming path in case the path points to a valid file, yet
|
||||
// the arch or UUID (if one was passed in) don't match.
|
||||
FileSpec file_spec = Symbols::LocateExecutableObjectFile (&in_file_spec, arch.IsValid() ? &arch : NULL, uuid_ptr);
|
||||
FileSpec file_spec = Symbols::LocateExecutableObjectFile (in_file_spec ? &in_file_spec : NULL,
|
||||
arch.IsValid() ? &arch : NULL,
|
||||
uuid_ptr);
|
||||
|
||||
// Don't look for the file if it appears to be the same one we already
|
||||
// checked for above...
|
||||
|
|
|
@ -29,6 +29,9 @@
|
|||
#include "Host/macosx/cfcpp/CFCString.h"
|
||||
#include "mach/machine.h"
|
||||
|
||||
#include "CFCBundle.h"
|
||||
|
||||
|
||||
using namespace lldb;
|
||||
using namespace lldb_private;
|
||||
using namespace llvm::MachO;
|
||||
|
@ -291,7 +294,7 @@ LocateMacOSXFilesUsingDebugSymbols
|
|||
const UInt8 *module_uuid = (const UInt8 *)uuid->GetBytes();
|
||||
if (module_uuid != NULL)
|
||||
{
|
||||
CFCReleaser<CFUUIDRef> module_uuid_ref(::CFUUIDCreateWithBytes ( NULL,
|
||||
CFCReleaser<CFUUIDRef> module_uuid_ref(::CFUUIDCreateWithBytes (NULL,
|
||||
module_uuid[0],
|
||||
module_uuid[1],
|
||||
module_uuid[2],
|
||||
|
@ -366,6 +369,57 @@ LocateMacOSXFilesUsingDebugSymbols
|
|||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// No dictionary, check near the dSYM bundle for an executable that matches...
|
||||
if (::CFURLGetFileSystemRepresentation (dsym_url.get(), true, (UInt8*)path, sizeof(path)-1))
|
||||
{
|
||||
char *dsym_extension_pos = ::strstr (path, ".dSYM");
|
||||
if (dsym_extension_pos)
|
||||
{
|
||||
*dsym_extension_pos = '\0';
|
||||
FileSpec file_spec (path, true);
|
||||
switch (file_spec.GetFileType())
|
||||
{
|
||||
case FileSpec::eFileTypeDirectory: // Bundle directory?
|
||||
{
|
||||
CFCBundle bundle (path);
|
||||
CFCReleaser<CFURLRef> bundle_exe_url (bundle.CopyExecutableURL ());
|
||||
if (bundle_exe_url.get())
|
||||
{
|
||||
if (::CFURLGetFileSystemRepresentation (bundle_exe_url.get(), true, (UInt8*)path, sizeof(path)-1))
|
||||
{
|
||||
FileSpec bundle_exe_file_spec (path, true);
|
||||
|
||||
if (FileAtPathContainsArchAndUUID (bundle_exe_file_spec, arch, uuid))
|
||||
{
|
||||
++items_found;
|
||||
*out_exec_fspec = bundle_exe_file_spec;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case FileSpec::eFileTypePipe: // Forget pipes
|
||||
case FileSpec::eFileTypeSocket: // We can't process socket files
|
||||
case FileSpec::eFileTypeInvalid: // File doesn't exist...
|
||||
break;
|
||||
|
||||
case FileSpec::eFileTypeUnknown:
|
||||
case FileSpec::eFileTypeRegular:
|
||||
case FileSpec::eFileTypeSymbolicLink:
|
||||
case FileSpec::eFileTypeOther:
|
||||
if (FileAtPathContainsArchAndUUID (file_spec, arch, uuid))
|
||||
{
|
||||
++items_found;
|
||||
*out_exec_fspec = file_spec;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -241,8 +241,8 @@ DynamicLoaderMacOSXKernel::FindTargetModule (OSKextLoadedKextSummary &image_info
|
|||
if (image_info_uuid_is_valid)
|
||||
{
|
||||
image_info.module_sp = m_process->GetTarget().GetSharedModule (FileSpec(),
|
||||
arch,
|
||||
&image_info.uuid);
|
||||
arch,
|
||||
&image_info.uuid);
|
||||
if (did_create_ptr)
|
||||
*did_create_ptr = image_info.module_sp;
|
||||
}
|
||||
|
@ -306,26 +306,48 @@ DynamicLoaderMacOSXKernel::UpdateImageLoadAddress (OSKextLoadedKextSummary& info
|
|||
uint32_t num_segments = info.segments.size();
|
||||
for (uint32_t i=0; i<num_segments; ++i)
|
||||
{
|
||||
SectionSP section_sp(section_list->FindSectionByName(info.segments[i].name));
|
||||
const addr_t new_section_load_addr = info.segments[i].vmaddr;
|
||||
if (section_sp)
|
||||
if (section_list->FindSectionByName(info.segments[i].name))
|
||||
{
|
||||
const addr_t old_section_load_addr = m_process->GetTarget().GetSectionLoadList().GetSectionLoadAddress (section_sp.get());
|
||||
if (old_section_load_addr == LLDB_INVALID_ADDRESS ||
|
||||
old_section_load_addr != new_section_load_addr)
|
||||
SectionSP section_sp(section_list->FindSectionByName(info.segments[i].name));
|
||||
if (section_sp)
|
||||
{
|
||||
if (m_process->GetTarget().GetSectionLoadList().SetSectionLoadAddress (section_sp.get(), new_section_load_addr))
|
||||
changed = true;
|
||||
const addr_t old_section_load_addr = m_process->GetTarget().GetSectionLoadList().GetSectionLoadAddress (section_sp.get());
|
||||
if (old_section_load_addr == LLDB_INVALID_ADDRESS ||
|
||||
old_section_load_addr != new_section_load_addr)
|
||||
{
|
||||
if (m_process->GetTarget().GetSectionLoadList().SetSectionLoadAddress (section_sp.get(), new_section_load_addr))
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf (stderr,
|
||||
"warning: unable to find and load segment named '%s' at 0x%llx in '%s/%s' in macosx dynamic loader plug-in.\n",
|
||||
info.segments[i].name.AsCString("<invalid>"),
|
||||
(uint64_t)new_section_load_addr,
|
||||
image_object_file->GetFileSpec().GetDirectory().AsCString(),
|
||||
image_object_file->GetFileSpec().GetFilename().AsCString());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf (stderr,
|
||||
"warning: unable to find and load segment named '%s' at 0x%llx in '%s/%s' in macosx dynamic loader plug-in.\n",
|
||||
info.segments[i].name.AsCString("<invalid>"),
|
||||
(uint64_t)new_section_load_addr,
|
||||
image_object_file->GetFileSpec().GetDirectory().AsCString(),
|
||||
image_object_file->GetFileSpec().GetFilename().AsCString());
|
||||
// The segment name is empty which means this is a .o file.
|
||||
// Object files in LLDB end up getting reorganized so that
|
||||
// the segment name that is in the section is promoted into
|
||||
// an actual segment, so we just need to go through all sections
|
||||
// and slide them by a single amount.
|
||||
|
||||
uint32_t num_sections = section_list->GetSize();
|
||||
for (uint32_t i=0; i<num_sections; ++i)
|
||||
{
|
||||
Section* section = section_list->GetSectionAtIndex (i).get();
|
||||
if (section)
|
||||
{
|
||||
if (m_process->GetTarget().GetSectionLoadList().SetSectionLoadAddress (section, section->GetFileAddress() + new_section_load_addr))
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -442,10 +464,17 @@ DynamicLoaderMacOSXKernel::ReadKextSummaryHeader ()
|
|||
if (bytes_read == count)
|
||||
{
|
||||
uint32_t offset = 0;
|
||||
m_kext_summary_header.version = data.GetU32(&offset);
|
||||
m_kext_summary_header.entry_size = data.GetU32(&offset);
|
||||
m_kext_summary_header.entry_count = data.GetU32(&offset);
|
||||
m_kext_summary_header.reserved = data.GetU32(&offset);
|
||||
m_kext_summary_header.version = data.GetU32(&offset);
|
||||
if (m_kext_summary_header.version >= 2)
|
||||
{
|
||||
m_kext_summary_header.entry_size = data.GetU32(&offset);
|
||||
}
|
||||
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);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -472,14 +501,14 @@ DynamicLoaderMacOSXKernel::ParseKextSummaries (const Address &kext_summary_addr,
|
|||
|
||||
for (uint32_t i = 0; i < count; i++)
|
||||
{
|
||||
if (!kext_summaries[i].UUIDValid())
|
||||
DataExtractor data; // Load command data
|
||||
if (ReadMachHeader (kext_summaries[i], &data))
|
||||
{
|
||||
DataExtractor data; // Load command data
|
||||
if (!ReadMachHeader (kext_summaries[i], &data))
|
||||
continue;
|
||||
|
||||
ParseLoadCommands (data, kext_summaries[i]);
|
||||
}
|
||||
|
||||
if (log)
|
||||
kext_summaries[i].PutToLog (log.get());
|
||||
}
|
||||
bool return_value = AddModulesUsingImageInfos (kext_summaries);
|
||||
return return_value;
|
||||
|
@ -560,11 +589,14 @@ DynamicLoaderMacOSXKernel::ReadKextSummaries (const Address &kext_summary_addr,
|
|||
error);
|
||||
if (bytes_read == count)
|
||||
{
|
||||
uint32_t offset = 0;
|
||||
|
||||
DataExtractor extractor (data.GetBytes(), data.GetByteSize(), endian, addr_size);
|
||||
uint32_t i=0;
|
||||
for (; i < image_infos.size() && extractor.ValidOffsetForDataOfSize(offset, m_kext_summary_header.entry_size); ++i)
|
||||
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)
|
||||
{
|
||||
uint32_t offset = kext_summary_offset;
|
||||
const void *name_data = extractor.GetData(&offset, KERNEL_MODULE_MAX_NAME);
|
||||
if (name_data == NULL)
|
||||
break;
|
||||
|
@ -577,7 +609,14 @@ DynamicLoaderMacOSXKernel::ReadKextSummaries (const Address &kext_summary_addr,
|
|||
image_infos[i].version = extractor.GetU64(&offset);
|
||||
image_infos[i].load_tag = extractor.GetU32(&offset);
|
||||
image_infos[i].flags = extractor.GetU32(&offset);
|
||||
image_infos[i].reference_list = extractor.GetU64(&offset);
|
||||
if ((offset - kext_summary_offset) < m_kext_summary_header.entry_size)
|
||||
{
|
||||
image_infos[i].reference_list = extractor.GetU64(&offset);
|
||||
}
|
||||
else
|
||||
{
|
||||
image_infos[i].reference_list = 0;
|
||||
}
|
||||
}
|
||||
if (i < image_infos.size())
|
||||
image_infos.resize(i);
|
||||
|
@ -601,7 +640,7 @@ DynamicLoaderMacOSXKernel::ReadAllKextSummaries ()
|
|||
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(16);
|
||||
summary_addr.Slide(m_kext_summary_header.GetSize());
|
||||
if (!ParseKextSummaries (summary_addr, m_kext_summary_header.entry_count))
|
||||
{
|
||||
m_kext_summaries.clear();
|
||||
|
@ -835,7 +874,7 @@ DynamicLoaderMacOSXKernel::OSKextLoadedKextSummary::PutToLog (Log *log) const
|
|||
{
|
||||
if (u)
|
||||
{
|
||||
log->Printf("\t 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' (UNLOADED)",
|
||||
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],
|
||||
|
@ -843,23 +882,23 @@ DynamicLoaderMacOSXKernel::OSKextLoadedKextSummary::PutToLog (Log *log) const
|
|||
name);
|
||||
}
|
||||
else
|
||||
log->Printf("\t name='%s' (UNLOADED)", name);
|
||||
log->Printf("\tname=\"%s\" (UNLOADED)", name);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (u)
|
||||
{
|
||||
log->Printf("\taddress=0x%16.16llx 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'",
|
||||
address,
|
||||
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],
|
||||
log->Printf("\taddr=0x%16.16llx size=0x%16.16llx version=0x%16.16llx load-tag=0x%8.8x flags=0x%8.8x ref-list=0x%16.16llx 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\"",
|
||||
address, size, version, load_tag, flags, reference_list,
|
||||
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],
|
||||
name);
|
||||
}
|
||||
else
|
||||
{
|
||||
log->Printf("\taddress=0x%16.16llx path='%s/%s'", address, name);
|
||||
log->Printf("\t[0x%16.16llx - 0x%16.16llx) version=0x%16.16llx load-tag=0x%8.8x flags=0x%8.8x ref-list=0x%16.16llx name=\"%s\"",
|
||||
address, address+size, version, load_tag, flags, reference_list,
|
||||
name);
|
||||
}
|
||||
for (uint32_t i=0; i<segments.size(); ++i)
|
||||
segments[i].PutToLog(log, 0);
|
||||
|
@ -877,12 +916,11 @@ DynamicLoaderMacOSXKernel::PutToLog(Log *log) const
|
|||
return;
|
||||
|
||||
Mutex::Locker locker(m_mutex);
|
||||
log->Printf("gLoadedKextSummaries = 0x%16.16llx { version=%u, entry_size=%u, entry_count=%u, reserved=%u }",
|
||||
log->Printf("gLoadedKextSummaries = 0x%16.16llx { 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,
|
||||
m_kext_summary_header.reserved);
|
||||
m_kext_summary_header.entry_count);
|
||||
|
||||
size_t i;
|
||||
const size_t count = m_kext_summaries.size();
|
||||
|
|
|
@ -192,7 +192,15 @@ protected:
|
|||
|
||||
};
|
||||
|
||||
enum { KERNEL_MODULE_MAX_NAME = 64u };
|
||||
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
|
||||
};
|
||||
|
||||
struct OSKextLoadedKextSummary
|
||||
{
|
||||
|
@ -327,25 +335,35 @@ protected:
|
|||
uint32_t version;
|
||||
uint32_t entry_size;
|
||||
uint32_t entry_count;
|
||||
uint32_t reserved; /* explicit alignment for gdb */
|
||||
lldb::addr_t image_infos_addr;
|
||||
|
||||
OSKextLoadedKextSummaryHeader() :
|
||||
version (0),
|
||||
entry_size (0),
|
||||
entry_count (0),
|
||||
reserved (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;
|
||||
reserved = 0;
|
||||
image_infos_addr = LLDB_INVALID_ADDRESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -604,7 +604,7 @@ ObjectFileMachO::ParseSections ()
|
|||
segment_name.Clear();
|
||||
}
|
||||
}
|
||||
if (m_header.filetype == HeaderFileTypeDSYM)
|
||||
if (segment_sp && m_header.filetype == HeaderFileTypeDSYM)
|
||||
{
|
||||
if (first_segment_sectID <= sectID)
|
||||
{
|
||||
|
|
|
@ -161,14 +161,14 @@ PlatformMacOSX::GetSharedModule (const FileSpec &platform_file,
|
|||
if (!module_sp)
|
||||
{
|
||||
// Fall back to the local platform and find the file locally
|
||||
error = Platform::GetSharedModule(platform_file,
|
||||
arch,
|
||||
uuid_ptr,
|
||||
object_name_ptr,
|
||||
object_offset,
|
||||
module_sp,
|
||||
old_module_sp_ptr,
|
||||
did_create_ptr);
|
||||
error = Platform::GetSharedModule (platform_file,
|
||||
arch,
|
||||
uuid_ptr,
|
||||
object_name_ptr,
|
||||
object_offset,
|
||||
module_sp,
|
||||
old_module_sp_ptr,
|
||||
did_create_ptr);
|
||||
}
|
||||
if (module_sp)
|
||||
module_sp->SetPlatformFileSpec(platform_file);
|
||||
|
|
|
@ -15,10 +15,13 @@
|
|||
#include <string.h>
|
||||
|
||||
// C++ Includes
|
||||
#include "llvm/Support/MachO.h"
|
||||
|
||||
// Other libraries and framework includes
|
||||
#include "lldb/Core/DataBufferHeap.h"
|
||||
#include "lldb/Core/DataExtractor.h"
|
||||
#include "lldb/Core/Log.h"
|
||||
#include "lldb/Core/State.h"
|
||||
#include "lldb/Host/FileSpec.h"
|
||||
#include "lldb/Host/Host.h"
|
||||
#include "lldb/Host/TimeValue.h"
|
||||
|
@ -37,6 +40,7 @@ using namespace lldb_private;
|
|||
//----------------------------------------------------------------------
|
||||
CommunicationKDP::CommunicationKDP (const char *comm_name) :
|
||||
Communication(comm_name),
|
||||
m_addr_byte_size (4),
|
||||
m_byte_order (eByteOrderLittle),
|
||||
m_packet_timeout (1),
|
||||
m_sequence_mutex (Mutex::eMutexTypeRecursive),
|
||||
|
@ -129,13 +133,9 @@ CommunicationKDP::SendRequestPacketNoLock (const PacketStreamType &request_packe
|
|||
LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_PACKETS));
|
||||
if (log)
|
||||
{
|
||||
PacketStreamType log_strm;
|
||||
|
||||
DataExtractor::DumpHexBytes (&log_strm, packet_data, packet_size, UINT32_MAX, LLDB_INVALID_ADDRESS);
|
||||
|
||||
log->Printf("send kdp-packet: %.*s",
|
||||
(uint32_t)log_strm.GetSize(),
|
||||
log_strm.GetData());
|
||||
PacketStreamType log_strm;
|
||||
DumpPacket (log_strm, packet_data, packet_size);
|
||||
log->Printf("%.*s", (uint32_t)log_strm.GetSize(), log_strm.GetData());
|
||||
}
|
||||
ConnectionStatus status = eConnectionStatusSuccess;
|
||||
|
||||
|
@ -298,18 +298,9 @@ CommunicationKDP::CheckForPacket (const uint8_t *src, size_t src_len, DataExtrac
|
|||
if (log)
|
||||
{
|
||||
PacketStreamType log_strm;
|
||||
packet.Dump (&log_strm, // Stream to dump to
|
||||
0, // Offset into "packet"
|
||||
eFormatBytes, // Dump as hex bytes
|
||||
1, // Size of each item is 1 for single bytes
|
||||
length, // 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
|
||||
DumpPacket (log_strm, packet);
|
||||
|
||||
log->Printf("recv kdp-packet: %.*s",
|
||||
(uint32_t)log_strm.GetSize(),
|
||||
log_strm.GetData());
|
||||
log->Printf("%.*s", (uint32_t)log_strm.GetSize(), log_strm.GetData());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -336,7 +327,7 @@ CommunicationKDP::SendRequestConnect (uint16_t reply_port,
|
|||
uint16_t exc_port,
|
||||
const char *greeting)
|
||||
{
|
||||
PacketStreamType request_packet (Stream::eBinary, 4, m_byte_order);
|
||||
PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order);
|
||||
if (greeting == NULL)
|
||||
greeting = "";
|
||||
|
||||
|
@ -369,7 +360,7 @@ CommunicationKDP::ClearKDPSettings ()
|
|||
bool
|
||||
CommunicationKDP::SendRequestReattach (uint16_t reply_port)
|
||||
{
|
||||
PacketStreamType request_packet (Stream::eBinary, 4, m_byte_order);
|
||||
PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order);
|
||||
const CommandType command = eCommandTypeReattach;
|
||||
// Length is 8 bytes for the header plus 2 bytes for the reply UDP port
|
||||
const uint32_t command_length = 8 + 2;
|
||||
|
@ -410,7 +401,7 @@ CommunicationKDP::GetFeatureFlags ()
|
|||
bool
|
||||
CommunicationKDP::SendRequestVersion ()
|
||||
{
|
||||
PacketStreamType request_packet (Stream::eBinary, 4, m_byte_order);
|
||||
PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order);
|
||||
const CommandType command = eCommandTypeVersion;
|
||||
const uint32_t command_length = 8;
|
||||
const uint32_t request_sequence_id = m_request_sequence_id;
|
||||
|
@ -454,7 +445,7 @@ CommunicationKDP::GetCPUSubtype ()
|
|||
bool
|
||||
CommunicationKDP::SendRequestHostInfo ()
|
||||
{
|
||||
PacketStreamType request_packet (Stream::eBinary, 4, m_byte_order);
|
||||
PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order);
|
||||
const CommandType command = eCommandTypeHostInfo;
|
||||
const uint32_t command_length = 8;
|
||||
const uint32_t request_sequence_id = m_request_sequence_id;
|
||||
|
@ -464,9 +455,17 @@ CommunicationKDP::SendRequestHostInfo ()
|
|||
{
|
||||
// Reset the sequence ID to zero for reattach
|
||||
uint32_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);
|
||||
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;
|
||||
|
@ -475,7 +474,7 @@ CommunicationKDP::SendRequestHostInfo ()
|
|||
bool
|
||||
CommunicationKDP::SendRequestDisconnect ()
|
||||
{
|
||||
PacketStreamType request_packet (Stream::eBinary, 4, m_byte_order);
|
||||
PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order);
|
||||
const CommandType command = eCommandTypeDisconnect;
|
||||
const uint32_t command_length = 8;
|
||||
const uint32_t request_sequence_id = m_request_sequence_id;
|
||||
|
@ -489,3 +488,331 @@ CommunicationKDP::SendRequestDisconnect ()
|
|||
return true;
|
||||
}
|
||||
|
||||
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 ? eCommandTypeReadMemory64 : eCommandTypeReadMemory;
|
||||
// Size is header + address size + uint32_t length
|
||||
const uint32_t command_length = 8 + command_addr_byte_size + 4;
|
||||
const uint32_t request_sequence_id = m_request_sequence_id;
|
||||
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_sequence_id, request_packet, reply_packet))
|
||||
{
|
||||
// Reset the sequence ID to zero for reattach
|
||||
uint32_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");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *
|
||||
CommunicationKDP::GetCommandAsCString (uint8_t command)
|
||||
{
|
||||
switch (command)
|
||||
{
|
||||
case eCommandTypeConnect: return "KDP_CONNECT";
|
||||
case eCommandTypeDisconnect: return "KDP_DISCONNECT";
|
||||
case eCommandTypeHostInfo: return "KDP_HOSTINFO";
|
||||
case eCommandTypeVersion: return "KDP_VERSION";
|
||||
case eCommandTypeMaxBytes: return "KDP_MAXBYTES";
|
||||
case eCommandTypeReadMemory: return "KDP_READMEM";
|
||||
case eCommandTypeWriteMemory: return "KDP_WRITEMEM";
|
||||
case eCommandTypeReadRegisters: return "KDP_READREGS";
|
||||
case eCommandTypeWriteRegisters: return "KDP_WRITEREGS";
|
||||
case eCommandTypeLoad: return "KDP_LOAD";
|
||||
case eCommandTypeImagePath: return "KDP_IMAGEPATH";
|
||||
case eCommandTypeSuspend: return "KDP_SUSPEND";
|
||||
case eCommandTypeResume: return "KDP_RESUMECPUS";
|
||||
case eCommandTypeException: return "KDP_EXCEPTION";
|
||||
case eCommandTypeTermination: return "KDP_TERMINATION";
|
||||
case eCommandTypeBreakpointSet: return "KDP_BREAKPOINT_SET";
|
||||
case eCommandTypeBreakpointRemove: return "KDP_BREAKPOINT_REMOVE";
|
||||
case eCommandTypeRegions: return "KDP_REGIONS";
|
||||
case eCommandTypeReattach: return "KDP_REATTACH";
|
||||
case eCommandTypeHostReboot: return "KDP_HOSTREBOOT";
|
||||
case eCommandTypeReadMemory64: return "KDP_READMEM64";
|
||||
case eCommandTypeWriteMemory64: return "KDP_WRITEMEM64";
|
||||
case eCommandTypeBreakpointSet64: return "KDP_BREAKPOINT64_SET";
|
||||
case eCommandTypeBreakpointRemove64: return "KDP_BREAKPOINT64_REMOVE";
|
||||
case eCommandTypeKernelVersion: return "KDP_KERNELVERSION";
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
uint32_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 ("%s {%u:%u} <0x%4.4x> %s",
|
||||
is_reply ? "<--" : "-->",
|
||||
key,
|
||||
sequence_id,
|
||||
length,
|
||||
command_name);
|
||||
|
||||
if (is_reply)
|
||||
{
|
||||
// Dump request reply packets
|
||||
switch (command)
|
||||
{
|
||||
case eCommandTypeConnect:
|
||||
{
|
||||
const uint32_t error = packet.GetU32 (&offset);
|
||||
s.Printf(" (error=0x%8.8x)", error);
|
||||
}
|
||||
break;
|
||||
|
||||
case eCommandTypeDisconnect:
|
||||
case eCommandTypeReattach:
|
||||
case eCommandTypeHostReboot:
|
||||
// No return value for the reply, just the header to ack
|
||||
break;
|
||||
|
||||
case eCommandTypeHostInfo:
|
||||
{
|
||||
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 eCommandTypeVersion:
|
||||
{
|
||||
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 eCommandTypeRegions:
|
||||
{
|
||||
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[%i] = { range = [0x%16.16llx - 0x%16.16llx), size = 0x%8.8x, prot = %s }", region_addr, region_addr + region_size, region_size, GetPermissionsAsCString (region_prot));
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case eCommandTypeReadMemory:
|
||||
case eCommandTypeReadMemory64:
|
||||
case eCommandTypeReadRegisters:
|
||||
{
|
||||
const uint32_t error = packet.GetU32 (&offset);
|
||||
const uint32_t count = packet.GetByteSize() - 12;
|
||||
s.Printf(" (error = 0x%8.8x <0x%x>:\n", error, count);
|
||||
if (count > 0)
|
||||
DataExtractor::DumpHexBytes(&s, packet.GetData(&offset, count), count, 32, LLDB_INVALID_ADDRESS);
|
||||
}
|
||||
break;
|
||||
|
||||
case eCommandTypeMaxBytes:
|
||||
case eCommandTypeWriteMemory:
|
||||
case eCommandTypeWriteRegisters:
|
||||
case eCommandTypeLoad:
|
||||
case eCommandTypeImagePath:
|
||||
case eCommandTypeSuspend:
|
||||
case eCommandTypeResume:
|
||||
case eCommandTypeException:
|
||||
case eCommandTypeTermination:
|
||||
case eCommandTypeBreakpointSet:
|
||||
case eCommandTypeBreakpointRemove:
|
||||
case eCommandTypeWriteMemory64:
|
||||
case eCommandTypeBreakpointSet64:
|
||||
case eCommandTypeBreakpointRemove64:
|
||||
case eCommandTypeKernelVersion:
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Dump request packets
|
||||
switch (command)
|
||||
{
|
||||
case eCommandTypeConnect:
|
||||
{
|
||||
const uint16_t reply_port = packet.GetU16 (&offset);
|
||||
const uint16_t exc_port = packet.GetU16 (&offset);
|
||||
s.Printf(" (reply_port=%u, exc_port=%u, greeting=\"%s\")", reply_port, exc_port, packet.GetCStr(&offset));
|
||||
}
|
||||
break;
|
||||
|
||||
case eCommandTypeDisconnect:
|
||||
case eCommandTypeHostReboot:
|
||||
case eCommandTypeHostInfo:
|
||||
case eCommandTypeVersion:
|
||||
case eCommandTypeRegions:
|
||||
// No args, just the header in the request...
|
||||
break;
|
||||
|
||||
case eCommandTypeReadMemory:
|
||||
{
|
||||
const uint32_t addr = packet.GetU32 (&offset);
|
||||
const uint32_t size = packet.GetU32 (&offset);
|
||||
s.Printf(" (addr = 0x%8.8x, size=%u)", addr, size);
|
||||
}
|
||||
break;
|
||||
|
||||
case eCommandTypeReadMemory64:
|
||||
{
|
||||
const uint64_t addr = packet.GetU64 (&offset);
|
||||
const uint32_t size = packet.GetU32 (&offset);
|
||||
s.Printf(" (addr = 0x%16.16llx, size=%u)", addr, size);
|
||||
}
|
||||
break;
|
||||
|
||||
case eCommandTypeReadRegisters:
|
||||
{
|
||||
const uint32_t cpu = packet.GetU32 (&offset);
|
||||
const uint32_t flavor = packet.GetU32 (&offset);
|
||||
s.Printf(" (cpu = %u, flavor=%u)", cpu, flavor);
|
||||
}
|
||||
break;
|
||||
|
||||
case eCommandTypeMaxBytes:
|
||||
case eCommandTypeWriteMemory:
|
||||
case eCommandTypeWriteRegisters:
|
||||
case eCommandTypeLoad:
|
||||
case eCommandTypeImagePath:
|
||||
case eCommandTypeSuspend:
|
||||
case eCommandTypeResume:
|
||||
case eCommandTypeException:
|
||||
case eCommandTypeTermination:
|
||||
case eCommandTypeBreakpointSet:
|
||||
case eCommandTypeBreakpointRemove:
|
||||
break;
|
||||
|
||||
case eCommandTypeReattach:
|
||||
{
|
||||
const uint16_t reply_port = packet.GetU16 (&offset);
|
||||
s.Printf(" (reply_port=%u)", reply_port);
|
||||
}
|
||||
break;
|
||||
|
||||
case eCommandTypeWriteMemory64:
|
||||
case eCommandTypeBreakpointSet64:
|
||||
case eCommandTypeBreakpointRemove64:
|
||||
case eCommandTypeKernelVersion:
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
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 = eCommandTypeReadRegisters;
|
||||
// Size is header + 4 byte cpu and 4 byte flavor
|
||||
const uint32_t command_length = 8 + 4 + 4;
|
||||
const uint32_t request_sequence_id = m_request_sequence_id;
|
||||
MakeRequestPacketHeader (command, request_packet, command_length);
|
||||
request_packet.PutHex32 (cpu);
|
||||
request_packet.PutHex32 (flavor);
|
||||
DataExtractor reply_packet;
|
||||
if (SendRequestAndGetReply (command, request_sequence_id, request_packet, reply_packet))
|
||||
{
|
||||
// Reset the sequence ID to zero for reattach
|
||||
uint32_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.SetErrorStringWithFormat("failed to read kdp registers for cpu %u flavor %u", cpu, flavor);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -140,6 +140,9 @@ public:
|
|||
lldb_private::ProcessLaunchInfo &launch_info);
|
||||
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Public Request Packets
|
||||
//------------------------------------------------------------------
|
||||
bool
|
||||
SendRequestConnect (uint16_t reply_port,
|
||||
uint16_t exc_port,
|
||||
|
@ -151,6 +154,24 @@ public:
|
|||
bool
|
||||
SendRequestDisconnect ();
|
||||
|
||||
uint32_t
|
||||
SendRequestReadMemory (lldb::addr_t addr,
|
||||
void *buf,
|
||||
uint32_t size,
|
||||
lldb_private::Error &error);
|
||||
|
||||
uint32_t
|
||||
SendRequestReadRegisters (uint32_t cpu,
|
||||
uint32_t flavor,
|
||||
void *dst,
|
||||
uint32_t dst_size,
|
||||
lldb_private::Error &error);
|
||||
// size_t
|
||||
// SendRequestWriteMemory (lldb::addr_t addr,
|
||||
// const void *buf,
|
||||
// size_t size,
|
||||
// lldb_private::Error &error);
|
||||
|
||||
uint32_t
|
||||
GetVersion ();
|
||||
|
||||
|
@ -184,9 +205,25 @@ protected:
|
|||
PacketStreamType &request_packet,
|
||||
uint16_t request_length);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Protected Request Packets (use public accessors which will cache
|
||||
// results.
|
||||
//------------------------------------------------------------------
|
||||
bool
|
||||
SendRequestVersion ();
|
||||
|
||||
bool
|
||||
SendRequestHostInfo ();
|
||||
|
||||
|
||||
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
|
||||
|
@ -201,7 +238,21 @@ protected:
|
|||
}
|
||||
|
||||
bool
|
||||
SendRequestHostInfo ();
|
||||
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 ();
|
||||
|
@ -214,6 +265,7 @@ protected:
|
|||
//------------------------------------------------------------------
|
||||
// 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;
|
||||
lldb_private::Mutex m_sequence_mutex; // Restrict access to sending/receiving packets to a single thread at a time
|
||||
|
|
|
@ -18,11 +18,12 @@
|
|||
#include "lldb/Core/State.h"
|
||||
#include "lldb/Host/Host.h"
|
||||
#include "lldb/Target/Target.h"
|
||||
#include "lldb/Target/Thread.h"
|
||||
|
||||
// Project includes
|
||||
#include "ProcessKDP.h"
|
||||
#include "ProcessKDPLog.h"
|
||||
//#include "ThreadKDP.h"
|
||||
#include "ThreadKDP.h"
|
||||
#include "StopInfoMachException.h"
|
||||
|
||||
using namespace lldb;
|
||||
|
@ -182,7 +183,10 @@ ProcessKDP::DoConnectRemote (const char *remote_url)
|
|||
ArchSpec kernel_arch;
|
||||
kernel_arch.SetArchitecture(eArchTypeMachO, cpu, sub);
|
||||
m_target.SetArchitecture(kernel_arch);
|
||||
// TODO: thread registers based off of architecture...
|
||||
|
||||
SetID (1);
|
||||
UpdateThreadListIfNeeded ();
|
||||
SetPrivateState (eStateStopped);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -295,34 +299,24 @@ ProcessKDP::UpdateThreadListIfNeeded ()
|
|||
log->Printf ("ProcessKDP::%s (pid = %i)", __FUNCTION__, GetID());
|
||||
|
||||
Mutex::Locker locker (m_thread_list.GetMutex ());
|
||||
// TODO: get the thread list here!
|
||||
const uint32_t stop_id = GetStopID();
|
||||
if (m_thread_list.GetSize(false) == 0 || stop_id != m_thread_list.GetStopID())
|
||||
if (m_thread_list.GetSize(false) == 0)
|
||||
{
|
||||
// Update the thread list's stop id immediately so we don't recurse into this function.
|
||||
// ThreadList curr_thread_list (this);
|
||||
// curr_thread_list.SetStopID(stop_id);
|
||||
//
|
||||
// std::vector<lldb::tid_t> thread_ids;
|
||||
// bool sequence_mutex_unavailable = false;
|
||||
// const size_t num_thread_ids = m_comm.GetCurrentThreadIDs (thread_ids, sequence_mutex_unavailable);
|
||||
// if (num_thread_ids > 0)
|
||||
// {
|
||||
// for (size_t i=0; i<num_thread_ids; ++i)
|
||||
// {
|
||||
// tid_t tid = thread_ids[i];
|
||||
// ThreadSP thread_sp (GetThreadList().FindThreadByID (tid, false));
|
||||
// if (!thread_sp)
|
||||
// thread_sp.reset (new ThreadGDBRemote (*this, tid));
|
||||
// curr_thread_list.AddThread(thread_sp);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if (sequence_mutex_unavailable == false)
|
||||
// {
|
||||
// m_thread_list = curr_thread_list;
|
||||
// SetThreadStopInfo (m_last_stop_packet);
|
||||
// }
|
||||
// We currently are making only one thread per core and we
|
||||
// actually don't know about actual threads. Eventually we
|
||||
// want to get the thread list from memory and note which
|
||||
// threads are on CPU as those are the only ones that we
|
||||
// will be able to resume.
|
||||
ThreadList curr_thread_list (this);
|
||||
curr_thread_list.SetStopID(stop_id);
|
||||
const uint32_t cpu_mask = m_comm.GetCPUMask();
|
||||
for (uint32_t cpu_mask_bit = 1; cpu_mask_bit & cpu_mask; cpu_mask_bit <<= 1)
|
||||
{
|
||||
// The thread ID is currently the CPU mask bit
|
||||
ThreadSP thread_sp (new ThreadKDP (*this, cpu_mask_bit));
|
||||
curr_thread_list.AddThread(thread_sp);
|
||||
}
|
||||
m_thread_list = curr_thread_list;
|
||||
}
|
||||
return GetThreadList().GetSize(false);
|
||||
}
|
||||
|
@ -549,7 +543,9 @@ ProcessKDP::IsAlive ()
|
|||
size_t
|
||||
ProcessKDP::DoReadMemory (addr_t addr, void *buf, size_t size, Error &error)
|
||||
{
|
||||
error.SetErrorString ("ProcessKDP::DoReadMemory not implemented");
|
||||
if (m_comm.IsConnected())
|
||||
return m_comm.SendRequestReadMemory (addr, buf, size, error);
|
||||
error.SetErrorString ("not connected");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -183,6 +183,12 @@ public:
|
|||
virtual lldb_private::Error
|
||||
DisableWatchpoint (lldb_private::WatchpointLocation *wp_loc);
|
||||
|
||||
CommunicationKDP &
|
||||
GetCommunication()
|
||||
{
|
||||
return m_comm;
|
||||
}
|
||||
|
||||
protected:
|
||||
friend class ThreadKDP;
|
||||
friend class CommunicationKDP;
|
||||
|
@ -229,12 +235,6 @@ protected:
|
|||
uint32_t
|
||||
UpdateThreadListIfNeeded ();
|
||||
|
||||
CommunicationKDP &
|
||||
GetCommunication()
|
||||
{
|
||||
return m_comm;
|
||||
}
|
||||
|
||||
enum
|
||||
{
|
||||
eBroadcastBitAsyncContinue = (1 << 0),
|
||||
|
|
|
@ -0,0 +1,90 @@
|
|||
//===-- RegisterContextKDP_arm.cpp ------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "RegisterContextKDP_arm.h"
|
||||
|
||||
// C Includes
|
||||
// C++ Includes
|
||||
// Other libraries and framework includes
|
||||
// Project includes
|
||||
#include "ProcessKDP.h"
|
||||
#include "ThreadKDP.h"
|
||||
|
||||
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)
|
||||
{
|
||||
Error error;
|
||||
if (m_kdp_thread.GetKDPProcess().GetCommunication().SendRequestReadRegisters (tid,
|
||||
GPRRegSet,
|
||||
&gpr, sizeof(gpr),
|
||||
error))
|
||||
{
|
||||
if (error.Success())
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
RegisterContextKDP_arm::DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
RegisterContextKDP_arm::DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
RegisterContextKDP_arm::DoReadDBG (lldb::tid_t tid, int flavor, DBG &dbg)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
RegisterContextKDP_arm::DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
RegisterContextKDP_arm::DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
RegisterContextKDP_arm::DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
RegisterContextKDP_arm::DoWriteDBG (lldb::tid_t tid, int flavor, const DBG &dbg)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
//===-- RegisterContextKDP_arm.h --------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef liblldb_RegisterContextKDP_arm_h_
|
||||
#define liblldb_RegisterContextKDP_arm_h_
|
||||
|
||||
// C Includes
|
||||
|
||||
// C++ Includes
|
||||
// Other libraries and framework includes
|
||||
// Project includes
|
||||
#include "Plugins/Process/Utility/RegisterContextDarwin_arm.h"
|
||||
|
||||
class ThreadKDP;
|
||||
|
||||
class RegisterContextKDP_arm : public RegisterContextDarwin_arm
|
||||
{
|
||||
public:
|
||||
|
||||
RegisterContextKDP_arm (ThreadKDP &thread,
|
||||
uint32_t concrete_frame_idx);
|
||||
|
||||
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);
|
||||
|
||||
ThreadKDP &m_kdp_thread;
|
||||
};
|
||||
|
||||
#endif // liblldb_RegisterContextKDP_arm_h_
|
|
@ -0,0 +1,71 @@
|
|||
//===-- RegisterContextKDP_i386.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 <mach/thread_act.h>
|
||||
|
||||
// C++ Includes
|
||||
// Other libraries and framework includes
|
||||
// Project includes
|
||||
#include "RegisterContextKDP_i386.h"
|
||||
|
||||
using namespace lldb;
|
||||
using namespace lldb_private;
|
||||
|
||||
|
||||
RegisterContextKDP_i386::RegisterContextKDP_i386(Thread &thread, uint32_t concrete_frame_idx) :
|
||||
RegisterContextDarwin_i386 (thread, concrete_frame_idx)
|
||||
{
|
||||
}
|
||||
|
||||
RegisterContextKDP_i386::~RegisterContextKDP_i386()
|
||||
{
|
||||
}
|
||||
|
||||
int
|
||||
RegisterContextKDP_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
|
||||
RegisterContextKDP_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
|
||||
RegisterContextKDP_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
|
||||
RegisterContextKDP_i386::DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr)
|
||||
{
|
||||
return ::thread_set_state(tid, flavor, (thread_state_t)&gpr, GPRWordCount);
|
||||
}
|
||||
|
||||
int
|
||||
RegisterContextKDP_i386::DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu)
|
||||
{
|
||||
return ::thread_set_state(tid, flavor, (thread_state_t)&fpu, FPUWordCount);
|
||||
}
|
||||
|
||||
int
|
||||
RegisterContextKDP_i386::DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc)
|
||||
{
|
||||
return ::thread_set_state(tid, flavor, (thread_state_t)&exc, EXCWordCount);
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
//===-- RegisterContextKDP_i386.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_RegisterContextKDP_i386_h_
|
||||
#define liblldb_RegisterContextKDP_i386_h_
|
||||
|
||||
// C Includes
|
||||
// C++ Includes
|
||||
// Other libraries and framework includes
|
||||
// Project includes
|
||||
#include "Plugins/Process/Utility/RegisterContextDarwin_i386.h"
|
||||
|
||||
class RegisterContextKDP_i386 : public RegisterContextDarwin_i386
|
||||
{
|
||||
public:
|
||||
RegisterContextKDP_i386 (lldb_private::Thread &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);
|
||||
};
|
||||
|
||||
#endif // liblldb_RegisterContextKDP_i386_h_
|
|
@ -0,0 +1,66 @@
|
|||
//===-- RegisterContextKDP_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.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
|
||||
// C Includes
|
||||
#include <mach/thread_act.h>
|
||||
|
||||
// C++ Includes
|
||||
// Other libraries and framework includes
|
||||
// Project includes
|
||||
#include "RegisterContextKDP_x86_64.h"
|
||||
|
||||
using namespace lldb;
|
||||
using namespace lldb_private;
|
||||
|
||||
|
||||
RegisterContextKDP_x86_64::RegisterContextKDP_x86_64(Thread &thread, uint32_t concrete_frame_idx) :
|
||||
RegisterContextDarwin_x86_64 (thread, concrete_frame_idx)
|
||||
{
|
||||
}
|
||||
|
||||
RegisterContextKDP_x86_64::~RegisterContextKDP_x86_64()
|
||||
{
|
||||
}
|
||||
|
||||
int
|
||||
RegisterContextKDP_x86_64::DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
RegisterContextKDP_x86_64::DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
RegisterContextKDP_x86_64::DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
RegisterContextKDP_x86_64::DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
RegisterContextKDP_x86_64::DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
RegisterContextKDP_x86_64::DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc)
|
||||
{
|
||||
return -1;
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
//===-- RegisterContextKDP_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_RegisterContextKDP_x86_64_h_
|
||||
#define liblldb_RegisterContextKDP_x86_64_h_
|
||||
|
||||
// C Includes
|
||||
// C++ Includes
|
||||
// Other libraries and framework includes
|
||||
// Project includes
|
||||
#include "Plugins/Process/Utility/RegisterContextDarwin_x86_64.h"
|
||||
|
||||
class RegisterContextKDP_x86_64 : public RegisterContextDarwin_x86_64
|
||||
{
|
||||
public:
|
||||
|
||||
RegisterContextKDP_x86_64 (lldb_private::Thread &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);
|
||||
};
|
||||
|
||||
#endif // liblldb_RegisterContextKDP_x86_64_h_
|
|
@ -0,0 +1,247 @@
|
|||
//===-- ThreadKDP.cpp -------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
|
||||
#include "ThreadKDP.h"
|
||||
|
||||
#include "llvm/Support/MachO.h"
|
||||
|
||||
#include "lldb/Core/ArchSpec.h"
|
||||
#include "lldb/Core/DataExtractor.h"
|
||||
#include "lldb/Core/StreamString.h"
|
||||
#include "lldb/Core/State.h"
|
||||
#include "lldb/Target/Process.h"
|
||||
#include "lldb/Target/RegisterContext.h"
|
||||
#include "lldb/Target/StopInfo.h"
|
||||
#include "lldb/Target/Target.h"
|
||||
#include "lldb/Target/Unwind.h"
|
||||
#include "lldb/Breakpoint/WatchpointLocation.h"
|
||||
|
||||
#include "ProcessKDP.h"
|
||||
#include "ProcessKDPLog.h"
|
||||
#include "RegisterContextKDP_arm.h"
|
||||
#include "RegisterContextKDP_i386.h"
|
||||
#include "RegisterContextKDP_x86_64.h"
|
||||
#include "Plugins/Process/Utility/UnwindLLDB.h"
|
||||
|
||||
#if defined(__APPLE__)
|
||||
#include "UnwindMacOSXFrameBackchain.h"
|
||||
#endif
|
||||
|
||||
using namespace lldb;
|
||||
using namespace lldb_private;
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Thread Registers
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
ThreadKDP::ThreadKDP (ProcessKDP &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 (pid = %i, tid = 0x%4.4x)", this, m_process.GetID(), GetID());
|
||||
}
|
||||
|
||||
ThreadKDP::~ThreadKDP ()
|
||||
{
|
||||
ProcessKDPLog::LogIf(KDP_LOG_THREAD, "%p: ThreadKDP::~ThreadKDP (pid = %i, tid = 0x%4.4x)", this, m_process.GetID(), GetID());
|
||||
DestroyThread();
|
||||
}
|
||||
|
||||
|
||||
const char *
|
||||
ThreadKDP::GetInfo ()
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
const char *
|
||||
ThreadKDP::GetName ()
|
||||
{
|
||||
if (m_thread_name.empty())
|
||||
return NULL;
|
||||
return m_thread_name.c_str();
|
||||
}
|
||||
|
||||
const char *
|
||||
ThreadKDP::GetQueueName ()
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool
|
||||
ThreadKDP::WillResume (StateType resume_state)
|
||||
{
|
||||
ClearStackFrames();
|
||||
// Call the Thread::WillResume first. If we stop at a signal, the stop info
|
||||
// class for signal will set the resume signal that we need below. The signal
|
||||
// stuff obeys the Process::UnixSignal defaults.
|
||||
Thread::WillResume(resume_state);
|
||||
|
||||
lldb::LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_STEP));
|
||||
if (log)
|
||||
log->Printf ("Resuming thread: %4.4x with state: %s.", GetID(), StateAsCString(resume_state));
|
||||
|
||||
// ProcessKDP &process = GetKDPProcess();
|
||||
// switch (resume_state)
|
||||
// {
|
||||
// case eStateSuspended:
|
||||
// case eStateStopped:
|
||||
// // Don't append anything for threads that should stay stopped.
|
||||
// break;
|
||||
//
|
||||
// case eStateRunning:
|
||||
// case eStateStepping:
|
||||
// break;
|
||||
//
|
||||
// default:
|
||||
// break;
|
||||
// }
|
||||
return true;
|
||||
}
|
||||
|
||||
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;
|
||||
GetRegisterContext()->InvalidateIfNeeded (force);
|
||||
}
|
||||
|
||||
Unwind *
|
||||
ThreadKDP::GetUnwinder ()
|
||||
{
|
||||
if (m_unwinder_ap.get() == NULL)
|
||||
{
|
||||
const ArchSpec target_arch (GetProcess().GetTarget().GetArchitecture ());
|
||||
const llvm::Triple::ArchType machine = target_arch.GetMachine();
|
||||
switch (machine)
|
||||
{
|
||||
case llvm::Triple::x86_64:
|
||||
case llvm::Triple::x86:
|
||||
case llvm::Triple::arm:
|
||||
case llvm::Triple::thumb:
|
||||
m_unwinder_ap.reset (new UnwindLLDB (*this));
|
||||
break;
|
||||
|
||||
default:
|
||||
#if defined(__APPLE__)
|
||||
m_unwinder_ap.reset (new UnwindMacOSXFrameBackchain (*this));
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
return m_unwinder_ap.get();
|
||||
}
|
||||
|
||||
void
|
||||
ThreadKDP::ClearStackFrames ()
|
||||
{
|
||||
Unwind *unwinder = GetUnwinder ();
|
||||
if (unwinder)
|
||||
unwinder->Clear();
|
||||
Thread::ClearStackFrames();
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
switch (GetKDPProcess().GetCommunication().GetCPUType())
|
||||
{
|
||||
case llvm::MachO::CPUTypeARM:
|
||||
reg_ctx_sp.reset (new RegisterContextKDP_arm (*this, concrete_frame_idx));
|
||||
break;
|
||||
case llvm::MachO::CPUTypeI386:
|
||||
reg_ctx_sp.reset (new RegisterContextKDP_i386 (*this, concrete_frame_idx));
|
||||
break;
|
||||
case llvm::MachO::CPUTypeX86_64:
|
||||
reg_ctx_sp.reset (new RegisterContextKDP_x86_64 (*this, concrete_frame_idx));
|
||||
break;
|
||||
default:
|
||||
assert (!"Add CPU type support in KDP");
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (m_unwinder_ap.get())
|
||||
reg_ctx_sp = m_unwinder_ap->CreateRegisterContextForFrame (frame);
|
||||
return reg_ctx_sp;
|
||||
}
|
||||
|
||||
lldb::StopInfoSP
|
||||
ThreadKDP::GetPrivateStopReason ()
|
||||
{
|
||||
const uint32_t process_stop_id = GetProcess().GetStopID();
|
||||
if (m_thread_stop_reason_stop_id != process_stop_id ||
|
||||
(m_actual_stop_info_sp && !m_actual_stop_info_sp->IsValid()))
|
||||
{
|
||||
// TODO: can we query the initial state of the thread here?
|
||||
// For now I am just going to pretend that a SIGSTOP happened.
|
||||
|
||||
SetStopInfo(StopInfo::CreateStopReasonWithSignal (*this, SIGSTOP));
|
||||
|
||||
// If GetKDPProcess().SetThreadStopInfo() doesn't find a stop reason
|
||||
// for this thread, then m_actual_stop_info_sp will not ever contain
|
||||
// a valid stop reason and the "m_actual_stop_info_sp->IsValid() == false"
|
||||
// check will never be able to tell us if we have the correct stop info
|
||||
// for this thread and we will continually send qThreadStopInfo packets
|
||||
// down to the remote KDP server, so we need to keep our own notion
|
||||
// of the stop ID that m_actual_stop_info_sp is valid for (even if it
|
||||
// contains nothing). We use m_thread_stop_reason_stop_id for this below.
|
||||
// m_thread_stop_reason_stop_id = process_stop_id;
|
||||
// m_actual_stop_info_sp.reset();
|
||||
|
||||
}
|
||||
return m_actual_stop_info_sp;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,115 @@
|
|||
//===-- ThreadKDP.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_ThreadKDP_h_
|
||||
#define liblldb_ThreadKDP_h_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "lldb/Target/Process.h"
|
||||
#include "lldb/Target/Thread.h"
|
||||
|
||||
class ProcessKDP;
|
||||
|
||||
class ThreadKDP : public lldb_private::Thread
|
||||
{
|
||||
public:
|
||||
ThreadKDP (ProcessKDP &process,
|
||||
lldb::tid_t tid);
|
||||
|
||||
virtual
|
||||
~ThreadKDP ();
|
||||
|
||||
virtual bool
|
||||
WillResume (lldb::StateType resume_state);
|
||||
|
||||
virtual void
|
||||
RefreshStateAfterStop();
|
||||
|
||||
virtual const char *
|
||||
GetInfo ();
|
||||
|
||||
virtual const char *
|
||||
GetName ();
|
||||
|
||||
virtual const char *
|
||||
GetQueueName ();
|
||||
|
||||
virtual lldb::RegisterContextSP
|
||||
GetRegisterContext ();
|
||||
|
||||
virtual lldb::RegisterContextSP
|
||||
CreateRegisterContextForFrame (lldb_private::StackFrame *frame);
|
||||
|
||||
virtual void
|
||||
ClearStackFrames ();
|
||||
|
||||
ProcessKDP &
|
||||
GetKDPProcess ()
|
||||
{
|
||||
return (ProcessKDP &)m_process;
|
||||
}
|
||||
|
||||
void
|
||||
Dump (lldb_private::Log *log, uint32_t index);
|
||||
|
||||
static bool
|
||||
ThreadIDIsValid (lldb::tid_t thread);
|
||||
|
||||
bool
|
||||
ShouldStop (bool &step_more);
|
||||
|
||||
const char *
|
||||
GetBasicInfoAsString ();
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
void
|
||||
SetThreadDispatchQAddr (lldb::addr_t thread_dispatch_qaddr)
|
||||
{
|
||||
m_thread_dispatch_qaddr = thread_dispatch_qaddr;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
friend class ProcessKDP;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Member variables.
|
||||
//------------------------------------------------------------------
|
||||
std::string m_thread_name;
|
||||
std::string m_dispatch_queue_name;
|
||||
lldb::addr_t m_thread_dispatch_qaddr;
|
||||
//------------------------------------------------------------------
|
||||
// Member variables.
|
||||
//------------------------------------------------------------------
|
||||
|
||||
virtual lldb_private::Unwind *
|
||||
GetUnwinder ();
|
||||
|
||||
virtual lldb::StopInfoSP
|
||||
GetPrivateStopReason ();
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif // liblldb_ThreadKDP_h_
|
File diff suppressed because it is too large
Load Diff
|
@ -11,46 +11,13 @@
|
|||
#define liblldb_RegisterContextMach_arm_h_
|
||||
|
||||
// C Includes
|
||||
#include <mach/mach_types.h>
|
||||
|
||||
// C++ Includes
|
||||
// Other libraries and framework includes
|
||||
// Project includes
|
||||
#include "lldb/lldb-private.h"
|
||||
#include "lldb/Target/RegisterContext.h"
|
||||
#include "Plugins/Process/Utility/RegisterContextDarwin_arm.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))
|
||||
|
||||
// Link a BVR/BCR or WVR/WCR pair to another
|
||||
#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))
|
||||
|
||||
// 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 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))
|
||||
|
||||
class RegisterContextMach_arm : public lldb_private::RegisterContext
|
||||
class RegisterContextMach_arm : public RegisterContextDarwin_arm
|
||||
{
|
||||
public:
|
||||
|
||||
|
@ -59,242 +26,31 @@ public:
|
|||
virtual
|
||||
~RegisterContextMach_arm();
|
||||
|
||||
virtual void
|
||||
InvalidateAllRegisters ();
|
||||
|
||||
virtual size_t
|
||||
GetRegisterCount ();
|
||||
|
||||
virtual const lldb_private::RegisterInfo *
|
||||
GetRegisterInfoAtIndex (uint32_t reg);
|
||||
|
||||
virtual size_t
|
||||
GetRegisterSetCount ();
|
||||
|
||||
virtual const lldb_private::RegisterSet *
|
||||
GetRegisterSet (uint32_t set);
|
||||
|
||||
virtual bool
|
||||
ReadRegister (const lldb_private::RegisterInfo *reg_info,
|
||||
lldb_private::RegisterValue ®_value);
|
||||
|
||||
virtual bool
|
||||
WriteRegister (const lldb_private::RegisterInfo *reg_info,
|
||||
const lldb_private::RegisterValue ®_value);
|
||||
|
||||
virtual bool
|
||||
ReadAllRegisterValues (lldb::DataBufferSP &data_sp);
|
||||
|
||||
virtual bool
|
||||
WriteAllRegisterValues (const lldb::DataBufferSP &data_sp);
|
||||
|
||||
virtual uint32_t
|
||||
ConvertRegisterKindToRegisterNumber (uint32_t kind, uint32_t num);
|
||||
|
||||
virtual uint32_t
|
||||
NumSupportedHardwareBreakpoints ();
|
||||
|
||||
virtual uint32_t
|
||||
SetHardwareBreakpoint (lldb::addr_t addr, size_t size);
|
||||
|
||||
virtual bool
|
||||
ClearHardwareBreakpoint (uint32_t hw_idx);
|
||||
|
||||
virtual uint32_t
|
||||
NumSupportedHardwareWatchpoints ();
|
||||
|
||||
virtual uint32_t
|
||||
SetHardwareWatchpoint (lldb::addr_t addr, size_t size, bool read, bool write);
|
||||
|
||||
virtual bool
|
||||
ClearHardwareWatchpoint (uint32_t hw_index);
|
||||
|
||||
struct GPR
|
||||
{
|
||||
uint32_t r[16]; // R0-R15
|
||||
uint32_t cpsr; // CPSR
|
||||
};
|
||||
|
||||
|
||||
struct FPU
|
||||
{
|
||||
union {
|
||||
uint32_t s[32];
|
||||
uint64_t d[16];
|
||||
} 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,
|
||||
FPURegSet = 2,
|
||||
EXCRegSet = 3,
|
||||
DBGRegSet = 4,
|
||||
};
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
virtual int
|
||||
DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu);
|
||||
|
||||
int
|
||||
ReadGPR (bool force);
|
||||
|
||||
DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc);
|
||||
|
||||
int
|
||||
ReadFPU (bool force);
|
||||
|
||||
DoReadDBG (lldb::tid_t tid, int flavor, DBG &dbg);
|
||||
|
||||
int
|
||||
ReadEXC (bool force);
|
||||
|
||||
DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr);
|
||||
|
||||
int
|
||||
ReadDBG (bool force);
|
||||
|
||||
DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu);
|
||||
|
||||
int
|
||||
WriteGPR ();
|
||||
|
||||
DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc);
|
||||
|
||||
int
|
||||
WriteFPU ();
|
||||
|
||||
int
|
||||
WriteEXC ();
|
||||
|
||||
int
|
||||
WriteDBG ();
|
||||
|
||||
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 ();
|
||||
DoWriteDBG (lldb::tid_t tid, int flavor, const DBG &dbg);
|
||||
};
|
||||
|
||||
#endif // liblldb_RegisterContextMach_arm_h_
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -14,237 +14,36 @@
|
|||
// C++ Includes
|
||||
// Other libraries and framework includes
|
||||
// Project includes
|
||||
#include "lldb/lldb-private.h"
|
||||
#include "lldb/Target/RegisterContext.h"
|
||||
#include "Plugins/Process/Utility/RegisterContextDarwin_i386.h"
|
||||
|
||||
class RegisterContextMach_i386 : public lldb_private::RegisterContext
|
||||
class RegisterContextMach_i386 : public RegisterContextDarwin_i386
|
||||
{
|
||||
public:
|
||||
|
||||
RegisterContextMach_i386(lldb_private::Thread &thread,
|
||||
uint32_t concrete_frame_idx);
|
||||
|
||||
|
||||
RegisterContextMach_i386(lldb_private::Thread &thread, uint32_t concrete_frame_idx);
|
||||
|
||||
virtual
|
||||
~RegisterContextMach_i386();
|
||||
|
||||
virtual void
|
||||
InvalidateAllRegisters ();
|
||||
|
||||
virtual size_t
|
||||
GetRegisterCount ();
|
||||
|
||||
virtual const lldb_private::RegisterInfo *
|
||||
GetRegisterInfoAtIndex (uint32_t reg);
|
||||
|
||||
virtual size_t
|
||||
GetRegisterSetCount ();
|
||||
|
||||
virtual const lldb_private::RegisterSet *
|
||||
GetRegisterSet (uint32_t set);
|
||||
|
||||
virtual bool
|
||||
ReadRegister (const lldb_private::RegisterInfo *reg_info, lldb_private::RegisterValue &value);
|
||||
|
||||
virtual bool
|
||||
WriteRegister (const lldb_private::RegisterInfo *reg_info, const lldb_private::RegisterValue &value);
|
||||
|
||||
virtual bool
|
||||
ReadAllRegisterValues (lldb::DataBufferSP &data_sp);
|
||||
|
||||
virtual bool
|
||||
WriteAllRegisterValues (const lldb::DataBufferSP &data_sp);
|
||||
|
||||
virtual uint32_t
|
||||
ConvertRegisterKindToRegisterNumber (uint32_t kind, uint32_t num);
|
||||
|
||||
virtual bool
|
||||
HardwareSingleStep (bool enable);
|
||||
|
||||
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;
|
||||
kern_return_t gpr_errs[2]; // Read/Write errors
|
||||
kern_return_t fpu_errs[2]; // Read/Write errors
|
||||
kern_return_t exc_errs[2]; // Read/Write errors
|
||||
|
||||
void
|
||||
InvalidateAllRegisterStates()
|
||||
{
|
||||
SetError (GPRRegSet, Read, -1);
|
||||
SetError (FPURegSet, Read, -1);
|
||||
SetError (EXCRegSet, Read, -1);
|
||||
}
|
||||
|
||||
kern_return_t
|
||||
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;
|
||||
}
|
||||
|
||||
bool
|
||||
SetError (int flavor, uint32_t err_idx, kern_return_t 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) == KERN_SUCCESS;
|
||||
}
|
||||
|
||||
void
|
||||
LogGPR (lldb_private::Log *log, const char *title);
|
||||
|
||||
kern_return_t
|
||||
ReadGPR (bool force);
|
||||
|
||||
kern_return_t
|
||||
ReadFPU (bool force);
|
||||
|
||||
kern_return_t
|
||||
ReadEXC (bool force);
|
||||
|
||||
kern_return_t
|
||||
WriteGPR ();
|
||||
|
||||
kern_return_t
|
||||
WriteFPU ();
|
||||
|
||||
kern_return_t
|
||||
WriteEXC ();
|
||||
|
||||
kern_return_t
|
||||
ReadRegisterSet (uint32_t set, bool force);
|
||||
|
||||
kern_return_t
|
||||
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 ();
|
||||
|
||||
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_
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,4 +1,4 @@
|
|||
//===-- RegisterContextMach_x86_64.h ----------------------------*- C++ -*-===//
|
||||
//===-- RegisterContextMach_x86_64.h ------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
|
@ -14,242 +14,36 @@
|
|||
// C++ Includes
|
||||
// Other libraries and framework includes
|
||||
// Project includes
|
||||
#include "lldb/lldb-private.h"
|
||||
#include "lldb/Target/RegisterContext.h"
|
||||
#include "Plugins/Process/Utility/RegisterContextDarwin_x86_64.h"
|
||||
|
||||
class RegisterContextMach_x86_64 : public lldb_private::RegisterContext
|
||||
class RegisterContextMach_x86_64 : public RegisterContextDarwin_x86_64
|
||||
{
|
||||
public:
|
||||
RegisterContextMach_x86_64 (lldb_private::Thread &thread,
|
||||
uint32_t concrete_frame_idx);
|
||||
|
||||
|
||||
RegisterContextMach_x86_64(lldb_private::Thread &thread, uint32_t concrete_frame_idx);
|
||||
|
||||
virtual
|
||||
~RegisterContextMach_x86_64();
|
||||
|
||||
virtual void
|
||||
InvalidateAllRegisters ();
|
||||
|
||||
virtual size_t
|
||||
GetRegisterCount ();
|
||||
|
||||
virtual const lldb_private::RegisterInfo *
|
||||
GetRegisterInfoAtIndex (uint32_t reg);
|
||||
|
||||
virtual size_t
|
||||
GetRegisterSetCount ();
|
||||
|
||||
virtual const lldb_private::RegisterSet *
|
||||
GetRegisterSet (uint32_t set);
|
||||
|
||||
virtual bool
|
||||
ReadRegister (const lldb_private::RegisterInfo *reg_info, lldb_private::RegisterValue &value);
|
||||
|
||||
virtual bool
|
||||
WriteRegister (const lldb_private::RegisterInfo *reg_info, const lldb_private::RegisterValue &value);
|
||||
|
||||
virtual bool
|
||||
ReadAllRegisterValues (lldb::DataBufferSP &data_sp);
|
||||
|
||||
virtual bool
|
||||
WriteAllRegisterValues (const lldb::DataBufferSP &data_sp);
|
||||
|
||||
virtual uint32_t
|
||||
ConvertRegisterKindToRegisterNumber (uint32_t kind, uint32_t num);
|
||||
|
||||
virtual bool
|
||||
HardwareSingleStep (bool enable);
|
||||
|
||||
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;
|
||||
kern_return_t gpr_errs[2]; // Read/Write errors
|
||||
kern_return_t fpu_errs[2]; // Read/Write errors
|
||||
kern_return_t exc_errs[2]; // Read/Write errors
|
||||
|
||||
void
|
||||
InvalidateAllRegisterStates()
|
||||
{
|
||||
SetError (GPRRegSet, Read, -1);
|
||||
SetError (FPURegSet, Read, -1);
|
||||
SetError (EXCRegSet, Read, -1);
|
||||
}
|
||||
|
||||
kern_return_t
|
||||
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;
|
||||
}
|
||||
|
||||
bool
|
||||
SetError (int flavor, uint32_t err_idx, kern_return_t 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) == KERN_SUCCESS;
|
||||
}
|
||||
|
||||
void
|
||||
LogGPR (lldb_private::Log *log, const char *format, ...);
|
||||
|
||||
kern_return_t
|
||||
ReadGPR (bool force);
|
||||
|
||||
kern_return_t
|
||||
ReadFPU (bool force);
|
||||
|
||||
kern_return_t
|
||||
ReadEXC (bool force);
|
||||
|
||||
kern_return_t
|
||||
WriteGPR ();
|
||||
|
||||
kern_return_t
|
||||
WriteFPU ();
|
||||
|
||||
kern_return_t
|
||||
WriteEXC ();
|
||||
|
||||
kern_return_t
|
||||
ReadRegisterSet (uint32_t set, bool force);
|
||||
|
||||
kern_return_t
|
||||
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 ();
|
||||
|
||||
|
||||
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_
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,348 @@
|
|||
//===-- RegisterContextDarwin_arm.h -----------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef liblldb_RegisterContextDarwin_arm_h_
|
||||
#define liblldb_RegisterContextDarwin_arm_h_
|
||||
|
||||
// C Includes
|
||||
// C++ Includes
|
||||
// Other libraries and framework includes
|
||||
// Project includes
|
||||
#include "lldb/lldb-private.h"
|
||||
#include "lldb/Target/RegisterContext.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))
|
||||
|
||||
// Link a BVR/BCR or WVR/WCR pair to another
|
||||
#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))
|
||||
|
||||
// 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 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))
|
||||
|
||||
class RegisterContextDarwin_arm : public lldb_private::RegisterContext
|
||||
{
|
||||
public:
|
||||
|
||||
RegisterContextDarwin_arm(lldb_private::Thread &thread, uint32_t concrete_frame_idx);
|
||||
|
||||
virtual
|
||||
~RegisterContextDarwin_arm();
|
||||
|
||||
virtual void
|
||||
InvalidateAllRegisters ();
|
||||
|
||||
virtual size_t
|
||||
GetRegisterCount ();
|
||||
|
||||
virtual const lldb_private::RegisterInfo *
|
||||
GetRegisterInfoAtIndex (uint32_t reg);
|
||||
|
||||
virtual size_t
|
||||
GetRegisterSetCount ();
|
||||
|
||||
virtual const lldb_private::RegisterSet *
|
||||
GetRegisterSet (uint32_t set);
|
||||
|
||||
virtual bool
|
||||
ReadRegister (const lldb_private::RegisterInfo *reg_info,
|
||||
lldb_private::RegisterValue ®_value);
|
||||
|
||||
virtual bool
|
||||
WriteRegister (const lldb_private::RegisterInfo *reg_info,
|
||||
const lldb_private::RegisterValue ®_value);
|
||||
|
||||
virtual bool
|
||||
ReadAllRegisterValues (lldb::DataBufferSP &data_sp);
|
||||
|
||||
virtual bool
|
||||
WriteAllRegisterValues (const lldb::DataBufferSP &data_sp);
|
||||
|
||||
virtual uint32_t
|
||||
ConvertRegisterKindToRegisterNumber (uint32_t kind, uint32_t num);
|
||||
|
||||
virtual uint32_t
|
||||
NumSupportedHardwareBreakpoints ();
|
||||
|
||||
virtual uint32_t
|
||||
SetHardwareBreakpoint (lldb::addr_t addr, size_t size);
|
||||
|
||||
virtual bool
|
||||
ClearHardwareBreakpoint (uint32_t hw_idx);
|
||||
|
||||
virtual uint32_t
|
||||
NumSupportedHardwareWatchpoints ();
|
||||
|
||||
virtual uint32_t
|
||||
SetHardwareWatchpoint (lldb::addr_t addr, size_t size, bool read, bool write);
|
||||
|
||||
virtual bool
|
||||
ClearHardwareWatchpoint (uint32_t hw_index);
|
||||
|
||||
struct GPR
|
||||
{
|
||||
uint32_t r[16]; // R0-R15
|
||||
uint32_t cpsr; // CPSR
|
||||
};
|
||||
|
||||
|
||||
struct FPU
|
||||
{
|
||||
union {
|
||||
uint32_t s[32];
|
||||
uint64_t d[16];
|
||||
} 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,
|
||||
FPURegSet = 2,
|
||||
EXCRegSet = 3,
|
||||
DBGRegSet = 4,
|
||||
};
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
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
|
||||
RegisterSetIsCached (int set) const
|
||||
{
|
||||
return GetError(set, Read) == 0;
|
||||
}
|
||||
|
||||
int
|
||||
ReadGPR (bool force);
|
||||
|
||||
int
|
||||
ReadFPU (bool force);
|
||||
|
||||
int
|
||||
ReadEXC (bool force);
|
||||
|
||||
int
|
||||
ReadDBG (bool force);
|
||||
|
||||
int
|
||||
WriteGPR ();
|
||||
|
||||
int
|
||||
WriteFPU ();
|
||||
|
||||
int
|
||||
WriteEXC ();
|
||||
|
||||
int
|
||||
WriteDBG ();
|
||||
|
||||
|
||||
// Subclasses override these to do the actual reading.
|
||||
virtual int
|
||||
DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
DoReadDBG (lldb::tid_t tid, int flavor, DBG &dbg)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
DoWriteDBG (lldb::tid_t tid, int flavor, const DBG &dbg)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
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 ();
|
||||
};
|
||||
|
||||
#endif // liblldb_RegisterContextDarwin_arm_h_
|
|
@ -0,0 +1,971 @@
|
|||
//===-- RegisterContextDarwin_i386.cpp --------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
|
||||
// C Includes
|
||||
// C++ Includes
|
||||
// Other libraries and framework includes
|
||||
#include "lldb/Core/DataBufferHeap.h"
|
||||
#include "lldb/Core/DataExtractor.h"
|
||||
#include "lldb/Core/Log.h"
|
||||
#include "lldb/Core/RegisterValue.h"
|
||||
#include "lldb/Core/Scalar.h"
|
||||
#include "lldb/Host/Endian.h"
|
||||
|
||||
// Project includes
|
||||
#include "RegisterContextDarwin_i386.h"
|
||||
|
||||
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
|
||||
{
|
||||
gcc_eax = 0,
|
||||
gcc_ecx,
|
||||
gcc_edx,
|
||||
gcc_ebx,
|
||||
gcc_ebp,
|
||||
gcc_esp,
|
||||
gcc_esi,
|
||||
gcc_edi,
|
||||
gcc_eip,
|
||||
gcc_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
|
||||
{
|
||||
gdb_eax = 0,
|
||||
gdb_ecx = 1,
|
||||
gdb_edx = 2,
|
||||
gdb_ebx = 3,
|
||||
gdb_esp = 4,
|
||||
gdb_ebp = 5,
|
||||
gdb_esi = 6,
|
||||
gdb_edi = 7,
|
||||
gdb_eip = 8,
|
||||
gdb_eflags = 9,
|
||||
gdb_cs = 10,
|
||||
gdb_ss = 11,
|
||||
gdb_ds = 12,
|
||||
gdb_es = 13,
|
||||
gdb_fs = 14,
|
||||
gdb_gs = 15,
|
||||
gdb_stmm0 = 16,
|
||||
gdb_stmm1 = 17,
|
||||
gdb_stmm2 = 18,
|
||||
gdb_stmm3 = 19,
|
||||
gdb_stmm4 = 20,
|
||||
gdb_stmm5 = 21,
|
||||
gdb_stmm6 = 22,
|
||||
gdb_stmm7 = 23,
|
||||
gdb_fctrl = 24, gdb_fcw = gdb_fctrl,
|
||||
gdb_fstat = 25, gdb_fsw = gdb_fstat,
|
||||
gdb_ftag = 26, gdb_ftw = gdb_ftag,
|
||||
gdb_fiseg = 27, gdb_fpu_cs = gdb_fiseg,
|
||||
gdb_fioff = 28, gdb_ip = gdb_fioff,
|
||||
gdb_foseg = 29, gdb_fpu_ds = gdb_foseg,
|
||||
gdb_fooff = 30, gdb_dp = gdb_fooff,
|
||||
gdb_fop = 31,
|
||||
gdb_xmm0 = 32,
|
||||
gdb_xmm1 = 33,
|
||||
gdb_xmm2 = 34,
|
||||
gdb_xmm3 = 35,
|
||||
gdb_xmm4 = 36,
|
||||
gdb_xmm5 = 37,
|
||||
gdb_xmm6 = 38,
|
||||
gdb_xmm7 = 39,
|
||||
gdb_mxcsr = 40,
|
||||
gdb_mm0 = 41,
|
||||
gdb_mm1 = 42,
|
||||
gdb_mm2 = 43,
|
||||
gdb_mm3 = 44,
|
||||
gdb_mm4 = 45,
|
||||
gdb_mm5 = 46,
|
||||
gdb_mm6 = 47,
|
||||
gdb_mm7 = 48
|
||||
};
|
||||
|
||||
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()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
#define GPR_OFFSET(reg) (offsetof (RegisterContextDarwin_i386::GPR, reg))
|
||||
#define FPU_OFFSET(reg) (offsetof (RegisterContextDarwin_i386::FPU, reg) + sizeof (RegisterContextDarwin_i386::GPR))
|
||||
#define EXC_OFFSET(reg) (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, gdb_##reg##i, fpu_##reg##i }
|
||||
|
||||
#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 GCC DWARF GENERIC GDB LLDB
|
||||
// =============================== ======================= =================== ========================= ================== =================
|
||||
{ DEFINE_GPR(eax , NULL) , { gcc_eax , dwarf_eax , LLDB_INVALID_REGNUM , gdb_eax , gpr_eax }},
|
||||
{ DEFINE_GPR(ebx , NULL) , { gcc_ebx , dwarf_ebx , LLDB_INVALID_REGNUM , gdb_ebx , gpr_ebx }},
|
||||
{ DEFINE_GPR(ecx , NULL) , { gcc_ecx , dwarf_ecx , LLDB_INVALID_REGNUM , gdb_ecx , gpr_ecx }},
|
||||
{ DEFINE_GPR(edx , NULL) , { gcc_edx , dwarf_edx , LLDB_INVALID_REGNUM , gdb_edx , gpr_edx }},
|
||||
{ DEFINE_GPR(edi , NULL) , { gcc_edi , dwarf_edi , LLDB_INVALID_REGNUM , gdb_edi , gpr_edi }},
|
||||
{ DEFINE_GPR(esi , NULL) , { gcc_esi , dwarf_esi , LLDB_INVALID_REGNUM , gdb_esi , gpr_esi }},
|
||||
{ DEFINE_GPR(ebp , "fp") , { gcc_ebp , dwarf_ebp , LLDB_REGNUM_GENERIC_FP , gdb_ebp , gpr_ebp }},
|
||||
{ DEFINE_GPR(esp , "sp") , { gcc_esp , dwarf_esp , LLDB_REGNUM_GENERIC_SP , gdb_esp , gpr_esp }},
|
||||
{ DEFINE_GPR(ss , NULL) , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , gdb_ss , gpr_ss }},
|
||||
{ DEFINE_GPR(eflags , "flags") , { gcc_eflags , dwarf_eflags , LLDB_REGNUM_GENERIC_FLAGS , gdb_eflags , gpr_eflags }},
|
||||
{ DEFINE_GPR(eip , "pc") , { gcc_eip , dwarf_eip , LLDB_REGNUM_GENERIC_PC , gdb_eip , gpr_eip }},
|
||||
{ DEFINE_GPR(cs , NULL) , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , gdb_cs , gpr_cs }},
|
||||
{ DEFINE_GPR(ds , NULL) , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , gdb_ds , gpr_ds }},
|
||||
{ DEFINE_GPR(es , NULL) , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , gdb_es , gpr_es }},
|
||||
{ DEFINE_GPR(fs , NULL) , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , gdb_fs , gpr_fs }},
|
||||
{ DEFINE_GPR(gs , NULL) , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , gdb_gs , gpr_gs }},
|
||||
|
||||
{ DEFINE_FPU_UINT(fcw) , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , gdb_fcw , fpu_fcw }},
|
||||
{ DEFINE_FPU_UINT(fsw) , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , gdb_fsw , fpu_fsw }},
|
||||
{ DEFINE_FPU_UINT(ftw) , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , gdb_ftw , fpu_ftw }},
|
||||
{ DEFINE_FPU_UINT(fop) , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , gdb_fop , fpu_fop }},
|
||||
{ DEFINE_FPU_UINT(ip) , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , gdb_ip , fpu_ip }},
|
||||
{ DEFINE_FPU_UINT(cs) , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , gdb_cs , fpu_cs }},
|
||||
{ DEFINE_FPU_UINT(dp) , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , gdb_dp , fpu_dp }},
|
||||
{ DEFINE_FPU_UINT(ds) , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , gdb_ds , fpu_ds }},
|
||||
{ DEFINE_FPU_UINT(mxcsr) , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , gdb_mxcsr , fpu_mxcsr }},
|
||||
{ DEFINE_FPU_UINT(mxcsrmask) , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, fpu_mxcsrmask}},
|
||||
{ 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 }},
|
||||
{ DEFINE_EXC(err) , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, exc_err }},
|
||||
{ DEFINE_EXC(faultvaddr) , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM, exc_faultvaddr }}
|
||||
};
|
||||
|
||||
static size_t k_num_register_infos = (sizeof(g_register_infos)/sizeof(RegisterInfo));
|
||||
|
||||
void
|
||||
RegisterContextDarwin_i386::InvalidateAllRegisters ()
|
||||
{
|
||||
InvalidateAllRegisterStates();
|
||||
}
|
||||
|
||||
|
||||
size_t
|
||||
RegisterContextDarwin_i386::GetRegisterCount ()
|
||||
{
|
||||
assert(k_num_register_infos == k_num_registers);
|
||||
return k_num_registers;
|
||||
}
|
||||
|
||||
const RegisterInfo *
|
||||
RegisterContextDarwin_i386::GetRegisterInfoAtIndex (uint32_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;
|
||||
}
|
||||
|
||||
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
|
||||
};
|
||||
|
||||
// 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
|
||||
};
|
||||
|
||||
// Exception registers
|
||||
|
||||
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 = sizeof(g_gpr_regnums) / sizeof(uint32_t);
|
||||
const size_t k_num_fpu_registers = sizeof(g_fpu_regnums) / sizeof(uint32_t);
|
||||
const size_t k_num_exc_registers = sizeof(g_exc_regnums) / sizeof(uint32_t);
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Register set definitions. The first definitions at register set index
|
||||
// of zero is for all registers, followed by other registers sets. The
|
||||
// register information for the all register set need not be filled in.
|
||||
//----------------------------------------------------------------------
|
||||
static const RegisterSet g_reg_sets[] =
|
||||
{
|
||||
{ "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 = sizeof(g_reg_sets) / sizeof(RegisterSet);
|
||||
|
||||
|
||||
size_t
|
||||
RegisterContextDarwin_i386::GetRegisterSetCount ()
|
||||
{
|
||||
return k_num_regsets;
|
||||
}
|
||||
|
||||
const RegisterSet *
|
||||
RegisterContextDarwin_i386::GetRegisterSet (uint32_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;
|
||||
}
|
||||
|
||||
|
||||
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::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::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::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::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;
|
||||
}
|
||||
|
||||
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 (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;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
RegisterContextDarwin_i386::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) != 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:
|
||||
(&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;
|
||||
|
||||
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);
|
||||
|
||||
::memcpy (dst, &fpu, sizeof(fpu));
|
||||
dst += sizeof(gpr);
|
||||
|
||||
::memcpy (dst, &exc, sizeof(exc));
|
||||
return true;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
uint32_t
|
||||
RegisterContextDarwin_i386::ConvertRegisterKindToRegisterNumber (uint32_t 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 == eRegisterKindGCC || 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 == eRegisterKindGDB)
|
||||
{
|
||||
switch (reg)
|
||||
{
|
||||
case gdb_eax : return gpr_eax;
|
||||
case gdb_ebx : return gpr_ebx;
|
||||
case gdb_ecx : return gpr_ecx;
|
||||
case gdb_edx : return gpr_edx;
|
||||
case gdb_esi : return gpr_esi;
|
||||
case gdb_edi : return gpr_edi;
|
||||
case gdb_ebp : return gpr_ebp;
|
||||
case gdb_esp : return gpr_esp;
|
||||
case gdb_eip : return gpr_eip;
|
||||
case gdb_eflags : return gpr_eflags;
|
||||
case gdb_cs : return gpr_cs;
|
||||
case gdb_ss : return gpr_ss;
|
||||
case gdb_ds : return gpr_ds;
|
||||
case gdb_es : return gpr_es;
|
||||
case gdb_fs : return gpr_fs;
|
||||
case gdb_gs : return gpr_gs;
|
||||
case gdb_stmm0 : return fpu_stmm0;
|
||||
case gdb_stmm1 : return fpu_stmm1;
|
||||
case gdb_stmm2 : return fpu_stmm2;
|
||||
case gdb_stmm3 : return fpu_stmm3;
|
||||
case gdb_stmm4 : return fpu_stmm4;
|
||||
case gdb_stmm5 : return fpu_stmm5;
|
||||
case gdb_stmm6 : return fpu_stmm6;
|
||||
case gdb_stmm7 : return fpu_stmm7;
|
||||
case gdb_fctrl : return fpu_fctrl;
|
||||
case gdb_fstat : return fpu_fstat;
|
||||
case gdb_ftag : return fpu_ftag;
|
||||
case gdb_fiseg : return fpu_fiseg;
|
||||
case gdb_fioff : return fpu_fioff;
|
||||
case gdb_foseg : return fpu_foseg;
|
||||
case gdb_fooff : return fpu_fooff;
|
||||
case gdb_fop : return fpu_fop;
|
||||
case gdb_xmm0 : return fpu_xmm0;
|
||||
case gdb_xmm1 : return fpu_xmm1;
|
||||
case gdb_xmm2 : return fpu_xmm2;
|
||||
case gdb_xmm3 : return fpu_xmm3;
|
||||
case gdb_xmm4 : return fpu_xmm4;
|
||||
case gdb_xmm5 : return fpu_xmm5;
|
||||
case gdb_xmm6 : return fpu_xmm6;
|
||||
case gdb_xmm7 : return fpu_xmm7;
|
||||
case gdb_mxcsr : return fpu_mxcsr;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,287 @@
|
|||
//===-- RegisterContextDarwin_i386.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_RegisterContextDarwin_i386_h_
|
||||
#define liblldb_RegisterContextDarwin_i386_h_
|
||||
|
||||
// C Includes
|
||||
// C++ Includes
|
||||
// Other libraries and framework includes
|
||||
// Project includes
|
||||
#include "lldb/lldb-private.h"
|
||||
#include "lldb/Target/RegisterContext.h"
|
||||
|
||||
class RegisterContextDarwin_i386 : public lldb_private::RegisterContext
|
||||
{
|
||||
public:
|
||||
|
||||
RegisterContextDarwin_i386(lldb_private::Thread &thread,
|
||||
uint32_t concrete_frame_idx);
|
||||
|
||||
virtual
|
||||
~RegisterContextDarwin_i386();
|
||||
|
||||
virtual void
|
||||
InvalidateAllRegisters ();
|
||||
|
||||
virtual size_t
|
||||
GetRegisterCount ();
|
||||
|
||||
virtual const lldb_private::RegisterInfo *
|
||||
GetRegisterInfoAtIndex (uint32_t reg);
|
||||
|
||||
virtual size_t
|
||||
GetRegisterSetCount ();
|
||||
|
||||
virtual const lldb_private::RegisterSet *
|
||||
GetRegisterSet (uint32_t set);
|
||||
|
||||
virtual bool
|
||||
ReadRegister (const lldb_private::RegisterInfo *reg_info, lldb_private::RegisterValue &value);
|
||||
|
||||
virtual bool
|
||||
WriteRegister (const lldb_private::RegisterInfo *reg_info, const lldb_private::RegisterValue &value);
|
||||
|
||||
virtual bool
|
||||
ReadAllRegisterValues (lldb::DataBufferSP &data_sp);
|
||||
|
||||
virtual bool
|
||||
WriteAllRegisterValues (const lldb::DataBufferSP &data_sp);
|
||||
|
||||
virtual uint32_t
|
||||
ConvertRegisterKindToRegisterNumber (uint32_t kind, uint32_t num);
|
||||
|
||||
virtual bool
|
||||
HardwareSingleStep (bool enable);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
void
|
||||
LogGPR (lldb_private::Log *log, const char *title);
|
||||
|
||||
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)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
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 ();
|
||||
};
|
||||
|
||||
#endif // liblldb_RegisterContextDarwin_i386_h_
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,293 @@
|
|||
//===-- RegisterContextDarwin_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_RegisterContextDarwin_x86_64_h_
|
||||
#define liblldb_RegisterContextDarwin_x86_64_h_
|
||||
|
||||
// C Includes
|
||||
// C++ Includes
|
||||
// Other libraries and framework includes
|
||||
// Project includes
|
||||
#include "lldb/lldb-private.h"
|
||||
#include "lldb/Target/RegisterContext.h"
|
||||
|
||||
class RegisterContextDarwin_x86_64 : public lldb_private::RegisterContext
|
||||
{
|
||||
public:
|
||||
RegisterContextDarwin_x86_64 (lldb_private::Thread &thread,
|
||||
uint32_t concrete_frame_idx);
|
||||
|
||||
virtual
|
||||
~RegisterContextDarwin_x86_64();
|
||||
|
||||
virtual void
|
||||
InvalidateAllRegisters ();
|
||||
|
||||
virtual size_t
|
||||
GetRegisterCount ();
|
||||
|
||||
virtual const lldb_private::RegisterInfo *
|
||||
GetRegisterInfoAtIndex (uint32_t reg);
|
||||
|
||||
virtual size_t
|
||||
GetRegisterSetCount ();
|
||||
|
||||
virtual const lldb_private::RegisterSet *
|
||||
GetRegisterSet (uint32_t set);
|
||||
|
||||
virtual bool
|
||||
ReadRegister (const lldb_private::RegisterInfo *reg_info, lldb_private::RegisterValue &value);
|
||||
|
||||
virtual bool
|
||||
WriteRegister (const lldb_private::RegisterInfo *reg_info, const lldb_private::RegisterValue &value);
|
||||
|
||||
virtual bool
|
||||
ReadAllRegisterValues (lldb::DataBufferSP &data_sp);
|
||||
|
||||
virtual bool
|
||||
WriteAllRegisterValues (const lldb::DataBufferSP &data_sp);
|
||||
|
||||
virtual uint32_t
|
||||
ConvertRegisterKindToRegisterNumber (uint32_t kind, uint32_t num);
|
||||
|
||||
virtual bool
|
||||
HardwareSingleStep (bool enable);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
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 ();
|
||||
|
||||
};
|
||||
|
||||
#endif // liblldb_RegisterContextDarwin_x86_64_h_
|
|
@ -31,5 +31,116 @@ enum
|
|||
gcc_cpsr
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
// Name Nr Rel Offset Size Type Raw value
|
||||
gdb_arm_r0 = 0, // 0 0 4 int32_t
|
||||
gdb_arm_r1 = 1, // 1 4 4 int32_t
|
||||
gdb_arm_r2 = 2, // 2 8 4 int32_t
|
||||
gdb_arm_r3 = 3, // 3 12 4 int32_t
|
||||
gdb_arm_r4 = 4, // 4 16 4 int32_t
|
||||
gdb_arm_r5 = 5, // 5 20 4 int32_t
|
||||
gdb_arm_r6 = 6, // 6 24 4 int32_t
|
||||
gdb_arm_r7 = 7, // 7 28 4 int32_t
|
||||
gdb_arm_r8 = 8, // 8 32 4 int32_t
|
||||
gdb_arm_r9 = 9, // 9 36 4 int32_t
|
||||
gdb_arm_r10 = 10, // 10 40 4 int32_t
|
||||
gdb_arm_r11 = 11, // 11 44 4 int32_t
|
||||
gdb_arm_r12 = 12, // 12 48 4 int32_t
|
||||
gdb_arm_sp = 13, // 13 52 4 int32_t
|
||||
gdb_arm_lr = 14, // 14 56 4 int32_t
|
||||
gdb_arm_pc = 15, // 15 60 4 int32_t
|
||||
gdb_arm_f0 = 16, // 16 64 12 _arm_ext_littlebyte_bigword
|
||||
gdb_arm_f1 = 17, // 17 76 12 _arm_ext_littlebyte_bigword
|
||||
gdb_arm_f2 = 18, // 18 88 12 _arm_ext_littlebyte_bigword
|
||||
gdb_arm_f3 = 19, // 19 100 12 _arm_ext_littlebyte_bigword
|
||||
gdb_arm_f4 = 20, // 20 112 12 _arm_ext_littlebyte_bigword
|
||||
gdb_arm_f5 = 21, // 21 124 12 _arm_ext_littlebyte_bigword
|
||||
gdb_arm_f6 = 22, // 22 136 12 _arm_ext_littlebyte_bigword
|
||||
gdb_arm_f7 = 23, // 23 148 12 _arm_ext_littlebyte_bigword
|
||||
gdb_arm_f8 = 24, // 24 160 12 _arm_ext_littlebyte_bigword
|
||||
gdb_arm_cpsr = 25, // 25 172 4 int32_t
|
||||
gdb_arm_s0 = 26, // 26 176 4 _ieee_single_little
|
||||
gdb_arm_s1 = 27, // 27 180 4 _ieee_single_little
|
||||
gdb_arm_s2 = 28, // 28 184 4 _ieee_single_little
|
||||
gdb_arm_s3 = 29, // 29 188 4 _ieee_single_little
|
||||
gdb_arm_s4 = 30, // 30 192 4 _ieee_single_little
|
||||
gdb_arm_s5 = 31, // 31 196 4 _ieee_single_little
|
||||
gdb_arm_s6 = 32, // 32 200 4 _ieee_single_little
|
||||
gdb_arm_s7 = 33, // 33 204 4 _ieee_single_little
|
||||
gdb_arm_s8 = 34, // 34 208 4 _ieee_single_little
|
||||
gdb_arm_s9 = 35, // 35 212 4 _ieee_single_little
|
||||
gdb_arm_s10 = 36, // 36 216 4 _ieee_single_little
|
||||
gdb_arm_s11 = 37, // 37 220 4 _ieee_single_little
|
||||
gdb_arm_s12 = 38, // 38 224 4 _ieee_single_little
|
||||
gdb_arm_s13 = 39, // 39 228 4 _ieee_single_little
|
||||
gdb_arm_s14 = 40, // 40 232 4 _ieee_single_little
|
||||
gdb_arm_s15 = 41, // 41 236 4 _ieee_single_little
|
||||
gdb_arm_s16 = 42, // 42 240 4 _ieee_single_little
|
||||
gdb_arm_s17 = 43, // 43 244 4 _ieee_single_little
|
||||
gdb_arm_s18 = 44, // 44 248 4 _ieee_single_little
|
||||
gdb_arm_s19 = 45, // 45 252 4 _ieee_single_little
|
||||
gdb_arm_s20 = 46, // 46 256 4 _ieee_single_little
|
||||
gdb_arm_s21 = 47, // 47 260 4 _ieee_single_little
|
||||
gdb_arm_s22 = 48, // 48 264 4 _ieee_single_little
|
||||
gdb_arm_s23 = 49, // 49 268 4 _ieee_single_little
|
||||
gdb_arm_s24 = 50, // 50 272 4 _ieee_single_little
|
||||
gdb_arm_s25 = 51, // 51 276 4 _ieee_single_little
|
||||
gdb_arm_s26 = 52, // 52 280 4 _ieee_single_little
|
||||
gdb_arm_s27 = 53, // 53 284 4 _ieee_single_little
|
||||
gdb_arm_s28 = 54, // 54 288 4 _ieee_single_little
|
||||
gdb_arm_s29 = 55, // 55 292 4 _ieee_single_little
|
||||
gdb_arm_s30 = 56, // 56 296 4 _ieee_single_little
|
||||
gdb_arm_s31 = 57, // 57 300 4 _ieee_single_little
|
||||
gdb_arm_fpscr = 58, // 58 304 4 int32_t
|
||||
gdb_arm_d16 = 59, // 59 308 8 _ieee_double_little
|
||||
gdb_arm_d17 = 60, // 60 316 8 _ieee_double_little
|
||||
gdb_arm_d18 = 61, // 61 324 8 _ieee_double_little
|
||||
gdb_arm_d19 = 62, // 62 332 8 _ieee_double_little
|
||||
gdb_arm_d20 = 63, // 63 340 8 _ieee_double_little
|
||||
gdb_arm_d21 = 64, // 64 348 8 _ieee_double_little
|
||||
gdb_arm_d22 = 65, // 65 356 8 _ieee_double_little
|
||||
gdb_arm_d23 = 66, // 66 364 8 _ieee_double_little
|
||||
gdb_arm_d24 = 67, // 67 372 8 _ieee_double_little
|
||||
gdb_arm_d25 = 68, // 68 380 8 _ieee_double_little
|
||||
gdb_arm_d26 = 69, // 69 388 8 _ieee_double_little
|
||||
gdb_arm_d27 = 70, // 70 396 8 _ieee_double_little
|
||||
gdb_arm_d28 = 71, // 71 404 8 _ieee_double_little
|
||||
gdb_arm_d29 = 72, // 72 412 8 _ieee_double_little
|
||||
gdb_arm_d30 = 73, // 73 420 8 _ieee_double_little
|
||||
gdb_arm_d31 = 74, // 74 428 8 _ieee_double_little
|
||||
gdb_arm_d0 = 75, // 0 436 8 _ieee_double_little
|
||||
gdb_arm_d1 = 76, // 1 444 8 _ieee_double_little
|
||||
gdb_arm_d2 = 77, // 2 452 8 _ieee_double_little
|
||||
gdb_arm_d3 = 78, // 3 460 8 _ieee_double_little
|
||||
gdb_arm_d4 = 79, // 4 468 8 _ieee_double_little
|
||||
gdb_arm_d5 = 80, // 5 476 8 _ieee_double_little
|
||||
gdb_arm_d6 = 81, // 6 484 8 _ieee_double_little
|
||||
gdb_arm_d7 = 82, // 7 492 8 _ieee_double_little
|
||||
gdb_arm_d8 = 83, // 8 500 8 _ieee_double_little
|
||||
gdb_arm_d9 = 84, // 9 508 8 _ieee_double_little
|
||||
gdb_arm_d10 = 85, // 10 516 8 _ieee_double_little
|
||||
gdb_arm_d11 = 86, // 11 524 8 _ieee_double_little
|
||||
gdb_arm_d12 = 87, // 12 532 8 _ieee_double_little
|
||||
gdb_arm_d13 = 88, // 13 540 8 _ieee_double_little
|
||||
gdb_arm_d14 = 89, // 14 548 8 _ieee_double_little
|
||||
gdb_arm_d15 = 90, // 15 556 8 _ieee_double_little
|
||||
gdb_arm_q0 = 91, // 16 564 16 _vec128
|
||||
gdb_arm_q1 = 92, // 17 580 16 _vec128
|
||||
gdb_arm_q2 = 93, // 18 596 16 _vec128
|
||||
gdb_arm_q3 = 94, // 19 612 16 _vec128
|
||||
gdb_arm_q4 = 95, // 20 628 16 _vec128
|
||||
gdb_arm_q5 = 96, // 21 644 16 _vec128
|
||||
gdb_arm_q6 = 97, // 22 660 16 _vec128
|
||||
gdb_arm_q7 = 98, // 23 676 16 _vec128
|
||||
gdb_arm_q8 = 99, // 24 692 16 _vec128
|
||||
gdb_arm_q9 = 100, // 25 708 16 _vec128
|
||||
gdb_arm_q10 = 101, // 26 724 16 _vec128
|
||||
gdb_arm_q11 = 102, // 27 740 16 _vec128
|
||||
gdb_arm_q12 = 103, // 28 756 16 _vec128
|
||||
gdb_arm_q13 = 104, // 29 772 16 _vec128
|
||||
gdb_arm_q14 = 105, // 30 788 16 _vec128
|
||||
gdb_arm_q15 = 106 // 31 804 16 _vec128
|
||||
};
|
||||
#endif // utility_ARM_GCC_Registers_h_
|
||||
|
||||
|
|
Loading…
Reference in New Issue