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.

1656 lines
47 KiB

  1. /*** alpha_reg.c - processor-specific register structures
  2. *
  3. * Copyright <C> 1990-2001, Microsoft Corporation
  4. * Copyright <C> 1992, Digital Equipment Corporation
  5. *
  6. * Purpose:
  7. * Structures used to parse and access register and flag
  8. * fields.
  9. *
  10. * Revision History:
  11. *
  12. * [-] 08-Aug-1992 Miche Baker-Harvey Created for Alpha
  13. * [-] 01-Jul-1990 Richk Created.
  14. *
  15. *************************************************************************/
  16. #include "ntsdp.hpp"
  17. #include "alpha_strings.h"
  18. #include "alpha_optable.h"
  19. // See Get/SetRegVal comments in machine.hpp.
  20. #define RegValError Do_not_use_GetSetRegVal_in_machine_implementations
  21. #define GetRegVal(index, val) RegValError
  22. #define GetRegVal32(index) RegValError
  23. #define GetRegVal64(index) RegValError
  24. #define SetRegVal(index, val) RegValError
  25. #define SetRegVal32(index, val) RegValError
  26. #define SetRegVal64(index, val) RegValError
  27. #define IS_FLOATING_SAVED(Register) ((SAVED_FLOATING_MASK >> Register) & 1L)
  28. #define IS_INTEGER_SAVED(Register) ((SAVED_INTEGER_MASK >> Register) & 1L)
  29. //
  30. // Define saved register masks.
  31. #define SAVED_FLOATING_MASK 0xfff00000 // saved floating registers
  32. #define SAVED_INTEGER_MASK 0xf3ffff02 // saved integer registers
  33. //
  34. // Instruction opcode values are defined in alphaops.h
  35. //
  36. REGDEF AlphaRegs[] =
  37. {
  38. g_F0, ALPHA_F0, g_F1, ALPHA_F1, g_F2, ALPHA_F2, g_F3, ALPHA_F3,
  39. g_F4, ALPHA_F4, g_F5, ALPHA_F5, g_F6, ALPHA_F6, g_F7, ALPHA_F7,
  40. g_F8, ALPHA_F8, g_F9, ALPHA_F9, g_F10, ALPHA_F10, g_F11, ALPHA_F11,
  41. g_F12, ALPHA_F12, g_F13, ALPHA_F13, g_F14, ALPHA_F14, g_F15, ALPHA_F15,
  42. g_F16, ALPHA_F16, g_F17, ALPHA_F17, g_F18, ALPHA_F18, g_F19, ALPHA_F19,
  43. g_F20, ALPHA_F20, g_F21, ALPHA_F21, g_F22, ALPHA_F22, g_F23, ALPHA_F23,
  44. g_F24, ALPHA_F24, g_F25, ALPHA_F25, g_F26, ALPHA_F26, g_F27, ALPHA_F27,
  45. g_F28, ALPHA_F28, g_F29, ALPHA_F29, g_F30, ALPHA_F30, g_F31, ALPHA_F31,
  46. g_AlphaV0, ALPHA_V0, g_AlphaT0, ALPHA_T0, g_AlphaT1, ALPHA_T1, g_AlphaT2, ALPHA_T2,
  47. g_AlphaT3, ALPHA_T3, g_AlphaT4, ALPHA_T4, g_AlphaT5, ALPHA_T5, g_AlphaT6, ALPHA_T6,
  48. g_AlphaT7, ALPHA_T7, g_AlphaS0, ALPHA_S0, g_AlphaS1, ALPHA_S1, g_AlphaS2, ALPHA_S2,
  49. g_AlphaS3, ALPHA_S3, g_AlphaS4, ALPHA_S4, g_AlphaS5, ALPHA_S5, g_AlphaFP, ALPHA_FP,
  50. g_AlphaA0, ALPHA_A0, g_AlphaA1, ALPHA_A1, g_AlphaA2, ALPHA_A2, g_AlphaA3, ALPHA_A3,
  51. g_AlphaA4, ALPHA_A4, g_AlphaA5, ALPHA_A5, g_AlphaT8, ALPHA_T8, g_AlphaT9, ALPHA_T9,
  52. g_AlphaT10, ALPHA_T10, g_AlphaT11, ALPHA_T11, g_AlphaRA, ALPHA_RA,
  53. g_AlphaT12, ALPHA_T12, g_AlphaAT, ALPHA_AT, g_AlphaGP, ALPHA_GP,
  54. g_AlphaSP, ALPHA_SP, g_AlphaZero, ALPHA_ZERO,
  55. szFpcr, ALPHA_FPCR, szSoftFpcr, ALPHA_SFTFPCR, szFir, ALPHA_FIR,
  56. szPsr, ALPHA_PSR,
  57. szFlagMode, ALPHA_MODE, szFlagIe, ALPHA_IE, szFlagIrql, ALPHA_IRQL,
  58. NULL, 0,
  59. };
  60. //
  61. // PSR & IE definitions are from ksalpha.h
  62. // which is generated automatically.
  63. // Steal from \\bbox2\alphado\nt\public\sdk\inc\ksalpha.h
  64. // NB: our masks are already shifted:
  65. //
  66. REGSUBDEF AlphaSubRegs[] =
  67. {
  68. { ALPHA_MODE, ALPHA_PSR, ALPHA_PSR_MODE, ALPHA_PSR_MODE_MASK },
  69. { ALPHA_IE, ALPHA_PSR, ALPHA_PSR_IE, ALPHA_PSR_IE_MASK },
  70. { ALPHA_IRQL, ALPHA_PSR, ALPHA_PSR_IRQL, ALPHA_PSR_IRQL_MASK },
  71. { REG_ERROR, REG_ERROR, 0, 0 },
  72. };
  73. RegisterGroup g_AlphaGroup =
  74. {
  75. NULL, 0, AlphaRegs, AlphaSubRegs, NULL
  76. };
  77. // First ExecTypes entry must be the actual processor type.
  78. ULONG g_Axp32ExecTypes[] =
  79. {
  80. IMAGE_FILE_MACHINE_ALPHA
  81. };
  82. // First ExecTypes entry must be the actual processor type.
  83. ULONG g_Axp64ExecTypes[] =
  84. {
  85. IMAGE_FILE_MACHINE_AXP64
  86. };
  87. Axp32MachineInfo g_Axp32Machine;
  88. Axp64MachineInfo g_Axp64Machine;
  89. HRESULT
  90. AlphaMachineInfo::InitializeConstants(void)
  91. {
  92. HRESULT Status;
  93. m_Groups = &g_AlphaGroup;
  94. m_AllMask = REGALL_INT64;
  95. m_MaxDataBreakpoints = 0;
  96. m_SymPrefix = NULL;
  97. // 32/64-bit values are set in the specific Initialize.
  98. // Alpha-generic values are here.
  99. C_ASSERT(sizeof(ALPHA_CONTEXT) == sizeof(ALPHA_NT5_CONTEXT));
  100. m_SizeTargetContext = sizeof(ALPHA_NT5_CONTEXT);
  101. m_OffsetTargetContextFlags = FIELD_OFFSET(ALPHA_NT5_CONTEXT, ContextFlags);
  102. m_SizeCanonicalContext = sizeof(ALPHA_NT5_CONTEXT);
  103. m_SverCanonicalContext = NT_SVER_NT4;
  104. m_SizeControlReport = sizeof(ALPHA_DBGKD_CONTROL_REPORT);
  105. m_OffsetSpecialRegisters = 0;
  106. m_SizeKspecialRegisters = 0;
  107. if ((Status = opTableInit()) != S_OK)
  108. {
  109. return Status;
  110. }
  111. return MachineInfo::InitializeConstants();
  112. }
  113. void
  114. AlphaMachineInfo::
  115. InitializeContext(ULONG64 Pc,
  116. PDBGKD_ANY_CONTROL_REPORT ControlReport)
  117. {
  118. m_Context.AlphaNt5Context.Fir = Pc;
  119. m_ContextState = Pc ? MCTX_PC : MCTX_NONE;
  120. if (Pc && ControlReport != NULL)
  121. {
  122. CacheReportInstructions
  123. (Pc, ControlReport->AlphaControlReport.InstructionCount,
  124. ControlReport->AlphaControlReport.InstructionStream);
  125. }
  126. }
  127. HRESULT
  128. AlphaMachineInfo::KdGetContextState(ULONG State)
  129. {
  130. // MCTX_CONTEXT and MCTX_FULL are the same for Alpha.
  131. if (State >= MCTX_CONTEXT && m_ContextState < MCTX_FULL)
  132. {
  133. HRESULT Status;
  134. Status = g_Target->GetContext(g_RegContextThread->Handle, &m_Context);
  135. if (Status != S_OK)
  136. {
  137. return Status;
  138. }
  139. m_ContextState = MCTX_FULL;
  140. }
  141. return S_OK;
  142. }
  143. HRESULT
  144. AlphaMachineInfo::KdSetContext(void)
  145. {
  146. return g_Target->SetContext(g_RegContextThread->Handle, &m_Context);
  147. }
  148. HRESULT
  149. AlphaMachineInfo::ConvertContextFrom(PCROSS_PLATFORM_CONTEXT Context,
  150. ULONG FromSver,
  151. ULONG FromSize, PVOID From)
  152. {
  153. if (FromSize < sizeof(ALPHA_NT5_CONTEXT))
  154. {
  155. return E_INVALIDARG;
  156. }
  157. PALPHA_CONTEXT Ctx = (PALPHA_CONTEXT)From;
  158. // ALPHA_CONTEXT has been floating around for a while
  159. // for use by the debugger. The system hasn't used it
  160. // so they shouldn't ever end up here but go ahead
  161. // and try and detect them based on the flags.
  162. if (Ctx->ContextFlags != ALPHA_CONTEXT_FULL)
  163. {
  164. // This doesn't look like an ALPHA_CONTEXT, check
  165. // ALPHA_NT5_CONTEXT.
  166. if (((PALPHA_NT5_CONTEXT)From)->ContextFlags !=
  167. ALPHA_CONTEXT_FULL)
  168. {
  169. return E_INVALIDARG;
  170. }
  171. // It looks like an ALPHA_NT5_CONTEXT so don't convert.
  172. memcpy(Context, From, sizeof(ALPHA_NT5_CONTEXT));
  173. }
  174. else
  175. {
  176. PULONG High;
  177. PULONG Low;
  178. PULONGLONG Full;
  179. int Count;
  180. Low = &Ctx->FltF0;
  181. High = &Ctx->HighFltF0;
  182. Full = &Context->AlphaNt5Context.FltF0;
  183. for (Count = 0; Count < 32; Count++)
  184. {
  185. Full[Count] = Low[Count] + ((ULONGLONG)High[Count] << 32);
  186. }
  187. Low = &Ctx->IntV0;
  188. High = &Ctx->HighIntV0;
  189. Full = &Context->AlphaNt5Context.IntV0;
  190. for (Count = 0; Count < 32; Count++)
  191. {
  192. Full[Count] = Low[Count] + ((ULONGLONG)High[Count] << 32);
  193. }
  194. Context->AlphaNt5Context.ContextFlags = Ctx->ContextFlags;
  195. Context->AlphaNt5Context.Psr = Ctx->Psr;
  196. Context->AlphaNt5Context.Fpcr =
  197. Ctx->Fpcr + ((ULONGLONG)Ctx->HighFpcr << 32);
  198. Context->AlphaNt5Context.SoftFpcr =
  199. Ctx->SoftFpcr + ((ULONGLONG)Ctx->HighSoftFpcr << 32);
  200. Context->AlphaNt5Context.Fir =
  201. Ctx->Fir + ((ULONGLONG)Ctx->HighFir << 32);
  202. }
  203. return S_OK;
  204. }
  205. HRESULT
  206. AlphaMachineInfo::ConvertContextTo(PCROSS_PLATFORM_CONTEXT Context,
  207. ULONG ToSver, ULONG ToSize, PVOID To)
  208. {
  209. if (ToSize < sizeof(ALPHA_NT5_CONTEXT))
  210. {
  211. return E_INVALIDARG;
  212. }
  213. memcpy(To, Context, sizeof(ALPHA_NT5_CONTEXT));
  214. return S_OK;
  215. }
  216. void
  217. AlphaMachineInfo::InitializeContextFlags(PCROSS_PLATFORM_CONTEXT Context,
  218. ULONG Version)
  219. {
  220. Context->AlphaNt5Context.ContextFlags = ALPHA_CONTEXT_FULL;
  221. }
  222. int
  223. AlphaMachineInfo::GetType(ULONG index)
  224. {
  225. if (
  226. #if ALPHA_FLT_BASE > 0
  227. index >= ALPHA_FLT_BASE &&
  228. #endif
  229. index <= ALPHA_FLT_LAST)
  230. {
  231. return REGVAL_FLOAT8;
  232. }
  233. else if (index >= ALPHA_INT64_BASE && index <= ALPHA_INT64_LAST)
  234. {
  235. return REGVAL_INT64;
  236. }
  237. else if (index >= ALPHA_INT32_BASE && index <= ALPHA_INT32_LAST)
  238. {
  239. return REGVAL_INT32;
  240. }
  241. else
  242. {
  243. return REGVAL_SUB32;
  244. }
  245. }
  246. /*** RegGetVal - get register value
  247. *
  248. * Purpose:
  249. * Returns the value of the register from the processor
  250. * context structure.
  251. *
  252. * Input:
  253. * regnum - register specification
  254. *
  255. * Returns:
  256. * value of the register from the context structure
  257. *
  258. *************************************************************************/
  259. BOOL
  260. AlphaMachineInfo::GetVal (
  261. ULONG regnum,
  262. REGVAL *val
  263. )
  264. {
  265. if (GetContextState(MCTX_FULL) != S_OK)
  266. {
  267. return FALSE;
  268. }
  269. val->type = GetType(regnum);
  270. // All registers except PSR are 64 bits and PSR is followed by
  271. // ContextFlags so it's safe to always just grab 64 bits for
  272. // the value.
  273. val->i64 = *(&m_Context.AlphaNt5Context.FltF0 + regnum);
  274. return TRUE;
  275. }
  276. /*** RegSetVal - set register value
  277. *
  278. * Purpose:
  279. * Set the value of the register in the processor context
  280. * structure.
  281. *
  282. * Input:
  283. * regnum - register specification
  284. * regvalue - new value to set the register
  285. *
  286. * Output:
  287. * None.
  288. *
  289. *************************************************************************/
  290. BOOL
  291. AlphaMachineInfo::SetVal (
  292. ULONG regnum,
  293. REGVAL *val
  294. )
  295. {
  296. if (m_ContextIsReadOnly)
  297. {
  298. return FALSE;
  299. }
  300. // Optimize away some common cases where registers are
  301. // set to their current value.
  302. if (m_ContextState >= MCTX_PC && regnum == ALPHA_FIR &&
  303. val->i64 == m_Context.AlphaNt5Context.Fir)
  304. {
  305. return TRUE;
  306. }
  307. if (GetContextState(MCTX_DIRTY) != S_OK)
  308. {
  309. return FALSE;
  310. }
  311. if (regnum == ALPHA_PSR)
  312. {
  313. // Be careful to only write 32 bits for PSR to preserve
  314. // ContextFlags.
  315. *(ULONG *)(&m_Context.AlphaNt5Context.FltF0 + regnum) = val->i32;
  316. }
  317. else
  318. {
  319. *(&m_Context.AlphaNt5Context.FltF0 + regnum) = val->i64;
  320. }
  321. NotifyChangeDebuggeeState(DEBUG_CDS_REGISTERS,
  322. RegCountFromIndex(regnum));
  323. return TRUE;
  324. }
  325. /*** RegOutputAll - output all registers and present instruction
  326. *
  327. * Purpose:
  328. * Function of "r" command.
  329. *
  330. * To output the current register state of the processor.
  331. * All integer registers are output as well as processor status
  332. * registers. Important flag fields are also output separately.
  333. * OutDisCurrent is called to output the current instruction(s).
  334. *
  335. * Input:
  336. * None.
  337. *
  338. * Output:
  339. * None.
  340. *
  341. *************************************************************************/
  342. VOID
  343. AlphaMachineInfo::OutputAll(ULONG Mask, ULONG OutMask)
  344. {
  345. int regindex;
  346. int regnumber;
  347. ULONGLONG regvalue;
  348. if (GetContextState(MCTX_FULL) != S_OK)
  349. {
  350. ErrOut("Unable to retrieve register information\n");
  351. return;
  352. }
  353. if (Mask & (REGALL_INT32 | REGALL_INT64))
  354. {
  355. for (regindex = 0; regindex < 34; regindex++)
  356. {
  357. regnumber = GetIntRegNumber(regindex);
  358. regvalue = GetReg64(regnumber);
  359. if ( (Mask & REGALL_INT64) || regindex == 32 || regindex == 33)
  360. {
  361. MaskOut(OutMask, "%4s=%08lx %08lx",
  362. RegNameFromIndex(regnumber),
  363. (ULONG)(regvalue >> 32),
  364. (ULONG)(regvalue & 0xffffffff));
  365. if (regindex % 3 == 2)
  366. {
  367. MaskOut(OutMask, "\n");
  368. }
  369. else
  370. {
  371. MaskOut(OutMask, " ");
  372. }
  373. }
  374. else
  375. {
  376. MaskOut(OutMask, "%4s=%08lx%c",
  377. RegNameFromIndex(regnumber),
  378. (ULONG)(regvalue & 0xffffffff),
  379. NeedUpper(regvalue) ? '*' : ' ' );
  380. if (regindex % 5 == 4)
  381. {
  382. MaskOut(OutMask, "\n");
  383. }
  384. else
  385. {
  386. MaskOut(OutMask, " ");
  387. }
  388. }
  389. }
  390. //
  391. // print out the fpcr as 64 bits regardless,
  392. // and the FIR and Fpcr's - assuming we know they follow
  393. // the floating and integer registers.
  394. //
  395. if (m_Ptr64)
  396. {
  397. regnumber = ALPHA_FIR;
  398. MaskOut(OutMask, "%4s=%s\n",
  399. RegNameFromIndex(regnumber),
  400. FormatAddr64(GetReg64(regnumber)));
  401. }
  402. else
  403. {
  404. regnumber = ALPHA_FIR;
  405. MaskOut(OutMask, "%4s=%08lx\n",
  406. RegNameFromIndex(regnumber),
  407. GetReg32(regnumber));
  408. }
  409. regnumber = ALPHA_PSR;
  410. MaskOut(OutMask, "%4s=%08lx\n",
  411. RegNameFromIndex(regnumber), GetReg32(regnumber));
  412. MaskOut(OutMask, "mode=%1lx ie=%1lx irql=%1lx \n",
  413. GetSubReg32(ALPHA_MODE),
  414. GetSubReg32(ALPHA_IE),
  415. GetSubReg32(ALPHA_IRQL));
  416. }
  417. if (Mask & REGALL_FLOAT)
  418. {
  419. ULONG i;
  420. REGVAL val;
  421. //
  422. // Print them all out
  423. //
  424. for (i = 0 ; i < 16; i ++)
  425. {
  426. GetVal(i + ALPHA_FLT_BASE, &val);
  427. MaskOut(OutMask, "%4s = %16e\t",
  428. RegNameFromIndex(i), val.f8);
  429. GetVal(i + ALPHA_FLT_BASE + 16, &val);
  430. MaskOut(OutMask, "%4s = %16e\n",
  431. RegNameFromIndex(i+16), val.f8);
  432. }
  433. }
  434. }
  435. TRACEMODE
  436. AlphaMachineInfo::GetTraceMode (void)
  437. {
  438. return TRACE_NONE;
  439. }
  440. void
  441. AlphaMachineInfo::SetTraceMode (TRACEMODE Mode)
  442. {
  443. ;
  444. }
  445. BOOL
  446. AlphaMachineInfo::IsStepStatusSupported(ULONG Status)
  447. {
  448. switch (Status)
  449. {
  450. case DEBUG_STATUS_STEP_INTO:
  451. case DEBUG_STATUS_STEP_OVER:
  452. return TRUE;
  453. default:
  454. return FALSE;
  455. }
  456. }
  457. ULONG
  458. AlphaMachineInfo::ExecutingMachine(void)
  459. {
  460. return g_TargetMachineType;
  461. }
  462. void
  463. AlphaMachineInfo::ValidateCxr(PCROSS_PLATFORM_CONTEXT Context)
  464. {
  465. return;
  466. }
  467. BOOL
  468. AlphaMachineInfo::DisplayTrapFrame(ULONG64 FrameAddress,
  469. OUT PCROSS_PLATFORM_CONTEXT Context)
  470. {
  471. #define HIGH(x) ((ULONG) ((x>>32) & 0xFFFFFFFF))
  472. #define LOW(x) ((ULONG) (x & 0xFFFFFFFF))
  473. #define HIGHANDLOW(x) HIGH(x), LOW(x)
  474. ALPHA_KTRAP_FRAME TrapContents;
  475. ULONG64 Address=FrameAddress;
  476. ULONG result;
  477. ULONG64 DisasmAddr;
  478. ULONG64 Displacement;
  479. CHAR Buffer[80];
  480. ULONG64 IntSp, IntFp;
  481. if (!FrameAddress ||
  482. g_Target->ReadVirtual(Address, &TrapContents,
  483. sizeof(ALPHA_KTRAP_FRAME), &result) != S_OK)
  484. {
  485. dprintf("USAGE: !trap base_of_trap_frame\n");
  486. return FALSE;
  487. }
  488. dprintf("v0 = %08lx %08lx a0 = %08lx %08lx\n" ,
  489. HIGHANDLOW(TrapContents.IntV0),HIGHANDLOW(TrapContents.IntA0));
  490. dprintf("t0 = %08lx %08lx a1 = %08lx %08lx\n" ,
  491. HIGHANDLOW(TrapContents.IntT0),HIGHANDLOW(TrapContents.IntA1));
  492. dprintf("t1 = %08lx %08lx a2 = %08lx %08lx\n" ,
  493. HIGHANDLOW(TrapContents.IntT1),HIGHANDLOW(TrapContents.IntA2));
  494. dprintf("t2 = %08lx %08lx a3 = %08lx %08lx\n" ,
  495. HIGHANDLOW(TrapContents.IntT2),HIGHANDLOW(TrapContents.IntA3));
  496. dprintf("t3 = %08lx %08lx a4 = %08lx %08lx\n" ,
  497. HIGHANDLOW(TrapContents.IntT3),HIGHANDLOW(TrapContents.IntA4));
  498. dprintf("t4 = %08lx %08lx a5 = %08lx %08lx\n" ,
  499. HIGHANDLOW(TrapContents.IntT4),HIGHANDLOW(TrapContents.IntA5));
  500. dprintf("t5 = %08lx %08lx t8 = %08lx %08lx\n" ,
  501. HIGHANDLOW(TrapContents.IntT5),HIGHANDLOW(TrapContents.IntT8));
  502. dprintf("t6 = %08lx %08lx t9 = %08lx %08lx\n" ,
  503. HIGHANDLOW(TrapContents.IntT6),HIGHANDLOW(TrapContents.IntT9));
  504. dprintf("t7 = %08lx %08lx t10 = %08lx %08lx\n" ,
  505. HIGHANDLOW(TrapContents.IntT7),HIGHANDLOW(TrapContents.IntT10));
  506. dprintf(" t11 = %08lx %08lx\n" ,
  507. HIGHANDLOW(TrapContents.IntT11));
  508. dprintf(" ra = %08lx %08lx\n" ,
  509. HIGHANDLOW(TrapContents.IntRa));
  510. dprintf(" t12 = %08lx %08lx\n" ,
  511. HIGHANDLOW(TrapContents.IntT12));
  512. dprintf(" at = %08lx %08lx\n" ,
  513. HIGHANDLOW(TrapContents.IntAt));
  514. dprintf(" gp = %08lx %08lx\n" ,
  515. HIGHANDLOW(TrapContents.IntGp));
  516. dprintf("fp = %08lx %08lx sp = %08lx %08lx\n",
  517. HIGHANDLOW(IntFp = TrapContents.IntFp),HIGHANDLOW(IntSp = TrapContents.IntSp));
  518. dprintf("fir= %08lx %08lx\n",
  519. HIGHANDLOW(TrapContents.Fir));
  520. DisasmAddr = (TrapContents.Fir);
  521. g_LastRegFrame.InstructionOffset = DisasmAddr;
  522. g_LastRegFrame.StackOffset = IntSp;
  523. g_LastRegFrame.FrameOffset = IntFp;
  524. GetSymbolStdCall(DisasmAddr, Buffer, sizeof(Buffer), &Displacement, NULL);
  525. dprintf("%s+0x%I64lx\n",Buffer,Displacement);
  526. ADDR tempAddr;
  527. Type(tempAddr) = ADDR_FLAT | FLAT_COMPUTED;
  528. Off(tempAddr) = Flat(tempAddr) = DisasmAddr;
  529. if (Disassemble(&tempAddr, Buffer, FALSE))
  530. {
  531. dprintf(Buffer);
  532. }
  533. else
  534. {
  535. dprintf("%08I64lx ???????????????\n", DisasmAddr);
  536. }
  537. if (Context)
  538. {
  539. // Fill up the context struct
  540. if (g_EffMachine == IMAGE_FILE_MACHINE_ALPHA)
  541. {
  542. #define COPY(fld) Context->AlphaContext.fld = (ULONG) TrapContents.fld
  543. COPY(IntSp); COPY(IntFp); COPY(Fir);
  544. COPY(IntRa); COPY(IntAt); COPY(IntGp);
  545. COPY(IntV0); COPY(IntA0); COPY(IntT0); COPY(IntA1); COPY(IntA2);
  546. COPY(IntT1); COPY(IntT2); COPY(IntT3); COPY(IntT4); COPY(IntT5);
  547. COPY(IntT6); COPY(IntT6); COPY(IntT7); COPY(IntT8); COPY(IntT9);
  548. COPY(IntT10); COPY(IntT11); COPY(IntT12);
  549. COPY(IntA3); COPY(IntA4); COPY(IntA5);
  550. #undef COPY
  551. }
  552. else
  553. {
  554. }
  555. }
  556. return TRUE;
  557. #undef HIGHANDLOW
  558. #undef HIGH
  559. #undef LOW
  560. }
  561. HRESULT
  562. AlphaMachineInfo::ReadKernelProcessorId
  563. (ULONG Processor, PDEBUG_PROCESSOR_IDENTIFICATION_ALL Id)
  564. {
  565. HRESULT Status;
  566. ULONG64 Pcr;
  567. ULONG Data[2];
  568. if ((Status = g_Target->
  569. GetProcessorSystemDataOffset(Processor, DEBUG_DATA_KPCR_OFFSET,
  570. &Pcr)) != S_OK)
  571. {
  572. return Status;
  573. }
  574. Pcr += m_Ptr64 ?
  575. FIELD_OFFSET(AXP64_PARTIAL_KPCR, ProcessorType) :
  576. FIELD_OFFSET(ALPHA_PARTIAL_KPCR, ProcessorType);
  577. if ((Status = g_Target->
  578. ReadAllVirtual(Pcr, Data, sizeof(Data))) != S_OK)
  579. {
  580. return Status;
  581. }
  582. Id->Alpha.Type = Data[0];
  583. Id->Alpha.Revision = Data[1];
  584. return S_OK;
  585. }
  586. #define MAXENTRYTYPE 2
  587. const char *g_AlphaEntryTypeName[] =
  588. {
  589. "ALPHA_RF_NOT_CONTIGUOUS", // 0
  590. "ALPHA_RF_ALT_ENT_PROLOG", // 1
  591. "ALPHA_RF_NULL_CONTEXT", // 2
  592. "***INVALID***"
  593. };
  594. #define ALPHA_RF_ALT_PROLOG64(RF) (((ULONG64)(RF)->ExceptionHandler) & (~3))
  595. void
  596. AlphaMachineInfo::OutputFunctionEntry64
  597. (PIMAGE_ALPHA64_RUNTIME_FUNCTION_ENTRY Entry)
  598. {
  599. BOOL Secondary = FALSE;
  600. BOOL FixedReturn = FALSE;
  601. ULONG EntryType = 0;
  602. ULONG NullCount = 0;
  603. if ((ALPHA_RF_PROLOG_END_ADDRESS(Entry) < ALPHA_RF_BEGIN_ADDRESS(Entry)) ||
  604. (ALPHA_RF_PROLOG_END_ADDRESS(Entry) > ALPHA_RF_END_ADDRESS(Entry)))
  605. {
  606. Secondary = TRUE;
  607. EntryType = ALPHA_RF_ENTRY_TYPE(Entry);
  608. if (EntryType > MAXENTRYTYPE)
  609. {
  610. EntryType = MAXENTRYTYPE;
  611. }
  612. }
  613. else if (ALPHA_RF_IS_FIXED_RETURN(Entry))
  614. {
  615. FixedReturn = TRUE;
  616. }
  617. NullCount = ALPHA_RF_NULL_CONTEXT_COUNT(Entry);
  618. dprintf("BeginAddress = %s\n", FormatAddr64(Entry->BeginAddress));
  619. dprintf("EndAddress = %s", FormatAddr64(Entry->EndAddress));
  620. if (NullCount)
  621. {
  622. dprintf(" %d null-context instructions", NullCount);
  623. }
  624. dprintf("\n");
  625. dprintf("ExceptionHandler = %s",
  626. FormatAddr64(Entry->ExceptionHandler));
  627. if (Entry->ExceptionHandler != 0)
  628. {
  629. if (Secondary)
  630. {
  631. ULONG64 AlternateProlog = ALPHA_RF_ALT_PROLOG64(Entry);
  632. switch(EntryType)
  633. {
  634. case ALPHA_RF_NOT_CONTIGUOUS:
  635. case ALPHA_RF_ALT_ENT_PROLOG:
  636. if ((AlternateProlog >=
  637. ALPHA_RF_BEGIN_ADDRESS(Entry)) &&
  638. (AlternateProlog <= Entry->EndAddress))
  639. {
  640. dprintf(" alternate PrologEndAddress");
  641. }
  642. break;
  643. case ALPHA_RF_NULL_CONTEXT:
  644. dprintf(" stack adjustment");
  645. break;
  646. }
  647. }
  648. else if (FixedReturn)
  649. {
  650. dprintf(" fixed return address");
  651. }
  652. }
  653. dprintf("\n");
  654. dprintf("HandlerData = %s", FormatAddr64(Entry->HandlerData));
  655. if (Secondary)
  656. {
  657. dprintf(" type %d: %s", EntryType, g_AlphaEntryTypeName[EntryType]);
  658. }
  659. dprintf("\n");
  660. dprintf("PrologEndAddress = %s\n",
  661. FormatAddr64(Entry->PrologEndAddress));
  662. }
  663. HRESULT
  664. Axp32MachineInfo::InitializeConstants(void)
  665. {
  666. m_FullName = "Alpha 32-bit";
  667. m_AbbrevName = "alpha";
  668. m_PageSize = ALPHA_PAGE_SIZE;
  669. m_PageShift = ALPHA_PAGE_SHIFT;
  670. m_NumExecTypes = 1;
  671. m_ExecTypes = g_Axp32ExecTypes;
  672. m_Ptr64 = FALSE;
  673. return AlphaMachineInfo::InitializeConstants();
  674. }
  675. HRESULT
  676. Axp32MachineInfo::InitializeForTarget(void)
  677. {
  678. m_OffsetPrcbProcessorState =
  679. FIELD_OFFSET(ALPHA_PARTIAL_KPRCB, ProcessorState);
  680. m_OffsetPrcbNumber =
  681. FIELD_OFFSET(ALPHA_PARTIAL_KPRCB, Number);
  682. m_TriagePrcbOffset = EXTEND64(ALPHA_TRIAGE_PRCB_ADDRESS);
  683. m_SizePrcb = ALPHA_KPRCB_SIZE;
  684. m_OffsetKThreadApcProcess =
  685. FIELD_OFFSET(CROSS_PLATFORM_THREAD, AlphaThread.ApcState.Process);
  686. m_OffsetKThreadTeb =
  687. FIELD_OFFSET(CROSS_PLATFORM_THREAD, AlphaThread.Teb);
  688. m_OffsetKThreadInitialStack =
  689. FIELD_OFFSET(CROSS_PLATFORM_THREAD, AlphaThread.InitialStack);
  690. m_OffsetEprocessPeb = g_SystemVersion > NT_SVER_W2K ?
  691. ALPHA_NT51_PEB_IN_EPROCESS : ALPHA_NT5_PEB_IN_EPROCESS;
  692. m_OffsetEprocessDirectoryTableBase =
  693. ALPHA_DIRECTORY_TABLE_BASE_IN_EPROCESS;
  694. m_SizeEThread = ALPHA_ETHREAD_SIZE;
  695. m_SizeEProcess = g_SystemVersion > NT_SVER_W2K ?
  696. ALPHA_NT51_EPROCESS_SIZE : ALPHA_NT5_EPROCESS_SIZE;
  697. m_SizePartialKThread = sizeof(ALPHA_THREAD);
  698. m_SharedUserDataOffset = IS_KERNEL_TARGET() ?
  699. EXTEND64(ALPHA_KI_USER_SHARED_DATA) : MM_SHARED_USER_DATA_VA;
  700. return MachineInfo::InitializeForTarget();
  701. }
  702. HRESULT
  703. Axp32MachineInfo::GetContextFromThreadStack(ULONG64 ThreadBase,
  704. PCROSS_PLATFORM_THREAD Thread,
  705. PCROSS_PLATFORM_CONTEXT Context,
  706. PDEBUG_STACK_FRAME Frame,
  707. PULONG RunningOnProc)
  708. {
  709. if (Thread->AlphaThread.State == 2)
  710. {
  711. return E_NOTIMPL;
  712. }
  713. HRESULT Status;
  714. ALPHA_KEXCEPTION_FRAME ExFrame;
  715. if ((Status = g_Target->ReadAllVirtual(Thread->AlphaThread.KernelStack,
  716. &ExFrame, sizeof(ExFrame))) != S_OK)
  717. {
  718. return Status;
  719. }
  720. //
  721. // Successfully read an exception frame from the stack.
  722. //
  723. Context->AlphaNt5Context.IntSp =
  724. Thread->AlphaThread.KernelStack;
  725. Context->AlphaNt5Context.Fir = ExFrame.SwapReturn;
  726. Context->AlphaNt5Context.IntRa = ExFrame.SwapReturn;
  727. Context->AlphaNt5Context.IntS0 = ExFrame.IntS0;
  728. Context->AlphaNt5Context.IntS1 = ExFrame.IntS1;
  729. Context->AlphaNt5Context.IntS2 = ExFrame.IntS2;
  730. Context->AlphaNt5Context.IntS3 = ExFrame.IntS3;
  731. Context->AlphaNt5Context.IntS4 = ExFrame.IntS4;
  732. Context->AlphaNt5Context.IntS5 = ExFrame.IntS5;
  733. Context->AlphaNt5Context.Psr = ExFrame.Psr;
  734. Frame->FrameOffset = Context->AlphaNt5Context.IntSp;
  735. Frame->StackOffset = Context->AlphaNt5Context.IntSp;
  736. Frame->InstructionOffset = ExFrame.SwapReturn;
  737. return S_OK;
  738. }
  739. VOID
  740. Axp32MachineInfo::GetPC (
  741. PADDR Address
  742. )
  743. {
  744. // sign extend the address!
  745. ADDRFLAT(Address, EXTEND64(GetReg32(ALPHA_FIR)));
  746. }
  747. VOID
  748. Axp32MachineInfo::SetPC (
  749. PADDR paddr
  750. )
  751. {
  752. // sign extend the address!
  753. SetReg64(ALPHA_FIR, EXTEND64(Flat(*paddr)));
  754. }
  755. VOID
  756. Axp32MachineInfo::GetFP (
  757. PADDR Address
  758. )
  759. {
  760. ADDRFLAT(Address, GetReg32(FP_REG));
  761. }
  762. void
  763. Axp32MachineInfo::GetSP(PADDR Address)
  764. {
  765. ADDRFLAT(Address, GetReg32(SP_REG));
  766. }
  767. ULONG64
  768. Axp32MachineInfo::GetArgReg(void)
  769. {
  770. return GetReg32(ALPHA_INT64_BASE + A0_REG);
  771. }
  772. HRESULT
  773. Axp32MachineInfo::SetPageDirectory(ULONG Idx, ULONG64 PageDir,
  774. PULONG NextIdx)
  775. {
  776. *NextIdx = PAGE_DIR_COUNT;
  777. if (PageDir == 0)
  778. {
  779. HRESULT Status;
  780. if ((Status = g_Target->ReadImplicitProcessInfoPointer
  781. (m_OffsetEprocessDirectoryTableBase, &PageDir)) != S_OK)
  782. {
  783. return Status;
  784. }
  785. }
  786. // DirectoryTableBase values on Alpha are the raw PTE entries
  787. // so turn it into a clean physical address.
  788. PageDir = ((ULONG)PageDir >> ALPHA_VALID_PFN_SHIFT) <<
  789. ALPHA_PAGE_SHIFT;
  790. // There is only one page directory so update all the slots.
  791. m_PageDirectories[PAGE_DIR_USER] = PageDir;
  792. m_PageDirectories[PAGE_DIR_SESSION] = PageDir;
  793. m_PageDirectories[PAGE_DIR_KERNEL] = PageDir;
  794. return S_OK;
  795. }
  796. #define ALPHA_PAGE_FILE_INDEX(Entry) \
  797. (((ULONG)(Entry) >> 8) & MAX_PAGING_FILE_MASK)
  798. #define ALPHA_PAGE_FILE_OFFSET(Entry) \
  799. ((ULONG64)((Entry) >> 12) << ALPHA_PAGE_SHIFT)
  800. HRESULT
  801. Axp32MachineInfo::GetVirtualTranslationPhysicalOffsets(ULONG64 Virt,
  802. PULONG64 Offsets,
  803. ULONG OffsetsSize,
  804. PULONG Levels,
  805. PULONG PfIndex,
  806. PULONG64 LastVal)
  807. {
  808. HRESULT Status;
  809. *Levels = 0;
  810. if (m_Translating)
  811. {
  812. return E_UNEXPECTED;
  813. }
  814. m_Translating = TRUE;
  815. //
  816. // Reset the page directory in case it was 0
  817. //
  818. if (m_PageDirectories[PAGE_DIR_SINGLE] == 0)
  819. {
  820. if ((Status = SetDefaultPageDirectories(1 << PAGE_DIR_SINGLE)) != S_OK)
  821. {
  822. m_Translating = FALSE;
  823. return Status;
  824. }
  825. }
  826. KdOut("Axp32VtoP: Virt %s, pagedir %s\n",
  827. FormatAddr64(Virt),
  828. FormatAddr64(m_PageDirectories[PAGE_DIR_SINGLE]));
  829. (*Levels)++;
  830. if (Offsets != NULL && OffsetsSize > 0)
  831. {
  832. *Offsets++ = m_PageDirectories[PAGE_DIR_SINGLE];
  833. OffsetsSize--;
  834. }
  835. //
  836. // Certain ranges of the system are mapped directly.
  837. //
  838. if ((Virt >= EXTEND64(ALPHA_PHYSICAL_START)) &&
  839. (Virt <= EXTEND64(ALPHA_PHYSICAL_END)))
  840. {
  841. *LastVal = Virt - EXTEND64(ALPHA_PHYSICAL_START);
  842. KdOut("Axp32VtoP: Direct phys %s\n", FormatAddr64(*LastVal));
  843. (*Levels)++;
  844. if (Offsets != NULL && OffsetsSize > 0)
  845. {
  846. *Offsets++ = *LastVal;
  847. OffsetsSize--;
  848. }
  849. m_Translating = FALSE;
  850. return S_OK;
  851. }
  852. ULONG64 Addr;
  853. ULONG Entry;
  854. Addr = (((ULONG)Virt >> ALPHA_PDE_SHIFT) * sizeof(Entry)) +
  855. m_PageDirectories[PAGE_DIR_SINGLE];
  856. KdOut("Axp32VtoP: PDE %s\n", FormatAddr64(Addr));
  857. (*Levels)++;
  858. if (Offsets != NULL && OffsetsSize > 0)
  859. {
  860. *Offsets++ = Addr;
  861. OffsetsSize--;
  862. }
  863. if ((Status = g_Target->
  864. ReadAllPhysical(Addr, &Entry, sizeof(Entry))) != S_OK)
  865. {
  866. KdOut("Axp32VtoP: PDE read error 0x%X\n", Status);
  867. m_Translating = FALSE;
  868. return Status;
  869. }
  870. if (Entry == 0)
  871. {
  872. KdOut("Axp32VtoP: zero PDE\n");
  873. m_Translating = FALSE;
  874. return HR_PAGE_NOT_AVAILABLE;
  875. }
  876. else if (!(Entry & 1))
  877. {
  878. Addr = ((((ULONG)Virt >> ALPHA_PTE_SHIFT) & ALPHA_PTE_MASK) *
  879. sizeof(Entry)) + ALPHA_PAGE_FILE_OFFSET(Entry);
  880. KdOut("Axp32VtoP: pagefile PTE %d:%s\n",
  881. ALPHA_PAGE_FILE_INDEX(Entry), FormatAddr64(Addr));
  882. if ((Status = g_Target->
  883. ReadPageFile(ALPHA_PAGE_FILE_INDEX(Entry), Addr,
  884. &Entry, sizeof(Entry))) != S_OK)
  885. {
  886. KdOut("Axp32VtoP: PDE not present, 0x%X\n", Status);
  887. m_Translating = FALSE;
  888. return Status;
  889. }
  890. }
  891. else
  892. {
  893. Addr = ((((ULONG)Virt >> ALPHA_PTE_SHIFT) & ALPHA_PTE_MASK) *
  894. sizeof(Entry)) +
  895. ((Entry >> ALPHA_VALID_PFN_SHIFT) << ALPHA_PAGE_SHIFT);
  896. KdOut("Axp32VtoP: PTE %s\n", FormatAddr64(Addr));
  897. (*Levels)++;
  898. if (Offsets != NULL && OffsetsSize > 0)
  899. {
  900. *Offsets++ = Addr;
  901. OffsetsSize--;
  902. }
  903. if ((Status = g_Target->
  904. ReadAllPhysical(Addr, &Entry, sizeof(Entry))) != S_OK)
  905. {
  906. KdOut("Axp32VtoP: PTE read error 0x%X\n", Status);
  907. m_Translating = FALSE;
  908. return Status;
  909. }
  910. }
  911. if (!(Entry & 0x1) &&
  912. ((Entry & ALPHA_MM_PTE_PROTOTYPE_MASK) ||
  913. !(Entry & ALPHA_MM_PTE_TRANSITION_MASK)))
  914. {
  915. if (Entry == 0)
  916. {
  917. KdOut("Axp32VtoP: zero PTE\n");
  918. Status = HR_PAGE_NOT_AVAILABLE;
  919. }
  920. else if (Entry & ALPHA_MM_PTE_PROTOTYPE_MASK)
  921. {
  922. KdOut("Axp32VtoP: prototype PTE\n");
  923. Status = HR_PAGE_NOT_AVAILABLE;
  924. }
  925. else
  926. {
  927. *PfIndex = ALPHA_PAGE_FILE_INDEX(Entry);
  928. *LastVal = (Virt & (ALPHA_PAGE_SIZE - 1)) +
  929. ALPHA_PAGE_FILE_OFFSET(Entry);
  930. KdOut("Axp32VtoP: PTE not present, pagefile %d:%s\n",
  931. *PfIndex, FormatAddr64(*LastVal));
  932. Status = HR_PAGE_IN_PAGE_FILE;
  933. }
  934. m_Translating = FALSE;
  935. return Status;
  936. }
  937. //
  938. // This is a page which is either present or in transition.
  939. // Return the physical address for the request virtual address.
  940. //
  941. *LastVal = ((Entry >> ALPHA_VALID_PFN_SHIFT) << ALPHA_PAGE_SHIFT) |
  942. (Virt & (ALPHA_PAGE_SIZE - 1));
  943. KdOut("Axp32VtoP: Mapped phys %s\n", FormatAddr64(*LastVal));
  944. (*Levels)++;
  945. if (Offsets != NULL && OffsetsSize > 0)
  946. {
  947. *Offsets++ = *LastVal;
  948. OffsetsSize--;
  949. }
  950. m_Translating = FALSE;
  951. return S_OK;
  952. }
  953. HRESULT
  954. Axp32MachineInfo::GetBaseTranslationVirtualOffset(PULONG64 Offset)
  955. {
  956. *Offset = EXTEND64(ALPHA_BASE_VIRT);
  957. return S_OK;
  958. }
  959. void
  960. Axp32MachineInfo::OutputFunctionEntry(PVOID RawEntry)
  961. {
  962. // Assume Alpha function entries are always kept as
  963. // 64-bit entries. That's what imagehlp does right now.
  964. OutputFunctionEntry64((PIMAGE_ALPHA64_RUNTIME_FUNCTION_ENTRY)RawEntry);
  965. }
  966. HRESULT
  967. Axp32MachineInfo::ReadDynamicFunctionTable(ULONG64 Table,
  968. PULONG64 NextTable,
  969. PULONG64 MinAddress,
  970. PULONG64 MaxAddress,
  971. PULONG64 BaseAddress,
  972. PULONG64 TableData,
  973. PULONG TableSize,
  974. PWSTR OutOfProcessDll,
  975. PCROSS_PLATFORM_DYNAMIC_FUNCTION_TABLE RawTable)
  976. {
  977. HRESULT Status;
  978. if ((Status = g_Target->
  979. ReadAllVirtual(Table, &RawTable->AlphaTable,
  980. sizeof(RawTable->AlphaTable))) != S_OK)
  981. {
  982. return Status;
  983. }
  984. *NextTable = EXTEND64(RawTable->AlphaTable.Links.Flink);
  985. *MinAddress = EXTEND64(RawTable->AlphaTable.MinimumAddress);
  986. *MaxAddress = EXTEND64(RawTable->AlphaTable.MaximumAddress);
  987. *BaseAddress = EXTEND64(RawTable->AlphaTable.MinimumAddress);
  988. *TableData = EXTEND64(RawTable->AlphaTable.FunctionTable);
  989. *TableSize = RawTable->AlphaTable.EntryCount *
  990. sizeof(IMAGE_ALPHA_RUNTIME_FUNCTION_ENTRY);
  991. OutOfProcessDll[0] = 0;
  992. return S_OK;
  993. }
  994. PVOID
  995. Axp32MachineInfo::FindDynamicFunctionEntry(PCROSS_PLATFORM_DYNAMIC_FUNCTION_TABLE Table,
  996. ULONG64 Address,
  997. PVOID TableData,
  998. ULONG TableSize)
  999. {
  1000. ULONG i;
  1001. PIMAGE_ALPHA_RUNTIME_FUNCTION_ENTRY Func;
  1002. // Always return AXP64 function entries.
  1003. static IMAGE_ALPHA64_RUNTIME_FUNCTION_ENTRY s_RetFunc;
  1004. Func = (PIMAGE_ALPHA_RUNTIME_FUNCTION_ENTRY)TableData;
  1005. for (i = 0; i < TableSize / sizeof(IMAGE_ALPHA_RUNTIME_FUNCTION_ENTRY); i++)
  1006. {
  1007. if (Address >= ALPHA_RF_BEGIN_ADDRESS(Func) &&
  1008. Address < ALPHA_RF_END_ADDRESS(Func))
  1009. {
  1010. // The table data is temporary so copy the data into
  1011. // a static buffer for longer-term storage.
  1012. s_RetFunc.BeginAddress = EXTEND64(Func->BeginAddress);
  1013. s_RetFunc.EndAddress = EXTEND64(Func->EndAddress);
  1014. s_RetFunc.ExceptionHandler = EXTEND64(Func->ExceptionHandler);
  1015. s_RetFunc.HandlerData = EXTEND64(Func->HandlerData);
  1016. s_RetFunc.PrologEndAddress = EXTEND64(Func->PrologEndAddress);
  1017. return (PVOID)&s_RetFunc;
  1018. }
  1019. Func++;
  1020. }
  1021. return NULL;
  1022. }
  1023. HRESULT
  1024. Axp64MachineInfo::InitializeConstants(void)
  1025. {
  1026. m_FullName = "Alpha 64-bit";
  1027. m_AbbrevName = "axp64";
  1028. m_PageSize = AXP64_PAGE_SIZE;
  1029. m_PageShift = AXP64_PAGE_SHIFT;
  1030. m_NumExecTypes = 1;
  1031. m_ExecTypes = g_Axp64ExecTypes;
  1032. m_Ptr64 = TRUE;
  1033. return AlphaMachineInfo::InitializeConstants();
  1034. }
  1035. HRESULT
  1036. Axp64MachineInfo::InitializeForTarget(void)
  1037. {
  1038. m_OffsetPrcbProcessorState =
  1039. FIELD_OFFSET(AXP64_PARTIAL_KPRCB, ProcessorState);
  1040. m_OffsetPrcbNumber =
  1041. FIELD_OFFSET(AXP64_PARTIAL_KPRCB, Number);
  1042. m_TriagePrcbOffset = AXP64_TRIAGE_PRCB_ADDRESS;
  1043. m_SizePrcb = AXP64_KPRCB_SIZE;
  1044. m_OffsetKThreadApcProcess =
  1045. FIELD_OFFSET(CROSS_PLATFORM_THREAD, Axp64Thread.ApcState.Process);
  1046. m_OffsetKThreadTeb =
  1047. FIELD_OFFSET(CROSS_PLATFORM_THREAD, Axp64Thread.Teb);
  1048. m_OffsetKThreadInitialStack =
  1049. FIELD_OFFSET(CROSS_PLATFORM_THREAD, Axp64Thread.InitialStack);
  1050. m_OffsetEprocessPeb = AXP64_PEB_IN_EPROCESS;
  1051. m_OffsetEprocessDirectoryTableBase =
  1052. AXP64_DIRECTORY_TABLE_BASE_IN_EPROCESS;
  1053. m_SizeEThread = AXP64_ETHREAD_SIZE;
  1054. m_SizeEProcess = AXP64_EPROCESS_SIZE;
  1055. m_SizePartialKThread = sizeof(AXP64_THREAD);
  1056. m_SharedUserDataOffset = IS_KERNEL_TARGET() ?
  1057. AXP64_KI_USER_SHARED_DATA : MM_SHARED_USER_DATA_VA;
  1058. return MachineInfo::InitializeForTarget();
  1059. }
  1060. HRESULT
  1061. Axp64MachineInfo::GetContextFromThreadStack(ULONG64 ThreadBase,
  1062. PCROSS_PLATFORM_THREAD Thread,
  1063. PCROSS_PLATFORM_CONTEXT Context,
  1064. PDEBUG_STACK_FRAME Frame,
  1065. PULONG RunningOnProc)
  1066. {
  1067. if (Thread->Axp64Thread.State == 2)
  1068. {
  1069. return E_NOTIMPL;
  1070. }
  1071. HRESULT Status;
  1072. ALPHA_KEXCEPTION_FRAME ExFrame;
  1073. if ((Status = g_Target->ReadAllVirtual(Thread->Axp64Thread.KernelStack,
  1074. &ExFrame, sizeof(ExFrame))) != S_OK)
  1075. {
  1076. return Status;
  1077. }
  1078. //
  1079. // Successfully read an exception frame from the stack.
  1080. //
  1081. Context->AlphaNt5Context.IntSp =
  1082. Thread->Axp64Thread.KernelStack;
  1083. Context->AlphaNt5Context.Fir = ExFrame.SwapReturn;
  1084. Context->AlphaNt5Context.IntRa = ExFrame.SwapReturn;
  1085. Context->AlphaNt5Context.IntS0 = ExFrame.IntS0;
  1086. Context->AlphaNt5Context.IntS1 = ExFrame.IntS1;
  1087. Context->AlphaNt5Context.IntS2 = ExFrame.IntS2;
  1088. Context->AlphaNt5Context.IntS3 = ExFrame.IntS3;
  1089. Context->AlphaNt5Context.IntS4 = ExFrame.IntS4;
  1090. Context->AlphaNt5Context.IntS5 = ExFrame.IntS5;
  1091. Context->AlphaNt5Context.Psr = ExFrame.Psr;
  1092. Frame->FrameOffset = Context->AlphaNt5Context.IntSp;
  1093. Frame->StackOffset = Context->AlphaNt5Context.IntSp;
  1094. Frame->InstructionOffset = ExFrame.SwapReturn;
  1095. return S_OK;
  1096. }
  1097. VOID
  1098. Axp64MachineInfo::GetPC (
  1099. PADDR Address
  1100. )
  1101. {
  1102. ADDRFLAT(Address, GetReg64(ALPHA_FIR));
  1103. }
  1104. VOID
  1105. Axp64MachineInfo::SetPC (
  1106. PADDR paddr
  1107. )
  1108. {
  1109. SetReg64(ALPHA_FIR, Flat(*paddr));
  1110. }
  1111. VOID
  1112. Axp64MachineInfo::GetFP (
  1113. PADDR Address
  1114. )
  1115. {
  1116. ADDRFLAT(Address, GetReg64(FP_REG));
  1117. }
  1118. void
  1119. Axp64MachineInfo::GetSP(PADDR Address)
  1120. {
  1121. ADDRFLAT(Address, GetReg64(SP_REG));
  1122. }
  1123. ULONG64
  1124. Axp64MachineInfo::GetArgReg(void)
  1125. {
  1126. return GetReg64(ALPHA_INT64_BASE + A0_REG);
  1127. }
  1128. HRESULT
  1129. Axp64MachineInfo::SetPageDirectory(ULONG Idx, ULONG64 PageDir,
  1130. PULONG NextIdx)
  1131. {
  1132. if (PageDir == 0)
  1133. {
  1134. HRESULT Status;
  1135. if ((Status = g_Target->ReadImplicitProcessInfoPointer
  1136. (m_OffsetEprocessDirectoryTableBase, &PageDir)) != S_OK)
  1137. {
  1138. return Status;
  1139. }
  1140. }
  1141. // DirectoryTableBase values on Alpha are the raw PTE entries
  1142. // so turn it into a clean physical address.
  1143. PageDir = (PageDir >> AXP64_VALID_PFN_SHIFT) <<
  1144. AXP64_PAGE_SHIFT;
  1145. // There is only one page directory so update all the slots.
  1146. m_PageDirectories[PAGE_DIR_USER] = PageDir;
  1147. m_PageDirectories[PAGE_DIR_SESSION] = PageDir;
  1148. m_PageDirectories[PAGE_DIR_KERNEL] = PageDir;
  1149. return S_OK;
  1150. }
  1151. #define AXP64_PAGE_FILE_INDEX(Entry) \
  1152. (((ULONG)(Entry) >> 28) & MAX_PAGING_FILE_MASK)
  1153. #define AXP64_PAGE_FILE_OFFSET(Entry) \
  1154. (((Entry) >> 32) << AXP64_PAGE_SHIFT)
  1155. HRESULT
  1156. Axp64MachineInfo::GetVirtualTranslationPhysicalOffsets(ULONG64 Virt,
  1157. PULONG64 Offsets,
  1158. ULONG OffsetsSize,
  1159. PULONG Levels,
  1160. PULONG PfIndex,
  1161. PULONG64 LastVal)
  1162. {
  1163. HRESULT Status;
  1164. *Levels = 0;
  1165. if (m_Translating)
  1166. {
  1167. return E_UNEXPECTED;
  1168. }
  1169. m_Translating = TRUE;
  1170. //
  1171. // Reset the page directory in case it was 0
  1172. //
  1173. if (m_PageDirectories[PAGE_DIR_SINGLE] == 0)
  1174. {
  1175. if ((Status = SetDefaultPageDirectories(1 << PAGE_DIR_SINGLE)) != S_OK)
  1176. {
  1177. m_Translating = FALSE;
  1178. return Status;
  1179. }
  1180. }
  1181. KdOut("Axp64VtoP: Virt %s, pagedir %s\n",
  1182. FormatAddr64(Virt),
  1183. FormatAddr64(m_PageDirectories[PAGE_DIR_SINGLE]));
  1184. (*Levels)++;
  1185. if (Offsets != NULL && OffsetsSize > 0)
  1186. {
  1187. *Offsets++ = m_PageDirectories[PAGE_DIR_SINGLE];
  1188. OffsetsSize--;
  1189. }
  1190. //
  1191. // Certain ranges of the system are mapped directly.
  1192. //
  1193. if ((Virt >= AXP64_PHYSICAL1_START) && (Virt <= AXP64_PHYSICAL1_END))
  1194. {
  1195. *LastVal = Virt - AXP64_PHYSICAL1_START;
  1196. KdOut("Axp64VtoP: Direct phys 1 %s\n", FormatAddr64(*LastVal));
  1197. (*Levels)++;
  1198. if (Offsets != NULL && OffsetsSize > 0)
  1199. {
  1200. *Offsets++ = *LastVal;
  1201. OffsetsSize--;
  1202. }
  1203. m_Translating = FALSE;
  1204. return S_OK;
  1205. }
  1206. if ((Virt >= AXP64_PHYSICAL2_START) && (Virt <= AXP64_PHYSICAL2_END))
  1207. {
  1208. *LastVal = Virt - AXP64_PHYSICAL2_START;
  1209. KdOut("Axp64VtoP: Direct phys 2 %s\n", FormatAddr64(*LastVal));
  1210. (*Levels)++;
  1211. if (Offsets != NULL && OffsetsSize > 0)
  1212. {
  1213. *Offsets++ = *LastVal;
  1214. OffsetsSize--;
  1215. }
  1216. m_Translating = FALSE;
  1217. return S_OK;
  1218. }
  1219. ULONG64 Addr;
  1220. ULONG64 Entry;
  1221. Addr = (((Virt >> AXP64_PDE1_SHIFT) & AXP64_PDE_MASK) * sizeof(Entry)) +
  1222. m_PageDirectories[PAGE_DIR_SINGLE];
  1223. KdOut("Axp64VtoP: PDE1 %s\n", FormatAddr64(Addr));
  1224. (*Levels)++;
  1225. if (Offsets != NULL && OffsetsSize > 0)
  1226. {
  1227. *Offsets++ = Addr;
  1228. OffsetsSize--;
  1229. }
  1230. if ((Status = g_Target->
  1231. ReadAllPhysical(Addr, &Entry, sizeof(Entry))) != S_OK)
  1232. {
  1233. KdOut("Axp64VtoP: PDE1 read error 0x%X\n", Status);
  1234. m_Translating = FALSE;
  1235. return Status;
  1236. }
  1237. if (Entry == 0)
  1238. {
  1239. KdOut("Axp64VtoP: zero PDE1\n");
  1240. m_Translating = FALSE;
  1241. return HR_PAGE_NOT_AVAILABLE;
  1242. }
  1243. else if (!(Entry & 1))
  1244. {
  1245. Addr = (((Virt >> AXP64_PDE2_SHIFT) & AXP64_PDE_MASK) *
  1246. sizeof(Entry)) + AXP64_PAGE_FILE_OFFSET(Entry);
  1247. KdOut("Axp64VtoP: pagefile PDE2 %d:%s\n",
  1248. AXP64_PAGE_FILE_INDEX(Entry), FormatAddr64(Addr));
  1249. if ((Status = g_Target->
  1250. ReadPageFile(AXP64_PAGE_FILE_INDEX(Entry), Addr,
  1251. &Entry, sizeof(Entry))) != S_OK)
  1252. {
  1253. KdOut("Axp64VtoP: PDE1 not present, 0x%X\n", Status);
  1254. m_Translating = FALSE;
  1255. return Status;
  1256. }
  1257. }
  1258. else
  1259. {
  1260. Addr = (((Virt >> AXP64_PDE2_SHIFT) & AXP64_PDE_MASK) *
  1261. sizeof(Entry)) +
  1262. ((Entry >> AXP64_VALID_PFN_SHIFT) << AXP64_PAGE_SHIFT);
  1263. KdOut("Axp64VtoP: PDE2 %s\n", FormatAddr64(Addr));
  1264. (*Levels)++;
  1265. if (Offsets != NULL && OffsetsSize > 0)
  1266. {
  1267. *Offsets++ = Addr;
  1268. OffsetsSize--;
  1269. }
  1270. if ((Status = g_Target->
  1271. ReadAllPhysical(Addr, &Entry, sizeof(Entry))) != S_OK)
  1272. {
  1273. KdOut("Axp64VtoP: PDE2 read error 0x%X\n", Status);
  1274. m_Translating = FALSE;
  1275. return Status;
  1276. }
  1277. }
  1278. if (Entry == 0)
  1279. {
  1280. KdOut("Axp64VtoP: zero PDE2\n");
  1281. m_Translating = FALSE;
  1282. return HR_PAGE_NOT_AVAILABLE;
  1283. }
  1284. else if (!(Entry & 1))
  1285. {
  1286. Addr = (((Virt >> AXP64_PTE_SHIFT) & AXP64_PTE_MASK) *
  1287. sizeof(Entry)) + AXP64_PAGE_FILE_OFFSET(Entry);
  1288. KdOut("Axp64VtoP: pagefile PTE %d:%s\n",
  1289. AXP64_PAGE_FILE_INDEX(Entry), FormatAddr64(Addr));
  1290. if ((Status = g_Target->
  1291. ReadPageFile(AXP64_PAGE_FILE_INDEX(Entry), Addr,
  1292. &Entry, sizeof(Entry))) != S_OK)
  1293. {
  1294. KdOut("Axp64VtoP: PDE2 not present, 0x%X\n", Status);
  1295. m_Translating = FALSE;
  1296. return Status;
  1297. }
  1298. }
  1299. else
  1300. {
  1301. Addr = (((Virt >> AXP64_PTE_SHIFT) & AXP64_PTE_MASK) * sizeof(Entry)) +
  1302. ((Entry >> AXP64_VALID_PFN_SHIFT) << AXP64_PAGE_SHIFT);
  1303. KdOut("Axp64VtoP: PTE %s\n", FormatAddr64(Addr));
  1304. (*Levels)++;
  1305. if (Offsets != NULL && OffsetsSize > 0)
  1306. {
  1307. *Offsets++ = Addr;
  1308. OffsetsSize--;
  1309. }
  1310. if ((Status = g_Target->
  1311. ReadAllPhysical(Addr, &Entry, sizeof(Entry))) != S_OK)
  1312. {
  1313. KdOut("Axp64VtoP: PTE read error 0x%X\n", Status);
  1314. m_Translating = FALSE;
  1315. return Status;
  1316. }
  1317. }
  1318. if (!(Entry & 0x1) &&
  1319. ((Entry & AXP64_MM_PTE_PROTOTYPE_MASK) ||
  1320. !(Entry & AXP64_MM_PTE_TRANSITION_MASK)))
  1321. {
  1322. if (Entry == 0)
  1323. {
  1324. KdOut("Axp64VtoP: zero PTE\n");
  1325. Status = HR_PAGE_NOT_AVAILABLE;
  1326. }
  1327. else if (Entry & AXP64_MM_PTE_PROTOTYPE_MASK)
  1328. {
  1329. KdOut("Axp64VtoP: prototype PTE\n");
  1330. Status = HR_PAGE_NOT_AVAILABLE;
  1331. }
  1332. else
  1333. {
  1334. *PfIndex = AXP64_PAGE_FILE_INDEX(Entry);
  1335. *LastVal = (Virt & (AXP64_PAGE_SIZE - 1)) +
  1336. AXP64_PAGE_FILE_OFFSET(Entry);
  1337. KdOut("Axp64VtoP: PTE not present, pagefile %d:%s\n",
  1338. *PfIndex, FormatAddr64(*LastVal));
  1339. Status = HR_PAGE_IN_PAGE_FILE;
  1340. }
  1341. m_Translating = FALSE;
  1342. return Status;
  1343. }
  1344. //
  1345. // This is a page which is either present or in transition.
  1346. // Return the physical address for the request virtual address.
  1347. //
  1348. *LastVal = ((Entry >> AXP64_VALID_PFN_SHIFT) << AXP64_PAGE_SHIFT) |
  1349. (Virt & (AXP64_PAGE_SIZE - 1));
  1350. KdOut("Axp64VtoP: Mapped phys %s\n", FormatAddr64(*LastVal));
  1351. (*Levels)++;
  1352. if (Offsets != NULL && OffsetsSize > 0)
  1353. {
  1354. *Offsets++ = *LastVal;
  1355. OffsetsSize--;
  1356. }
  1357. m_Translating = FALSE;
  1358. return S_OK;
  1359. }
  1360. HRESULT
  1361. Axp64MachineInfo::GetBaseTranslationVirtualOffset(PULONG64 Offset)
  1362. {
  1363. *Offset = AXP64_BASE_VIRT;
  1364. return S_OK;
  1365. }
  1366. void
  1367. Axp64MachineInfo::OutputFunctionEntry(PVOID RawEntry)
  1368. {
  1369. OutputFunctionEntry64((PIMAGE_ALPHA64_RUNTIME_FUNCTION_ENTRY)RawEntry);
  1370. }
  1371. HRESULT
  1372. Axp64MachineInfo::ReadDynamicFunctionTable(ULONG64 Table,
  1373. PULONG64 NextTable,
  1374. PULONG64 MinAddress,
  1375. PULONG64 MaxAddress,
  1376. PULONG64 BaseAddress,
  1377. PULONG64 TableData,
  1378. PULONG TableSize,
  1379. PWSTR OutOfProcessDll,
  1380. PCROSS_PLATFORM_DYNAMIC_FUNCTION_TABLE RawTable)
  1381. {
  1382. HRESULT Status;
  1383. if ((Status = g_Target->
  1384. ReadAllVirtual(Table, &RawTable->Axp64Table,
  1385. sizeof(RawTable->Axp64Table))) != S_OK)
  1386. {
  1387. return Status;
  1388. }
  1389. *NextTable = RawTable->Axp64Table.Links.Flink;
  1390. *MinAddress = RawTable->Axp64Table.MinimumAddress;
  1391. *MaxAddress = RawTable->Axp64Table.MaximumAddress;
  1392. *BaseAddress = RawTable->Axp64Table.MinimumAddress;
  1393. *TableData = RawTable->Axp64Table.FunctionTable;
  1394. *TableSize = RawTable->Axp64Table.EntryCount *
  1395. sizeof(IMAGE_ALPHA64_RUNTIME_FUNCTION_ENTRY);
  1396. OutOfProcessDll[0] = 0;
  1397. return S_OK;
  1398. }
  1399. PVOID
  1400. Axp64MachineInfo::FindDynamicFunctionEntry(PCROSS_PLATFORM_DYNAMIC_FUNCTION_TABLE Table,
  1401. ULONG64 Address,
  1402. PVOID TableData,
  1403. ULONG TableSize)
  1404. {
  1405. ULONG i;
  1406. PIMAGE_ALPHA64_RUNTIME_FUNCTION_ENTRY Func;
  1407. static IMAGE_ALPHA64_RUNTIME_FUNCTION_ENTRY s_RetFunc;
  1408. Func = (PIMAGE_ALPHA64_RUNTIME_FUNCTION_ENTRY)TableData;
  1409. for (i = 0; i < TableSize / sizeof(IMAGE_ALPHA64_RUNTIME_FUNCTION_ENTRY); i++)
  1410. {
  1411. if (Address >= ALPHA_RF_BEGIN_ADDRESS(Func) &&
  1412. Address < ALPHA_RF_END_ADDRESS(Func))
  1413. {
  1414. // The table data is temporary so copy the data into
  1415. // a static buffer for longer-term storage.
  1416. s_RetFunc.BeginAddress = Func->BeginAddress;
  1417. s_RetFunc.EndAddress = Func->EndAddress;
  1418. s_RetFunc.ExceptionHandler = Func->ExceptionHandler;
  1419. s_RetFunc.HandlerData = Func->HandlerData;
  1420. s_RetFunc.PrologEndAddress = Func->PrologEndAddress;
  1421. return (PVOID)&s_RetFunc;
  1422. }
  1423. Func++;
  1424. }
  1425. return NULL;
  1426. }