Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

600 lines
23 KiB

  1. //----------------------------------------------------------------------------
  2. //
  3. // Abstraction of processor-specific information.
  4. //
  5. // Copyright (C) Microsoft Corporation, 1999-2001.
  6. //
  7. //----------------------------------------------------------------------------
  8. #ifndef __MACHINE_HPP__
  9. #define __MACHINE_HPP__
  10. // These context information states are intended to be shared among
  11. // processors so they may not all apply to each processor. The important
  12. // thing is that they are ordered from less information to more.
  13. // Each state includes all the information from the states that precede it.
  14. // More states can be inserted anywhere as new processors require them.
  15. #define MCTX_NONE 0 // No context information.
  16. #define MCTX_PC 1 // Program counter.
  17. #define MCTX_DR67_REPORT 2 // X86: DR6,7 control report.
  18. #define MCTX_REPORT 3 // Control report.
  19. #define MCTX_CONTEXT 4 // Kernel protocol context information.
  20. #define MCTX_FULL 5 // All possible information.
  21. #define MCTX_DIRTY 6 // Dirty context, implies full information.
  22. // Constant offset value returned from GetNextOffset to indicate the
  23. // trace flag should be used.
  24. #define OFFSET_TRACE ((ULONG64)(LONG64)-1)
  25. #define OFFSET_TRACE_32 ((ULONG)OFFSET_TRACE)
  26. // Distinguished error code for GetVirtualTranslationPhysicalOffsets
  27. // to indicate that all translations were successful but
  28. // the page was not present. In this case the LastVal value
  29. // will contain the page file offset and PfIndex will contain
  30. // the page file number.
  31. #define HR_PAGE_IN_PAGE_FILE HRESULT_FROM_NT(STATUS_PAGE_FAULT_PAGING_FILE)
  32. // Translation could not complete and a page file location
  33. // for the data could not be determined.
  34. #define HR_PAGE_NOT_AVAILABLE HRESULT_FROM_NT(STATUS_NO_PAGEFILE)
  35. #define MAX_PAGING_FILE_MASK 0xf
  36. //
  37. // Segment register access.
  38. // Processors which do not support segment registers return
  39. // zero for the segment register number.
  40. //
  41. enum
  42. {
  43. // Descriptor table pseudo-segments. The GDT does
  44. // not have a specific register number.
  45. // These pseudo-segments should be first so that
  46. // index zero is not used for a normal segreg.
  47. SEGREG_GDT,
  48. SEGREG_LDT,
  49. // Generic segments.
  50. SEGREG_CODE,
  51. SEGREG_DATA,
  52. SEGREG_STACK,
  53. // Extended segments.
  54. SEGREG_ES,
  55. SEGREG_FS,
  56. SEGREG_GS,
  57. SEGREG_COUNT
  58. };
  59. //
  60. // Segment descriptor values.
  61. // Due to the descriptor caching that x86 processors
  62. // do this may differ from the actual in-memory descriptor and
  63. // may be retrieved in a much different way.
  64. //
  65. // Special flags value that marks a descriptor as invalid.
  66. #define SEGDESC_INVALID 0xffffffff
  67. #define X86_DESC_TYPE(Flags) ((Flags) & 0x1f)
  68. #define X86_DESC_PRIVILEGE_SHIFT 5
  69. #define X86_DESC_PRIVILEGE(Flags) (((Flags) >> X86_DESC_PRIVILEGE_SHIFT) & 3)
  70. #define X86_DESC_PRESENT 0x80
  71. #define X86_DESC_LONG_MODE 0x200
  72. #define X86_DESC_DEFAULT_BIG 0x400
  73. #define X86_DESC_GRANULARITY 0x800
  74. typedef struct _DESCRIPTOR64
  75. {
  76. ULONG64 Base;
  77. ULONG64 Limit;
  78. ULONG Flags;
  79. } DESCRIPTOR64, *PDESCRIPTOR64;
  80. #define FORM_VM86 0x00000001
  81. #define FORM_CODE 0x00000002
  82. #define FORM_SEGREG 0x00000004
  83. #define X86_FORM_VM86(Efl) \
  84. (X86_IS_VM86(Efl) ? FORM_VM86 : 0)
  85. //----------------------------------------------------------------------------
  86. //
  87. // Abstract interface for machine information. All possible
  88. // machine-specific implementations of this interface exist at
  89. // all times. The effective implementation is selected when
  90. // SetEffMachine is called. For generic access the abstract
  91. // interface should be used. In machine-specific code the
  92. // specific implementation classes can be used.
  93. //
  94. // IMPORTANT: Be very careful when using machine-specific header files
  95. // such as nt<plat>.h. The machine implementation class is
  96. // compiled for all platforms so the nt<plat>.h file will be the
  97. // one for the build platform, not necessarily the platform
  98. // of the machine implementation. ntdbg.h contains many cross-platform
  99. // types and definitions that can be used to avoid problems.
  100. //
  101. //----------------------------------------------------------------------------
  102. extern BOOL g_PrefixSymbols;
  103. extern BOOL g_ContextChanged;
  104. extern DEBUG_PROCESSOR_IDENTIFICATION_ALL g_InitProcessorId;
  105. struct RegisterGroup
  106. {
  107. RegisterGroup* Next;
  108. // Counted automatically.
  109. ULONG NumberRegs;
  110. // Regs is assumed to be non-NULL in all groups.
  111. // SubRegs and AllExtraDesc may be NULL in any group.
  112. REGDEF* Regs;
  113. REGSUBDEF* SubRegs;
  114. REGALLDESC* AllExtraDesc;
  115. };
  116. // Trace modes used by SetTraceMode/GetTraceMode functions
  117. typedef enum
  118. {
  119. TRACE_NONE,
  120. TRACE_INSTRUCTION,
  121. TRACE_TAKEN_BRANCH
  122. } TRACEMODE;
  123. // These enumerants are abstract values but currently
  124. // only IA64 actually has different page directories
  125. // so set them up to match the IA64 mapping for convenience.
  126. enum
  127. {
  128. PAGE_DIR_USER,
  129. PAGE_DIR_SESSION,
  130. PAGE_DIR_KERNEL = 7,
  131. PAGE_DIR_COUNT
  132. };
  133. // For machines which only support a single page directory
  134. // take it from the kernel slot. All will be updated so
  135. // this is an arbitrary choice.
  136. #define PAGE_DIR_SINGLE PAGE_DIR_KERNEL
  137. // All directories bit mask.
  138. #define PAGE_DIR_ALL ((1 << PAGE_DIR_COUNT) - 1)
  139. // Flags for GetPrefixedSymbolOffset.
  140. #define GETPREF_VERBOSE 0x00000001
  141. class MachineInfo
  142. {
  143. public:
  144. // Descriptive information.
  145. PCSTR m_FullName;
  146. PCSTR m_AbbrevName;
  147. ULONG m_PageSize;
  148. ULONG m_PageShift;
  149. ULONG m_NumExecTypes;
  150. // First ExecTypes entry must be the actual processor type.
  151. PULONG m_ExecTypes;
  152. BOOL m_Ptr64;
  153. // Automatically counted from regs in base Initialize.
  154. ULONG m_NumberRegs;
  155. RegisterGroup* m_Groups;
  156. ULONG m_AllMask;
  157. // Collected automatically from groups.
  158. ULONG m_AllMaskBits;
  159. ULONG m_MaxDataBreakpoints;
  160. PCSTR m_SymPrefix;
  161. // Computed automatically.
  162. ULONG m_SymPrefixLen;
  163. // Hard-coded type information for machine and platform version.
  164. ULONG m_OffsetPrcbProcessorState;
  165. ULONG m_OffsetPrcbNumber;
  166. ULONG64 m_TriagePrcbOffset;
  167. ULONG m_SizePrcb;
  168. ULONG m_OffsetKThreadApcProcess;
  169. ULONG m_OffsetKThreadTeb;
  170. ULONG m_OffsetKThreadInitialStack;
  171. ULONG m_OffsetEprocessPeb;
  172. ULONG m_OffsetEprocessDirectoryTableBase;
  173. ULONG m_OffsetKThreadNextProcessor;
  174. // Size of the native context for the target machine.
  175. ULONG m_SizeTargetContext;
  176. // Offset of the flags ULONG in the native context.
  177. ULONG m_OffsetTargetContextFlags;
  178. // Control space offset for special registers.
  179. ULONG m_OffsetSpecialRegisters;
  180. // Size of the canonical context kept in the MachineInfo.
  181. ULONG m_SizeCanonicalContext;
  182. // System version of the canonical context. Can be compared
  183. // against g_SystemVersion to see if the target provides
  184. // canonical contexts or not.
  185. ULONG m_SverCanonicalContext;
  186. ULONG m_SizeControlReport;
  187. ULONG m_SizeEThread;
  188. ULONG m_SizeEProcess;
  189. ULONG m_SizeKspecialRegisters;
  190. // Size of the debugger's *_THREAD partial structure.
  191. ULONG m_SizePartialKThread;
  192. ULONG64 m_SharedUserDataOffset;
  193. // Context could be kept per-thread
  194. // so that several can be around at once for a cache.
  195. // That would also make the save/restore stuff unnecessary.
  196. ULONG m_ContextState;
  197. CROSS_PLATFORM_CONTEXT m_Context;
  198. // Segment register descriptors. These will only
  199. // be valid on processors that support them, otherwise
  200. // they will be marked invalid.
  201. DESCRIPTOR64 m_SegRegDesc[SEGREG_COUNT];
  202. DESCRIPTOR64 m_SavedSegRegDesc[SEGREG_COUNT];
  203. // Holds the current page directory offsets.
  204. ULONG64 m_PageDirectories[PAGE_DIR_COUNT];
  205. BOOL m_Translating;
  206. BOOL m_ContextIsReadOnly;
  207. // InitializeConstants initializes information which is
  208. // fixed and unaffected by the type of target being debugged.
  209. // InitializeForTarget initializes information which
  210. // varies according to the particular type of target being debugged.
  211. // InitializeForProcessor initializes information which
  212. // varies according to the particular type of processor that's
  213. // present in the target as described by g_InitProcessorId.
  214. // Derived classes should call base Initialize* after
  215. // their own initialization.
  216. virtual HRESULT InitializeConstants(void);
  217. virtual HRESULT InitializeForTarget(void);
  218. virtual HRESULT InitializeForProcessor(void);
  219. virtual void InitializeContext
  220. (ULONG64 Pc, PDBGKD_ANY_CONTROL_REPORT ControlReport) = 0;
  221. HRESULT GetContextState(ULONG State);
  222. HRESULT SetContext(void);
  223. // Base implementations use Get/SetThreadContext for
  224. // any request.
  225. virtual HRESULT UdGetContextState(ULONG State);
  226. virtual HRESULT UdSetContext(void);
  227. virtual HRESULT KdGetContextState(ULONG State) = 0;
  228. virtual HRESULT KdSetContext(void) = 0;
  229. // Base implementation sets ContextState to NONE.
  230. virtual void InvalidateContext(void);
  231. // Context conversion is version-based rather than size-based
  232. // as the size is ambiguous in certain cases. For example,
  233. // ALPHA_CONTEXT and ALPHA_NT5_CONTEXT are the same size
  234. // so additional information is necessary to distinguish them.
  235. virtual HRESULT ConvertContextFrom(PCROSS_PLATFORM_CONTEXT Context,
  236. ULONG FromSver,
  237. ULONG FromSize, PVOID From) = 0;
  238. virtual HRESULT ConvertContextTo(PCROSS_PLATFORM_CONTEXT Context,
  239. ULONG ToSver, ULONG ToSize, PVOID To) = 0;
  240. virtual void InitializeContextFlags(PCROSS_PLATFORM_CONTEXT Context,
  241. ULONG Version) = 0;
  242. virtual HRESULT GetContextFromThreadStack(ULONG64 ThreadBase,
  243. PCROSS_PLATFORM_THREAD Thread,
  244. PCROSS_PLATFORM_CONTEXT Context,
  245. PDEBUG_STACK_FRAME Frame,
  246. PULONG RunningOnProc) = 0;
  247. // Base implementations return E_NOTIMPL.
  248. virtual HRESULT GetExdiContext(IUnknown* Exdi, PEXDI_CONTEXT Context);
  249. virtual HRESULT SetExdiContext(IUnknown* Exdi, PEXDI_CONTEXT Context);
  250. virtual void ConvertExdiContextFromContext(PCROSS_PLATFORM_CONTEXT Context,
  251. PEXDI_CONTEXT ExdiContext);
  252. virtual void ConvertExdiContextToContext(PEXDI_CONTEXT ExdiContext,
  253. PCROSS_PLATFORM_CONTEXT Context);
  254. virtual void ConvertExdiContextToSegDescs(PEXDI_CONTEXT ExdiContext,
  255. ULONG Start, ULONG Count,
  256. PDESCRIPTOR64 Descs);
  257. virtual void ConvertExdiContextFromSpecial
  258. (PCROSS_PLATFORM_KSPECIAL_REGISTERS Special,
  259. PEXDI_CONTEXT ExdiContext);
  260. virtual void ConvertExdiContextToSpecial
  261. (PEXDI_CONTEXT ExdiContext,
  262. PCROSS_PLATFORM_KSPECIAL_REGISTERS Special);
  263. // A simple one-deep temporary save stack for CONTEXT information.
  264. // Useful when you want to swap in an arbitrary context for
  265. // some machine operation. This uses the same save area
  266. // as KdSave/RestoreProcessorState so the two should
  267. // not be used together.
  268. void PushContext(PCROSS_PLATFORM_CONTEXT Context)
  269. {
  270. DBG_ASSERT (!m_ContextIsReadOnly);
  271. m_SavedContextState = m_ContextState;
  272. m_SavedContext = m_Context;
  273. memcpy(m_SavedSegRegDesc, m_SegRegDesc, sizeof(m_SegRegDesc));
  274. m_Context = *Context;
  275. m_ContextState = MCTX_FULL;
  276. m_ContextIsReadOnly = TRUE;
  277. }
  278. void PopContext(void)
  279. {
  280. DBG_ASSERT((m_ContextState != MCTX_DIRTY) && (m_ContextIsReadOnly));
  281. m_Context = m_SavedContext;
  282. m_ContextState = m_SavedContextState;
  283. memcpy(m_SegRegDesc, m_SavedSegRegDesc, sizeof(m_SegRegDesc));
  284. m_ContextIsReadOnly = FALSE;
  285. }
  286. virtual int GetType(ULONG index) = 0;
  287. virtual BOOL GetVal(ULONG index, REGVAL *val) = 0;
  288. virtual BOOL SetVal(ULONG index, REGVAL *val) = 0;
  289. virtual void GetPC(PADDR Address) = 0;
  290. virtual void SetPC(PADDR Address) = 0;
  291. virtual void GetFP(PADDR Address) = 0;
  292. virtual void GetSP(PADDR Address) = 0;
  293. virtual ULONG64 GetArgReg(void) = 0;
  294. // Base implementations return zero and FALSE.
  295. virtual ULONG GetSegRegNum(ULONG SegReg);
  296. virtual HRESULT GetSegRegDescriptor(ULONG SegReg, PDESCRIPTOR64 Desc);
  297. virtual void OutputAll(ULONG Mask, ULONG OutMask) = 0;
  298. virtual TRACEMODE GetTraceMode(void) = 0;
  299. virtual void SetTraceMode(TRACEMODE Mode) = 0;
  300. // Returns true if trace mode appropriate to specified execution status
  301. // (e.g. DEBUG_STATUS_STEP_OVER, DEBUG_STATUS_STEP_INTO,
  302. // DEBUG_STATUS_STEP_BRANCH...) supported by the machine.
  303. virtual BOOL IsStepStatusSupported(ULONG Status) = 0;
  304. void QuietSetTraceMode(TRACEMODE Mode)
  305. {
  306. BOOL ContextChangedOrg = g_ContextChanged;
  307. SetTraceMode(Mode);
  308. g_ContextChanged = ContextChangedOrg;
  309. }
  310. // Base implementation does nothing.
  311. virtual void KdUpdateControlSet
  312. (PDBGKD_ANY_CONTROL_SET ControlSet);
  313. // Base implementations save and restore m_Context and m_ContextState.
  314. virtual void KdSaveProcessorState(void);
  315. virtual void KdRestoreProcessorState(void);
  316. virtual ULONG ExecutingMachine(void) = 0;
  317. virtual HRESULT SetPageDirectory(ULONG Idx, ULONG64 PageDir,
  318. PULONG NextIdx) = 0;
  319. HRESULT SetDefaultPageDirectories(ULONG Mask);
  320. virtual HRESULT GetVirtualTranslationPhysicalOffsets
  321. (ULONG64 Virt, PULONG64 Offsets, ULONG OffsetsSize,
  322. PULONG Levels, PULONG PfIndex, PULONG64 LastVal) = 0;
  323. virtual HRESULT GetBaseTranslationVirtualOffset(PULONG64 Offset) = 0;
  324. virtual void Assemble(PADDR Addr, PSTR Input) = 0;
  325. virtual BOOL Disassemble(PADDR Addr, PSTR Buffer, BOOL EffAddr) = 0;
  326. // Creates new Breakpoint object compatible with specific machine
  327. virtual HRESULT NewBreakpoint(DebugClient* Client,
  328. ULONG Type,
  329. ULONG Id,
  330. Breakpoint** RetBp);
  331. virtual BOOL IsBreakpointInstruction(PADDR Addr) = 0;
  332. virtual HRESULT InsertBreakpointInstruction(PUSER_DEBUG_SERVICES Services,
  333. ULONG64 Process,
  334. ULONG64 Offset,
  335. PUCHAR SaveInstr,
  336. PULONG64 ChangeStart,
  337. PULONG ChangeLen) = 0;
  338. virtual HRESULT RemoveBreakpointInstruction(PUSER_DEBUG_SERVICES Services,
  339. ULONG64 Process,
  340. ULONG64 Offset,
  341. PUCHAR SaveInstr,
  342. PULONG64 ChangeStart,
  343. PULONG ChangeLen) = 0;
  344. virtual void AdjustPCPastBreakpointInstruction(PADDR Addr,
  345. ULONG BreakType) = 0;
  346. // Base implementations do nothing for platforms which
  347. // do not support data breakpoints.
  348. virtual void InsertAllDataBreakpoints(void);
  349. virtual void RemoveAllDataBreakpoints(void);
  350. // Base implementation returns EXCEPTION_BRAKEPOINT_ANY
  351. // for STATUS_BREAKPOINT.
  352. virtual ULONG IsBreakpointOrStepException(PEXCEPTION_RECORD64 Record,
  353. ULONG FirstChance,
  354. PADDR BpAddr,
  355. PADDR RelAddr);
  356. virtual BOOL IsCallDisasm(PCSTR Disasm) = 0;
  357. virtual BOOL IsReturnDisasm(PCSTR Disasm) = 0;
  358. virtual BOOL IsSystemCallDisasm(PCSTR Disasm) = 0;
  359. virtual BOOL IsDelayInstruction(PADDR Addr) = 0;
  360. virtual void GetEffectiveAddr(PADDR Addr) = 0;
  361. // Some processors, such as IA64, have instructions which
  362. // switch between instruction sets, thus the machine type
  363. // of the next offset may be different from the current machine.
  364. // If the NextAddr is OFFSET_TRACE the NextMachine is ignored.
  365. virtual void GetNextOffset(BOOL StepOver,
  366. PADDR NextAddr, PULONG NextMachine) = 0;
  367. // Base implementation returns the value from StackWalk.
  368. virtual void GetRetAddr(PADDR Addr);
  369. // Base implementation does nothing for machines which
  370. // do not have symbol prefixing.
  371. virtual BOOL GetPrefixedSymbolOffset(ULONG64 SymOffset,
  372. ULONG Flags,
  373. PULONG64 PrefixedSymOffset);
  374. virtual void IncrementBySmallestInstruction(PADDR Addr) = 0;
  375. virtual void DecrementBySmallestInstruction(PADDR Addr) = 0;
  376. virtual BOOL DisplayTrapFrame(ULONG64 FrameAddress,
  377. PCROSS_PLATFORM_CONTEXT Context) = 0;
  378. virtual void ValidateCxr(PCROSS_PLATFORM_CONTEXT Context) = 0;
  379. // Output function entry information for the given entry.
  380. virtual void OutputFunctionEntry(PVOID RawEntry) = 0;
  381. // Base implementation returns E_UNEXPECTED.
  382. virtual HRESULT ReadDynamicFunctionTable(ULONG64 Table,
  383. PULONG64 NextTable,
  384. PULONG64 MinAddress,
  385. PULONG64 MaxAddress,
  386. PULONG64 BaseAddress,
  387. PULONG64 TableData,
  388. PULONG TableSize,
  389. PWSTR OutOfProcessDll,
  390. PCROSS_PLATFORM_DYNAMIC_FUNCTION_TABLE RawTable);
  391. // Base implementation returns NULL.
  392. virtual PVOID FindDynamicFunctionEntry(PCROSS_PLATFORM_DYNAMIC_FUNCTION_TABLE Table,
  393. ULONG64 Address,
  394. PVOID TableData,
  395. ULONG TableSize);
  396. virtual HRESULT ReadKernelProcessorId
  397. (ULONG Processor, PDEBUG_PROCESSOR_IDENTIFICATION_ALL Id) = 0;
  398. // Base implementation discards page directory entries.
  399. virtual void FlushPerExecutionCaches(void);
  400. // Stack output functions
  401. virtual void PrintStackFrameAddressesTitle(ULONG Flags);
  402. virtual void PrintStackFrameAddresses(ULONG Flags,
  403. PDEBUG_STACK_FRAME StackFrame);
  404. virtual void PrintStackArgumentsTitle(ULONG Flags);
  405. virtual void PrintStackArguments(ULONG Flags,
  406. PDEBUG_STACK_FRAME StackFrame);
  407. virtual void PrintStackCallSiteTitle(ULONG Flags);
  408. virtual void PrintStackCallSite(ULONG Flags,
  409. PDEBUG_STACK_FRAME StackFrame,
  410. CHAR SymBuf[], DWORD64 Displacement,
  411. USHORT StdCallArgs);
  412. virtual void PrintStackNonvolatileRegisters(ULONG Flags,
  413. PDEBUG_STACK_FRAME StackFrame,
  414. PCROSS_PLATFORM_CONTEXT Context,
  415. ULONG FrameNum);
  416. //
  417. // IMPORTANT
  418. //
  419. // Helpers for convenient value access. When in machine code
  420. // these helpers are preferred to Get/SetRegVal* because
  421. // they stay in the same machine whereas the generic code
  422. // always uses g_Machine. If a caller makes a direct call
  423. // on a specific machine g_Machine may not match so the
  424. // generic code will not work properly.
  425. //
  426. // Note that the set methods here do not get the register
  427. // type as is done in the generic code. All of these methods
  428. // assume that the proper call is being made for the register.
  429. // The Get/SetReg methods also only operate on real registers, not
  430. // subregisters. Use the Get/SetSubReg methods when dealing
  431. // with subregisters.
  432. //
  433. USHORT GetReg16(ULONG Reg)
  434. {
  435. REGVAL RegVal;
  436. RegVal.i64 = 0;
  437. GetVal(Reg, &RegVal);
  438. return RegVal.i16;
  439. }
  440. ULONG GetReg32(ULONG Reg)
  441. {
  442. REGVAL RegVal;
  443. RegVal.i64 = 0;
  444. GetVal(Reg, &RegVal);
  445. return RegVal.i32;
  446. }
  447. void SetReg32(ULONG Reg, ULONG Val)
  448. {
  449. REGVAL RegVal;
  450. RegVal.type = REGVAL_INT32;
  451. RegVal.i64 = 0;
  452. RegVal.i32 = Val;
  453. SetVal(Reg, &RegVal);
  454. }
  455. ULONG64 GetReg64(ULONG Reg)
  456. {
  457. REGVAL RegVal;
  458. RegVal.i64 = 0;
  459. GetVal(Reg, &RegVal);
  460. return RegVal.i64;
  461. }
  462. void SetReg64(ULONG Reg, ULONG64 Val)
  463. {
  464. REGVAL RegVal;
  465. RegVal.type = REGVAL_INT64;
  466. RegVal.i64 = Val;
  467. RegVal.Nat = FALSE;
  468. SetVal(Reg, &RegVal);
  469. }
  470. ULONG GetSubReg32(ULONG SubReg)
  471. {
  472. REGVAL RegVal;
  473. REGSUBDEF* SubDef = RegSubDefFromIndex(SubReg);
  474. if (!SubDef)
  475. {
  476. return 0;
  477. }
  478. RegVal.i64 = 0;
  479. GetVal(SubDef->fullreg, &RegVal);
  480. return (ULONG)((RegVal.i64 >> SubDef->shift) & SubDef->mask);
  481. }
  482. // Helper function to initialize an ADDR given a flat
  483. // offset from a known segment or segment register.
  484. void FormAddr(ULONG SegOrReg, ULONG64 Off, ULONG Flags,
  485. PADDR Address);
  486. protected:
  487. TRACEMODE m_TraceMode;
  488. // KdSave/Restore state.
  489. ULONG m_SavedContextState;
  490. CROSS_PLATFORM_CONTEXT m_SavedContext;
  491. // Common helpers for disassembly.
  492. PCHAR m_Buf, m_BufStart;
  493. void BufferHex(ULONG64 Value, ULONG Length, BOOL Signed);
  494. void BufferBlanks(ULONG BufferPos);
  495. void BufferString(PCSTR String);
  496. void PrintMultiPtrTitle(const CHAR* Title, USHORT PtrNum);
  497. };
  498. // Effective machine settings.
  499. extern ULONG g_EffMachine;
  500. extern MachineIndex g_EffMachineIndex;
  501. extern MachineInfo* g_Machine;
  502. // Target machine settings.
  503. extern MachineInfo* g_TargetMachine;
  504. extern MachineInfo* g_AllMachines[];
  505. HRESULT InitializeMachines(ULONG TargetMachine);
  506. MachineIndex MachineTypeIndex(ULONG Machine);
  507. // g_AllMachines has a NULL at MACHIDX_COUNT to handle errors.
  508. #define MachineTypeInfo(Machine) g_AllMachines[MachineTypeIndex(Machine)]
  509. void CacheReportInstructions(ULONG64 Pc, ULONG Count, PUCHAR Stream);
  510. void FlushMachinePerExecutionCaches(void);
  511. extern CHAR g_F0[], g_F1[], g_F2[], g_F3[], g_F4[], g_F5[];
  512. extern CHAR g_F6[], g_F7[], g_F8[], g_F9[], g_F10[], g_F11[];
  513. extern CHAR g_F12[], g_F13[], g_F14[], g_F15[], g_F16[], g_F17[];
  514. extern CHAR g_F18[], g_F19[], g_F20[], g_F21[], g_F22[], g_F23[];
  515. extern CHAR g_F24[], g_F25[], g_F26[], g_F27[], g_F28[], g_F29[];
  516. extern CHAR g_F30[], g_F31[];
  517. extern CHAR g_R0[], g_R1[], g_R2[], g_R3[], g_R4[], g_R5[];
  518. extern CHAR g_R6[], g_R7[], g_R8[], g_R9[], g_R10[], g_R11[];
  519. extern CHAR g_R12[], g_R13[], g_R14[], g_R15[], g_R16[], g_R17[];
  520. extern CHAR g_R18[], g_R19[], g_R20[], g_R21[], g_R22[], g_R23[];
  521. extern CHAR g_R24[], g_R25[], g_R26[], g_R27[], g_R28[], g_R29[];
  522. extern CHAR g_R30[], g_R31[];
  523. #endif // #ifndef __MACHINE_HPP__