Leaked source code of windows server 2003
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.

664 lines
26 KiB

  1. //----------------------------------------------------------------------------
  2. //
  3. // Abstraction of processor-specific information.
  4. //
  5. // Copyright (C) Microsoft Corporation, 1999-2002.
  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. #define FORM_VM86 0x00000001
  60. #define FORM_CODE 0x00000002
  61. #define FORM_SEGREG 0x00000004
  62. #define X86_FORM_VM86(Efl) \
  63. (X86_IS_VM86(Efl) ? FORM_VM86 : 0)
  64. #define X86_RPL_MASK 3
  65. #define MPTE_FLAG_VALID 0x00000001
  66. #define PAGE_ALIGN(Machine, Addr) \
  67. ((Addr) & ~((ULONG64)((Machine)->m_PageSize - 1)))
  68. #define NEXT_PAGE(Machine, Addr) \
  69. (((Addr) + (Machine)->m_PageSize) & \
  70. ~((ULONG64)((Machine)->m_PageSize - 1)))
  71. typedef struct _ADDR_RANGE
  72. {
  73. ULONG64 Base;
  74. ULONG Size;
  75. } ADDR_RANGE, *PADDR_RANGE;
  76. #define MAX_ALT_ADDR_RANGES 4
  77. //
  78. // InsertBreakpointInstruction flags. These
  79. // are processor specific.
  80. //
  81. #define IBI_DEFAULT 0x00000000
  82. // The low six bits on IA64 indicate which predicate
  83. // register to use in the break instruction.
  84. #define IBI_IA64_PRED_MASK 0x0000003f
  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. struct RegisterGroup
  105. {
  106. // Counted automatically.
  107. ULONG NumberRegs;
  108. // Regs is assumed to be non-NULL in all groups.
  109. // SubRegs and AllExtraDesc may be NULL in any group.
  110. REGDEF* Regs;
  111. REGSUBDEF* SubRegs;
  112. REGALLDESC* AllExtraDesc;
  113. };
  114. // Trace modes used by SetTraceMode/GetTraceMode functions
  115. typedef enum
  116. {
  117. TRACE_NONE,
  118. TRACE_INSTRUCTION,
  119. TRACE_TAKEN_BRANCH
  120. } TRACEMODE;
  121. // These enumerants are abstract values but currently
  122. // only IA64 actually has different page directories
  123. // so set them up to match the IA64 mapping for convenience.
  124. enum
  125. {
  126. PAGE_DIR_USER,
  127. PAGE_DIR_SESSION,
  128. PAGE_DIR_KERNEL = 7,
  129. PAGE_DIR_COUNT
  130. };
  131. // For machines which only support a single page directory
  132. // take it from the kernel slot. All will be updated so
  133. // this is an arbitrary choice.
  134. #define PAGE_DIR_SINGLE PAGE_DIR_KERNEL
  135. // All directories bit mask.
  136. #define PAGE_DIR_ALL ((1 << PAGE_DIR_COUNT) - 1)
  137. // Flags for GetPrefixedSymbolOffset.
  138. #define GETPREF_VERBOSE 0x00000001
  139. #define MAX_REGISTER_GROUPS 8
  140. struct CvRegMap
  141. {
  142. CV_HREG_e CvReg;
  143. ULONG Machine;
  144. };
  145. struct ContextSave
  146. {
  147. ULONG ContextState;
  148. BOOL ReadOnly;
  149. CROSS_PLATFORM_CONTEXT Context;
  150. CROSS_PLATFORM_KSPECIAL_REGISTERS Special;
  151. DESCRIPTOR64 SegRegDesc[SEGREG_COUNT];
  152. };
  153. class MachineInfo
  154. {
  155. public:
  156. MachineInfo(TargetInfo* Target);
  157. virtual ~MachineInfo(void);
  158. TargetInfo* m_Target;
  159. // Descriptive information.
  160. PCSTR m_FullName;
  161. PCSTR m_AbbrevName;
  162. ULONG m_PageSize;
  163. ULONG m_PageShift;
  164. ULONG m_NumExecTypes;
  165. // First entry must be the actual processor type.
  166. PULONG m_ExecTypes;
  167. BOOL m_Ptr64;
  168. ULONG m_RetRegIndex;
  169. // Automatically counted from regs in base initialization.
  170. ULONG m_NumRegs;
  171. ULONG m_NumGroups;
  172. RegisterGroup* m_Groups[MAX_REGISTER_GROUPS];
  173. ULONG m_AllMask;
  174. // Collected automatically from groups.
  175. ULONG m_AllMaskBits;
  176. ULONG m_MaxDataBreakpoints;
  177. PCSTR m_SymPrefix;
  178. // Computed automatically.
  179. ULONG m_SymPrefixLen;
  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 a system version to see if the target provides
  184. // canonical contexts or not.
  185. ULONG m_SverCanonicalContext;
  186. // Context could be kept per-thread
  187. // so that several can be around at once for a cache.
  188. // That would also make the save/restore stuff unnecessary.
  189. ULONG m_ContextState;
  190. CROSS_PLATFORM_CONTEXT m_Context;
  191. CROSS_PLATFORM_KSPECIAL_REGISTERS m_Special;
  192. // Segment register descriptors. These will only
  193. // be valid on processors that support them, otherwise
  194. // they will be marked invalid.
  195. DESCRIPTOR64 m_SegRegDesc[SEGREG_COUNT];
  196. // Holds the current page directory offsets.
  197. ULONG64 m_PageDirectories[PAGE_DIR_COUNT];
  198. BOOL m_Translating;
  199. BOOL m_ContextIsReadOnly;
  200. USHORT m_MainCodeSeg;
  201. ULONG m_CvRegMapSize;
  202. CvRegMap* m_CvRegMap;
  203. virtual HRESULT Initialize(void);
  204. virtual HRESULT InitializeForProcessor(void);
  205. virtual void GetSystemTypeInfo(PSYSTEM_TYPE_INFO Info) = 0;
  206. virtual void GetDefaultKdData(PKDDEBUGGER_DATA64 KdData) = 0;
  207. ULONG CvRegToMachine(CV_HREG_e CvReg);
  208. virtual void InitializeContext
  209. (ULONG64 Pc, PDBGKD_ANY_CONTROL_REPORT ControlReport) = 0;
  210. HRESULT GetContextState(ULONG State);
  211. HRESULT SetContext(void);
  212. // Base implementations use Get/SetThreadContext for
  213. // any request.
  214. virtual HRESULT UdGetContextState(ULONG State);
  215. virtual HRESULT UdSetContext(void);
  216. virtual HRESULT KdGetContextState(ULONG State) = 0;
  217. virtual HRESULT KdSetContext(void) = 0;
  218. // Base implementation sets ContextState to NONE.
  219. virtual void InvalidateContext(void);
  220. // Context conversion is version-based rather than size-based
  221. // as the size is ambiguous in certain cases. For example,
  222. // ALPHA_CONTEXT and ALPHA_NT5_CONTEXT are the same size
  223. // so additional information is necessary to distinguish them.
  224. virtual HRESULT ConvertContextFrom(PCROSS_PLATFORM_CONTEXT Context,
  225. ULONG FromSver,
  226. ULONG FromSize, PVOID From) = 0;
  227. virtual HRESULT ConvertContextTo(PCROSS_PLATFORM_CONTEXT Context,
  228. ULONG ToSver, ULONG ToSize, PVOID To) = 0;
  229. virtual void InitializeContextFlags(PCROSS_PLATFORM_CONTEXT Context,
  230. ULONG Version) = 0;
  231. virtual HRESULT GetContextFromThreadStack(ULONG64 ThreadBase,
  232. PCROSS_PLATFORM_CONTEXT Context,
  233. ULONG64 Stack) = 0;
  234. virtual HRESULT GetContextFromFiber(ProcessInfo* Process,
  235. ULONG64 FiberBase,
  236. PCROSS_PLATFORM_CONTEXT Context,
  237. BOOL Verbose) = 0;
  238. virtual HRESULT GetContextFromTrapFrame(ULONG64 TrapBase,
  239. PCROSS_PLATFORM_CONTEXT Context,
  240. BOOL Verbose) = 0;
  241. // Base implementation fails for platforms that don't
  242. // have task segments.
  243. virtual HRESULT GetContextFromTaskSegment(ULONG64 TssBase,
  244. PCROSS_PLATFORM_CONTEXT Context,
  245. BOOL Verbose);
  246. virtual void GetScopeFrameFromContext(PCROSS_PLATFORM_CONTEXT Context,
  247. PDEBUG_STACK_FRAME ScopeFrame) = 0;
  248. // Base implementation zeros addresses.
  249. virtual void GetStackDefaultsFromContext(PCROSS_PLATFORM_CONTEXT Context,
  250. LPADDRESS64 Instr,
  251. LPADDRESS64 Stack,
  252. LPADDRESS64 Frame);
  253. virtual HRESULT GetScopeFrameRegister(ULONG Reg,
  254. PDEBUG_STACK_FRAME ScopeFrame,
  255. PULONG64 Value) = 0;
  256. virtual HRESULT SetScopeFrameRegister(ULONG Reg,
  257. PDEBUG_STACK_FRAME ScopeFrame,
  258. ULONG64 Value) = 0;
  259. // Base implementation does nothing.
  260. virtual void SanitizeMemoryContext(PCROSS_PLATFORM_CONTEXT Context);
  261. // Base implementations return E_NOTIMPL.
  262. virtual HRESULT GetExdiContext(IUnknown* Exdi,
  263. PEXDI_CONTEXT Context,
  264. EXDI_CONTEXT_TYPE CtxType);
  265. virtual HRESULT SetExdiContext(IUnknown* Exdi,
  266. PEXDI_CONTEXT Context,
  267. EXDI_CONTEXT_TYPE CtxType);
  268. virtual void ConvertExdiContextFromContext(PCROSS_PLATFORM_CONTEXT Context,
  269. PEXDI_CONTEXT ExdiContext,
  270. EXDI_CONTEXT_TYPE CtxType);
  271. virtual void ConvertExdiContextToContext(PEXDI_CONTEXT ExdiContext,
  272. EXDI_CONTEXT_TYPE CtxType,
  273. PCROSS_PLATFORM_CONTEXT Context);
  274. virtual void ConvertExdiContextToSegDescs(PEXDI_CONTEXT ExdiContext,
  275. EXDI_CONTEXT_TYPE CtxType,
  276. ULONG Start, ULONG Count,
  277. PDESCRIPTOR64 Descs);
  278. virtual void ConvertExdiContextFromSpecial
  279. (PCROSS_PLATFORM_KSPECIAL_REGISTERS Special,
  280. PEXDI_CONTEXT ExdiContext,
  281. EXDI_CONTEXT_TYPE CtxType);
  282. virtual void ConvertExdiContextToSpecial
  283. (PEXDI_CONTEXT ExdiContext,
  284. EXDI_CONTEXT_TYPE CtxType,
  285. PCROSS_PLATFORM_KSPECIAL_REGISTERS Special);
  286. virtual int GetType(ULONG Reg) = 0;
  287. virtual HRESULT GetVal(ULONG Reg, REGVAL* Val) = 0;
  288. virtual HRESULT SetVal(ULONG Reg, 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. virtual ULONG64 GetRetReg(void) = 0;
  295. // Base implementations return zero and FALSE.
  296. virtual ULONG GetSegRegNum(ULONG SegReg);
  297. virtual HRESULT GetSegRegDescriptor(ULONG SegReg, PDESCRIPTOR64 Desc);
  298. virtual void OutputAll(ULONG Mask, ULONG OutMask) = 0;
  299. virtual HRESULT SetAndOutputTrapFrame(ULONG64 TrapBase,
  300. PCROSS_PLATFORM_CONTEXT Context) = 0;
  301. // Base implementation fails for platforms that don't
  302. // have task segments.
  303. virtual HRESULT SetAndOutputTaskSegment(ULONG64 TssBase,
  304. PCROSS_PLATFORM_CONTEXT Context,
  305. BOOL Extended);
  306. virtual TRACEMODE GetTraceMode(void) = 0;
  307. virtual void SetTraceMode(TRACEMODE Mode) = 0;
  308. // Returns true if trace mode appropriate to specified execution status
  309. // (e.g. DEBUG_STATUS_STEP_OVER, DEBUG_STATUS_STEP_INTO,
  310. // DEBUG_STATUS_STEP_BRANCH...) supported by the machine.
  311. virtual BOOL IsStepStatusSupported(ULONG Status) = 0;
  312. void QuietSetTraceMode(TRACEMODE Mode)
  313. {
  314. BOOL ContextChangedOrg = g_ContextChanged;
  315. SetTraceMode(Mode);
  316. g_ContextChanged = ContextChangedOrg;
  317. }
  318. // Base implementation does nothing.
  319. virtual void KdUpdateControlSet
  320. (PDBGKD_ANY_CONTROL_SET ControlSet);
  321. virtual ULONG ExecutingMachine(void) = 0;
  322. virtual HRESULT SetPageDirectory(ThreadInfo* Thread,
  323. ULONG Idx, ULONG64 PageDir,
  324. PULONG NextIdx) = 0;
  325. HRESULT SetDefaultPageDirectories(ThreadInfo* Thread, ULONG Mask);
  326. virtual HRESULT GetVirtualTranslationPhysicalOffsets
  327. (ThreadInfo* Thread, ULONG64 Virt, PULONG64 Offsets, ULONG OffsetsSize,
  328. PULONG Levels, PULONG PfIndex, PULONG64 LastVal) = 0;
  329. virtual HRESULT GetBaseTranslationVirtualOffset(PULONG64 Offset) = 0;
  330. virtual void DecodePte(ULONG64 Pte, PULONG64 PageFrameNumber,
  331. PULONG Flags) = 0;
  332. virtual void Assemble(ProcessInfo* Process,
  333. PADDR Addr, PSTR Input) = 0;
  334. virtual BOOL Disassemble(ProcessInfo* Process,
  335. PADDR Addr, PSTR Buffer, BOOL EffAddr) = 0;
  336. // Creates new Breakpoint object compatible with specific machine
  337. virtual HRESULT NewBreakpoint(DebugClient* Client,
  338. ULONG Type,
  339. ULONG Id,
  340. Breakpoint** RetBp);
  341. virtual BOOL IsBreakpointInstruction(ProcessInfo* Process, PADDR Addr) = 0;
  342. virtual HRESULT InsertBreakpointInstruction(PUSER_DEBUG_SERVICES Services,
  343. ULONG64 Process,
  344. ULONG64 Offset,
  345. ULONG Flags,
  346. PUCHAR SaveInstr,
  347. PULONG64 ChangeStart,
  348. PULONG ChangeLen) = 0;
  349. virtual HRESULT RemoveBreakpointInstruction(PUSER_DEBUG_SERVICES Services,
  350. ULONG64 Process,
  351. ULONG64 Offset,
  352. PUCHAR SaveInstr,
  353. PULONG64 ChangeStart,
  354. PULONG ChangeLen) = 0;
  355. virtual void AdjustPCPastBreakpointInstruction(PADDR Addr,
  356. ULONG BreakType) = 0;
  357. // Base implementations do nothing for platforms which
  358. // do not support data breakpoints.
  359. virtual void InsertThreadDataBreakpoints(void);
  360. virtual void RemoveThreadDataBreakpoints(void);
  361. // Base implementation returns EXCEPTION_BRAKEPOINT_ANY
  362. // for STATUS_BREAKPOINT.
  363. virtual ULONG IsBreakpointOrStepException(PEXCEPTION_RECORD64 Record,
  364. ULONG FirstChance,
  365. PADDR BpAddr,
  366. PADDR RelAddr);
  367. virtual BOOL IsCallDisasm(PCSTR Disasm) = 0;
  368. virtual BOOL IsReturnDisasm(PCSTR Disasm) = 0;
  369. virtual BOOL IsSystemCallDisasm(PCSTR Disasm) = 0;
  370. virtual BOOL IsDelayInstruction(PADDR Addr) = 0;
  371. virtual void GetEffectiveAddr(PADDR Addr, PULONG Size) = 0;
  372. // Some processors, such as IA64, have instructions which
  373. // switch between instruction sets, thus the machine type
  374. // of the next offset may be different from the current machine.
  375. // If the NextAddr is OFFSET_TRACE the NextMachine is ignored.
  376. virtual void GetNextOffset(ProcessInfo* Process, BOOL StepOver,
  377. PADDR NextAddr, PULONG NextMachine) = 0;
  378. // Base implementation returns the value from StackWalk.
  379. virtual void GetRetAddr(PADDR Addr);
  380. // Base implementation does nothing for machines which
  381. // do not have symbol prefixing.
  382. virtual BOOL GetPrefixedSymbolOffset(ProcessInfo* Process,
  383. ULONG64 SymOffset,
  384. ULONG Flags,
  385. PULONG64 PrefixedSymOffset);
  386. virtual void IncrementBySmallestInstruction(PADDR Addr) = 0;
  387. virtual void DecrementBySmallestInstruction(PADDR Addr) = 0;
  388. // Output function entry information for the given entry.
  389. virtual void OutputFunctionEntry(PVOID RawEntry) = 0;
  390. // Base implementation returns E_UNEXPECTED.
  391. virtual HRESULT ReadDynamicFunctionTable(ProcessInfo* Process,
  392. ULONG64 Table,
  393. PULONG64 NextTable,
  394. PULONG64 MinAddress,
  395. PULONG64 MaxAddress,
  396. PULONG64 BaseAddress,
  397. PULONG64 TableData,
  398. PULONG TableSize,
  399. PWSTR OutOfProcessDll,
  400. PCROSS_PLATFORM_DYNAMIC_FUNCTION_TABLE RawTable);
  401. // Base implementation returns NULL.
  402. virtual PVOID FindDynamicFunctionEntry(PCROSS_PLATFORM_DYNAMIC_FUNCTION_TABLE Table,
  403. ULONG64 Address,
  404. PVOID TableData,
  405. ULONG TableSize);
  406. // Base implementation returns E_UNEXPECTED.
  407. virtual HRESULT GetUnwindInfoBounds(ProcessInfo* Process,
  408. ULONG64 TableBase,
  409. PVOID RawTableEntries,
  410. ULONG EntryIndex,
  411. PULONG64 Start,
  412. PULONG Size);
  413. virtual HRESULT ReadKernelProcessorId
  414. (ULONG Processor, PDEBUG_PROCESSOR_IDENTIFICATION_ALL Id) = 0;
  415. // Base implementation discards page directory entries.
  416. virtual void FlushPerExecutionCaches(void);
  417. // Base implementation does nothing.
  418. virtual HRESULT GetAlternateTriageDumpDataRanges(ULONG64 PrcbBase,
  419. ULONG64 ThreadBase,
  420. PADDR_RANGE Ranges);
  421. // Stack output functions
  422. virtual void PrintStackFrameAddressesTitle(ULONG Flags);
  423. virtual void PrintStackFrameAddresses(ULONG Flags,
  424. PDEBUG_STACK_FRAME StackFrame);
  425. virtual void PrintStackArgumentsTitle(ULONG Flags);
  426. virtual void PrintStackArguments(ULONG Flags,
  427. PDEBUG_STACK_FRAME StackFrame);
  428. virtual void PrintStackCallSiteTitle(ULONG Flags);
  429. virtual void PrintStackCallSite(ULONG Flags,
  430. PDEBUG_STACK_FRAME StackFrame,
  431. PSYMBOL_INFO SiteSymbol,
  432. PSTR SymName,
  433. DWORD64 Displacement);
  434. virtual void PrintStackNonvolatileRegisters
  435. (ULONG Flags,
  436. PDEBUG_STACK_FRAME StackFrame,
  437. PCROSS_PLATFORM_CONTEXT Context,
  438. ULONG FrameNum);
  439. virtual void PrintStackFrameMemoryUsage(PDEBUG_STACK_FRAME CurFrame,
  440. PDEBUG_STACK_FRAME PrevFrame);
  441. //
  442. // Helpers for convenient value access.
  443. //
  444. // Note that the basic methods here do not get the register
  445. // type as is done in the generic code. All of these methods
  446. // assume that the proper call is being made for the register.
  447. // The Get/SetReg methods also only operate on real registers, not
  448. // subregisters. Use the Get/SetSubReg methods when dealing
  449. // with subregisters.
  450. //
  451. // Alternately, FullGet/SetVal perform all the necessary
  452. // work for typing and subregisters.
  453. //
  454. USHORT GetReg16(ULONG Reg)
  455. {
  456. REGVAL RegVal;
  457. RegVal.I64 = 0;
  458. GetVal(Reg, &RegVal);
  459. return RegVal.I16;
  460. }
  461. ULONG GetReg32(ULONG Reg)
  462. {
  463. REGVAL RegVal;
  464. RegVal.I64 = 0;
  465. GetVal(Reg, &RegVal);
  466. return RegVal.I32;
  467. }
  468. void SetReg32(ULONG Reg, ULONG Val)
  469. {
  470. REGVAL RegVal;
  471. RegVal.Type = REGVAL_INT32;
  472. RegVal.I64 = (ULONG64)Val;
  473. SetVal(Reg, &RegVal);
  474. }
  475. ULONG64 GetReg64(ULONG Reg)
  476. {
  477. REGVAL RegVal;
  478. RegVal.I64 = 0;
  479. GetVal(Reg, &RegVal);
  480. return RegVal.I64;
  481. }
  482. HRESULT SetReg64(ULONG Reg, ULONG64 Val)
  483. {
  484. REGVAL RegVal;
  485. RegVal.Type = REGVAL_INT64;
  486. RegVal.I64 = Val;
  487. RegVal.Nat = FALSE;
  488. return SetVal(Reg, &RegVal);
  489. }
  490. ULONG GetSubReg32(ULONG SubReg)
  491. {
  492. REGVAL RegVal;
  493. REGSUBDEF* SubDef = RegSubDefFromIndex(SubReg);
  494. if (!SubDef)
  495. {
  496. return 0;
  497. }
  498. RegVal.I64 = 0;
  499. GetVal(SubDef->FullReg, &RegVal);
  500. return (ULONG)((RegVal.I64 >> SubDef->Shift) & SubDef->Mask);
  501. }
  502. HRESULT FullGetVal(ULONG Reg, REGVAL* Val);
  503. ULONG FullGetVal32(ULONG Reg)
  504. {
  505. REGVAL RegVal;
  506. RegVal.I64 = 0;
  507. FullGetVal(Reg, &RegVal);
  508. return RegVal.I32;
  509. }
  510. ULONG64 FullGetVal64(ULONG Reg)
  511. {
  512. REGVAL RegVal;
  513. RegVal.I64 = 0;
  514. FullGetVal(Reg, &RegVal);
  515. return RegVal.I64;
  516. }
  517. HRESULT FullSetVal(ULONG Reg, REGVAL* Val);
  518. HRESULT FullSetVal32(ULONG Reg, ULONG Val)
  519. {
  520. REGVAL RegVal;
  521. ZeroMemory(&RegVal, sizeof(RegVal));
  522. RegVal.Type = GetType(Reg);
  523. RegVal.I32 = Val;
  524. return FullSetVal(Reg, &RegVal);
  525. }
  526. HRESULT FullSetVal64(ULONG Reg, ULONG64 Val)
  527. {
  528. REGVAL RegVal;
  529. ZeroMemory(&RegVal, sizeof(RegVal));
  530. RegVal.Type = GetType(Reg);
  531. RegVal.I64 = Val;
  532. return FullSetVal(Reg, &RegVal);
  533. }
  534. // Helper function to initialize an ADDR given a flat
  535. // offset from a known segment or segment register.
  536. void FormAddr(ULONG SegOrReg, ULONG64 Off, ULONG Flags,
  537. PADDR Address);
  538. REGSUBDEF* RegSubDefFromIndex(ULONG Index);
  539. REGDEF* RegDefFromIndex(ULONG Index);
  540. REGDEF* RegDefFromCount(ULONG Count);
  541. ULONG RegCountFromIndex(ULONG Index);
  542. ContextSave* PushContext(PCROSS_PLATFORM_CONTEXT Context);
  543. void PopContext(ContextSave* Save);
  544. protected:
  545. TRACEMODE m_TraceMode;
  546. // Common helpers for disassembly.
  547. PCHAR m_Buf, m_BufStart;
  548. void BufferHex(ULONG64 Value, ULONG Length, BOOL Signed);
  549. void BufferInt(ULONG64 Value, ULONG MinLength, BOOL Signed);
  550. void BufferBlanks(ULONG BufferPos);
  551. void BufferString(PCSTR String);
  552. void PrintMultiPtrTitle(const CHAR* Title, USHORT PtrNum);
  553. };
  554. extern ULONG g_PossibleProcessorTypes[MACHIDX_COUNT];
  555. MachineInfo* NewMachineInfo(ULONG Index, ULONG BaseMachineType,
  556. TargetInfo* Target);
  557. MachineIndex MachineTypeIndex(ULONG Machine);
  558. // g_AllMachines has a NULL at MACHIDX_COUNT to handle errors.
  559. #define MachineTypeInfo(Target, Machine) \
  560. (Target)->m_Machines[MachineTypeIndex(Machine)]
  561. void CacheReportInstructions(ULONG64 Pc, ULONG Count, PUCHAR Stream);
  562. BOOL IsImageMachineType64(DWORD MachineType);
  563. extern CHAR g_F0[], g_F1[], g_F2[], g_F3[], g_F4[], g_F5[];
  564. extern CHAR g_F6[], g_F7[], g_F8[], g_F9[], g_F10[], g_F11[];
  565. extern CHAR g_F12[], g_F13[], g_F14[], g_F15[], g_F16[], g_F17[];
  566. extern CHAR g_F18[], g_F19[], g_F20[], g_F21[], g_F22[], g_F23[];
  567. extern CHAR g_F24[], g_F25[], g_F26[], g_F27[], g_F28[], g_F29[];
  568. extern CHAR g_F30[], g_F31[];
  569. extern CHAR g_R0[], g_R1[], g_R2[], g_R3[], g_R4[], g_R5[];
  570. extern CHAR g_R6[], g_R7[], g_R8[], g_R9[], g_R10[], g_R11[];
  571. extern CHAR g_R12[], g_R13[], g_R14[], g_R15[], g_R16[], g_R17[];
  572. extern CHAR g_R18[], g_R19[], g_R20[], g_R21[], g_R22[], g_R23[];
  573. extern CHAR g_R24[], g_R25[], g_R26[], g_R27[], g_R28[], g_R29[];
  574. extern CHAR g_R30[], g_R31[];
  575. #endif // #ifndef __MACHINE_HPP__