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.

554 lines
14 KiB

  1. //----------------------------------------------------------------------------
  2. //
  3. // ARM machine implementation.
  4. //
  5. // Copyright (C) Microsoft Corporation, 2001-2002.
  6. //
  7. //----------------------------------------------------------------------------
  8. #include "ntsdp.hpp"
  9. char g_ArmSp[] = "sp";
  10. char g_ArmLr[] = "lr";
  11. char g_ArmPc[] = "pc";
  12. char g_ArmPsr[] = "psr";
  13. char g_ArmPsrN[] = "nf";
  14. char g_ArmPsrZ[] = "zf";
  15. char g_ArmPsrC[] = "cf";
  16. char g_ArmPsrV[] = "vf";
  17. char g_ArmPsrQ[] = "qf";
  18. char g_ArmPsrI[] = "if";
  19. char g_ArmPsrF[] = "ff";
  20. char g_ArmPsrT[] = "tf";
  21. char g_ArmPsrMode[] = "mode";
  22. REGDEF g_ArmRegs[] =
  23. {
  24. g_R0, ARM_R0, g_R1, ARM_R1, g_R2, ARM_R2, g_R3, ARM_R3,
  25. g_R4, ARM_R4, g_R5, ARM_R5, g_R6, ARM_R6,
  26. g_R7, ARM_R7, g_R8, ARM_R8, g_R9, ARM_R9, g_R10, ARM_R10,
  27. g_R11, ARM_R11, g_R12, ARM_R12,
  28. g_ArmSp, ARM_SP, g_ArmLr, ARM_LR, g_ArmPc, ARM_PC, g_ArmPsr, ARM_PSR,
  29. g_ArmPsrN, ARM_PSR_N, g_ArmPsrZ, ARM_PSR_Z, g_ArmPsrC, ARM_PSR_C,
  30. g_ArmPsrV, ARM_PSR_V, g_ArmPsrQ, ARM_PSR_Q, g_ArmPsrI, ARM_PSR_I,
  31. g_ArmPsrF, ARM_PSR_F, g_ArmPsrT, ARM_PSR_T,
  32. g_ArmPsrMode, ARM_PSR_MODE,
  33. NULL, 0,
  34. };
  35. REGSUBDEF g_ArmSubRegs[] =
  36. {
  37. { ARM_PSR_N, ARM_PSR, 31, 1 },
  38. { ARM_PSR_Z, ARM_PSR, 30, 1 },
  39. { ARM_PSR_C, ARM_PSR, 29, 1 },
  40. { ARM_PSR_V, ARM_PSR, 28, 1 },
  41. { ARM_PSR_Q, ARM_PSR, 27, 1 },
  42. { ARM_PSR_I, ARM_PSR, 7, 1 },
  43. { ARM_PSR_F, ARM_PSR, 6, 1 },
  44. { ARM_PSR_T, ARM_PSR, 5, 1 },
  45. { ARM_PSR_MODE, ARM_PSR, 0, 5 },
  46. { REG_ERROR, REG_ERROR, 0, 0 },
  47. };
  48. RegisterGroup g_ArmGroup =
  49. {
  50. 0, g_ArmRegs, g_ArmSubRegs, NULL
  51. };
  52. // First ExecTypes entry must be the actual processor type.
  53. ULONG g_ArmExecTypes[] =
  54. {
  55. IMAGE_FILE_MACHINE_ARM
  56. };
  57. // This array must be sorted by CV reg value.
  58. CvRegMap g_ArmCvRegMap[] =
  59. {
  60. {CV_ARM_R0, ARM_R0},
  61. {CV_ARM_R1, ARM_R1},
  62. {CV_ARM_R2, ARM_R2},
  63. {CV_ARM_R3, ARM_R3},
  64. {CV_ARM_R4, ARM_R4},
  65. {CV_ARM_R5, ARM_R5},
  66. {CV_ARM_R6, ARM_R6},
  67. {CV_ARM_R7, ARM_R7},
  68. {CV_ARM_R8, ARM_R8},
  69. {CV_ARM_R9, ARM_R9},
  70. {CV_ARM_R10, ARM_R10},
  71. {CV_ARM_R11, ARM_R11},
  72. {CV_ARM_R12, ARM_R12},
  73. {CV_ARM_SP, ARM_SP},
  74. {CV_ARM_LR, ARM_LR},
  75. {CV_ARM_PC, ARM_PC},
  76. {CV_ARM_CPSR, ARM_PSR},
  77. };
  78. ArmMachineInfo::ArmMachineInfo(TargetInfo* Target)
  79. : MachineInfo(Target)
  80. {
  81. m_FullName = "ARM 32-bit";
  82. m_AbbrevName = "arm";
  83. m_PageSize = ARM_PAGE_SIZE;
  84. m_PageShift = ARM_PAGE_SHIFT;
  85. m_NumExecTypes = 1;
  86. m_ExecTypes = g_ArmExecTypes;
  87. m_Ptr64 = FALSE;
  88. m_RetRegIndex = ARM_R0;
  89. m_MaxDataBreakpoints = 0;
  90. m_SymPrefix = NULL;
  91. m_AllMask = REGALL_INT32;
  92. m_SizeCanonicalContext = sizeof(ARM_CONTEXT);
  93. m_SverCanonicalContext = NT_SVER_NT4;
  94. m_CvRegMapSize = DIMA(g_ArmCvRegMap);
  95. m_CvRegMap = g_ArmCvRegMap;
  96. }
  97. HRESULT
  98. ArmMachineInfo::Initialize(void)
  99. {
  100. m_NumGroups = 1;
  101. m_Groups[0] = &g_ArmGroup;
  102. return MachineInfo::Initialize();
  103. }
  104. void
  105. ArmMachineInfo::
  106. InitializeContext(ULONG64 Pc,
  107. PDBGKD_ANY_CONTROL_REPORT ControlReport)
  108. {
  109. // No ARM KD support.
  110. }
  111. void
  112. ArmMachineInfo::GetSystemTypeInfo(PSYSTEM_TYPE_INFO Info)
  113. {
  114. Info->SizeTargetContext = sizeof(ARM_CONTEXT);
  115. Info->OffsetTargetContextFlags =
  116. FIELD_OFFSET(ARM_CONTEXT, ContextFlags);
  117. // NT doesn't run on the ARM so these NT-related
  118. // data structure constants are not meaningful.
  119. Info->SizeControlReport = 0;
  120. Info->OffsetSpecialRegisters = 0;
  121. Info->SizeKspecialRegisters = 0;
  122. Info->TriagePrcbOffset = 0;
  123. Info->SizePageFrameNumber = sizeof(ULONG);
  124. Info->SizePte = sizeof(ULONG);
  125. Info->SharedUserDataOffset = 0;
  126. Info->UmSharedUserDataOffset = 0;
  127. Info->UmSharedSysCallOffset = 0;
  128. Info->UmSharedSysCallSize = 0;
  129. Info->SizeDynamicFunctionTable = 0;
  130. Info->SizeRuntimeFunction = 0;
  131. }
  132. void
  133. ArmMachineInfo::GetDefaultKdData(PKDDEBUGGER_DATA64 KdData)
  134. {
  135. // No KD data to fill in.
  136. }
  137. HRESULT
  138. ArmMachineInfo::KdGetContextState(ULONG State)
  139. {
  140. // MCTX_CONTEXT and MCTX_FULL are the same for Arm.
  141. if (State >= MCTX_CONTEXT && m_ContextState < MCTX_FULL)
  142. {
  143. HRESULT Status;
  144. Status = m_Target->GetContext(m_Target->m_RegContextThread->m_Handle,
  145. &m_Context);
  146. if (Status != S_OK)
  147. {
  148. return Status;
  149. }
  150. m_ContextState = MCTX_FULL;
  151. }
  152. return S_OK;
  153. }
  154. HRESULT
  155. ArmMachineInfo::KdSetContext(void)
  156. {
  157. return m_Target->SetContext(m_Target->m_RegContextThread->m_Handle,
  158. &m_Context);
  159. }
  160. HRESULT
  161. ArmMachineInfo::ConvertContextFrom(PCROSS_PLATFORM_CONTEXT Context,
  162. ULONG FromSver,
  163. ULONG FromSize, PVOID From)
  164. {
  165. if (FromSize < sizeof(ARM_CONTEXT))
  166. {
  167. return E_INVALIDARG;
  168. }
  169. memcpy(Context, From, sizeof(ARM_CONTEXT));
  170. return S_OK;
  171. }
  172. HRESULT
  173. ArmMachineInfo::ConvertContextTo(PCROSS_PLATFORM_CONTEXT Context,
  174. ULONG ToSver, ULONG ToSize, PVOID To)
  175. {
  176. if (ToSize < sizeof(ARM_CONTEXT))
  177. {
  178. return E_INVALIDARG;
  179. }
  180. memcpy(To, Context, sizeof(ARM_CONTEXT));
  181. return S_OK;
  182. }
  183. void
  184. ArmMachineInfo::InitializeContextFlags(PCROSS_PLATFORM_CONTEXT Context,
  185. ULONG Version)
  186. {
  187. Context->ArmContext.ContextFlags = ARM_CONTEXT_FULL;
  188. }
  189. HRESULT
  190. ArmMachineInfo::GetContextFromThreadStack(ULONG64 ThreadBase,
  191. PCROSS_PLATFORM_CONTEXT Context,
  192. ULONG64 Stack)
  193. {
  194. return E_NOTIMPL;
  195. }
  196. HRESULT
  197. ArmMachineInfo::GetContextFromFiber(ProcessInfo* Process,
  198. ULONG64 FiberBase,
  199. PCROSS_PLATFORM_CONTEXT Context,
  200. BOOL Verbose)
  201. {
  202. return E_NOTIMPL;
  203. }
  204. HRESULT
  205. ArmMachineInfo::GetContextFromTrapFrame(ULONG64 TrapBase,
  206. PCROSS_PLATFORM_CONTEXT Context,
  207. BOOL Verbose)
  208. {
  209. return E_NOTIMPL;
  210. }
  211. void
  212. ArmMachineInfo::GetScopeFrameFromContext(PCROSS_PLATFORM_CONTEXT Context,
  213. PDEBUG_STACK_FRAME ScopeFrame)
  214. {
  215. ZeroMemory(ScopeFrame, sizeof(*ScopeFrame));
  216. ScopeFrame->InstructionOffset = Context->ArmContext.Pc;
  217. ScopeFrame->FrameOffset = Context->ArmContext.R11;
  218. ScopeFrame->StackOffset = Context->ArmContext.Sp;
  219. }
  220. HRESULT
  221. ArmMachineInfo::GetScopeFrameRegister(ULONG Reg,
  222. PDEBUG_STACK_FRAME ScopeFrame,
  223. PULONG64 Value)
  224. {
  225. HRESULT Status;
  226. REGVAL RegVal;
  227. switch(Reg)
  228. {
  229. case ARM_SP:
  230. *Value = ScopeFrame->StackOffset;
  231. return S_OK;
  232. case ARM_R11:
  233. *Value = ScopeFrame->FrameOffset;
  234. return S_OK;
  235. default:
  236. RegVal.I64 = 0;
  237. if ((Status = FullGetVal(Reg, &RegVal)) != S_OK)
  238. {
  239. return Status;
  240. }
  241. *Value = RegVal.I64;
  242. return S_OK;
  243. }
  244. }
  245. HRESULT
  246. ArmMachineInfo::SetScopeFrameRegister(ULONG Reg,
  247. PDEBUG_STACK_FRAME ScopeFrame,
  248. ULONG64 Value)
  249. {
  250. REGVAL RegVal;
  251. switch(Reg)
  252. {
  253. case ARM_SP:
  254. ScopeFrame->StackOffset = Value;
  255. return S_OK;
  256. case ARM_R11:
  257. ScopeFrame->FrameOffset = Value;
  258. return S_OK;
  259. default:
  260. RegVal.Type = GetType(Reg);
  261. RegVal.I64 = Value;
  262. return FullSetVal(Reg, &RegVal);
  263. }
  264. }
  265. int
  266. ArmMachineInfo::GetType(ULONG Reg)
  267. {
  268. if (Reg < ARM_INT_FIRST || Reg > ARM_INT_LAST)
  269. {
  270. return REGVAL_SUB32;
  271. }
  272. else
  273. {
  274. return REGVAL_INT32;
  275. }
  276. }
  277. HRESULT
  278. ArmMachineInfo::GetVal(ULONG Reg, REGVAL *Val)
  279. {
  280. HRESULT Status;
  281. if (Reg < ARM_INT_FIRST || Reg > ARM_INT_LAST)
  282. {
  283. return E_INVALIDARG;
  284. }
  285. if ((Status = GetContextState(MCTX_FULL)) != S_OK)
  286. {
  287. return Status;
  288. }
  289. Val->Type = GetType(Reg);
  290. Val->I64 = *(&m_Context.ArmContext.R0 + (Reg - ARM_INT_FIRST));
  291. return S_OK;
  292. }
  293. HRESULT
  294. ArmMachineInfo::SetVal(ULONG Reg, REGVAL *Val)
  295. {
  296. HRESULT Status;
  297. if (m_ContextIsReadOnly)
  298. {
  299. return HRESULT_FROM_WIN32(ERROR_WRITE_FAULT);
  300. }
  301. if (Reg < ARM_INT_FIRST || Reg > ARM_INT_LAST)
  302. {
  303. return E_INVALIDARG;
  304. }
  305. // Optimize away some common cases where registers are
  306. // set to their current value.
  307. if (m_ContextState >= MCTX_PC && Reg == ARM_PC &&
  308. Val->I64 == m_Context.ArmContext.Pc)
  309. {
  310. return S_OK;
  311. }
  312. if ((Status = GetContextState(MCTX_DIRTY)) != S_OK)
  313. {
  314. return Status;
  315. }
  316. *(&m_Context.ArmContext.R0 + (Reg - ARM_INT_FIRST)) = Val->I32;
  317. NotifyChangeDebuggeeState(DEBUG_CDS_REGISTERS,
  318. RegCountFromIndex(Reg));
  319. return S_OK;
  320. }
  321. void
  322. ArmMachineInfo::GetPC(PADDR Address)
  323. {
  324. ADDRFLAT(Address, EXTEND64(GetReg32(ARM_PC)));
  325. }
  326. void
  327. ArmMachineInfo::SetPC(PADDR Address)
  328. {
  329. SetReg32(ARM_PC, (ULONG)Flat(*Address));
  330. }
  331. void
  332. ArmMachineInfo::GetFP(PADDR Address)
  333. {
  334. ADDRFLAT(Address, EXTEND64(GetReg32(ARM_R11)));
  335. }
  336. void
  337. ArmMachineInfo::GetSP(PADDR Address)
  338. {
  339. ADDRFLAT(Address, EXTEND64(GetReg32(ARM_SP)));
  340. }
  341. ULONG64
  342. ArmMachineInfo::GetArgReg(void)
  343. {
  344. return EXTEND64(GetReg32(ARM_R0));
  345. }
  346. ULONG64
  347. ArmMachineInfo::GetRetReg(void)
  348. {
  349. return EXTEND64(GetReg32(ARM_R0));
  350. }
  351. void
  352. ArmMachineInfo::OutputAll(ULONG Mask, ULONG OutMask)
  353. {
  354. if (GetContextState(MCTX_FULL) != S_OK)
  355. {
  356. ErrOut("Unable to retrieve register information\n");
  357. return;
  358. }
  359. if (Mask & (REGALL_INT32 | REGALL_INT64))
  360. {
  361. MaskOut(OutMask, " r0=%08x r1=%08x r2=%08x "
  362. "r3=%08x r4=%08x r5=%08x\n",
  363. m_Context.ArmContext.R0, m_Context.ArmContext.R1,
  364. m_Context.ArmContext.R2, m_Context.ArmContext.R3,
  365. m_Context.ArmContext.R4, m_Context.ArmContext.R5);
  366. MaskOut(OutMask, " r6=%08x r7=%08x r8=%08x "
  367. "r9=%08x r10=%08x r11=%08x\n",
  368. m_Context.ArmContext.R6, m_Context.ArmContext.R7,
  369. m_Context.ArmContext.R8, m_Context.ArmContext.R9,
  370. m_Context.ArmContext.R10, m_Context.ArmContext.R11);
  371. MaskOut(OutMask, "r12=%08x sp=%08x lr=%08x "
  372. "pc=%08x psr=%08x %s%s%s%s%s %s\n",
  373. m_Context.ArmContext.R12, m_Context.ArmContext.Sp,
  374. m_Context.ArmContext.Lr, m_Context.ArmContext.Pc,
  375. m_Context.ArmContext.Psr,
  376. (m_Context.ArmContext.Psr & ARM_FLAG_N) ? "N" : "-",
  377. (m_Context.ArmContext.Psr & ARM_FLAG_Z) ? "Z" : "-",
  378. (m_Context.ArmContext.Psr & ARM_FLAG_C) ? "C" : "-",
  379. (m_Context.ArmContext.Psr & ARM_FLAG_V) ? "V" : "-",
  380. (m_Context.ArmContext.Psr & ARM_FLAG_Q) ? "Q" : "-",
  381. (m_Context.ArmContext.Psr & ARM_FLAG_T) ? "Thumb" : "ARM");
  382. }
  383. }
  384. HRESULT
  385. ArmMachineInfo::SetAndOutputTrapFrame(ULONG64 TrapBase,
  386. PCROSS_PLATFORM_CONTEXT Context)
  387. {
  388. return SetAndOutputContext(Context, TRUE, REGALL_INT32);
  389. }
  390. TRACEMODE
  391. ArmMachineInfo::GetTraceMode(void)
  392. {
  393. return TRACE_NONE;
  394. }
  395. void
  396. ArmMachineInfo::SetTraceMode(TRACEMODE Mode)
  397. {
  398. // No explicit trace mode needed.
  399. }
  400. BOOL
  401. ArmMachineInfo::IsStepStatusSupported(ULONG Status)
  402. {
  403. switch (Status)
  404. {
  405. case DEBUG_STATUS_STEP_INTO:
  406. case DEBUG_STATUS_STEP_OVER:
  407. return TRUE;
  408. default:
  409. return FALSE;
  410. }
  411. }
  412. ULONG
  413. ArmMachineInfo::ExecutingMachine(void)
  414. {
  415. return m_ExecTypes[0];
  416. }
  417. HRESULT
  418. ArmMachineInfo::SetPageDirectory(ThreadInfo* Thread,
  419. ULONG Idx, ULONG64 PageDir,
  420. PULONG NextIdx)
  421. {
  422. return E_NOTIMPL;
  423. }
  424. HRESULT
  425. ArmMachineInfo::GetVirtualTranslationPhysicalOffsets(ThreadInfo* Thread,
  426. ULONG64 Virt,
  427. PULONG64 Offsets,
  428. ULONG OffsetsSize,
  429. PULONG Levels,
  430. PULONG PfIndex,
  431. PULONG64 LastVal)
  432. {
  433. return E_NOTIMPL;
  434. }
  435. HRESULT
  436. ArmMachineInfo::GetBaseTranslationVirtualOffset(PULONG64 Offset)
  437. {
  438. return E_NOTIMPL;
  439. }
  440. void
  441. ArmMachineInfo::DecodePte(ULONG64 Pte, PULONG64 PageFrameNumber,
  442. PULONG Flags)
  443. {
  444. // XXX
  445. *PageFrameNumber = 0;
  446. *Flags = 0;
  447. }
  448. void
  449. ArmMachineInfo::OutputFunctionEntry(PVOID RawEntry)
  450. {
  451. ErrOut("ARM function entries not implemented\n");
  452. }
  453. HRESULT
  454. ArmMachineInfo::ReadDynamicFunctionTable(ProcessInfo* Process,
  455. ULONG64 Table,
  456. PULONG64 NextTable,
  457. PULONG64 MinAddress,
  458. PULONG64 MaxAddress,
  459. PULONG64 BaseAddress,
  460. PULONG64 TableData,
  461. PULONG TableSize,
  462. PWSTR OutOfProcessDll,
  463. PCROSS_PLATFORM_DYNAMIC_FUNCTION_TABLE RawTable)
  464. {
  465. return E_NOTIMPL;
  466. }
  467. PVOID
  468. ArmMachineInfo::FindDynamicFunctionEntry(PCROSS_PLATFORM_DYNAMIC_FUNCTION_TABLE Table,
  469. ULONG64 Address,
  470. PVOID TableData,
  471. ULONG TableSize)
  472. {
  473. return NULL;
  474. }
  475. HRESULT
  476. ArmMachineInfo::ReadKernelProcessorId
  477. (ULONG Processor, PDEBUG_PROCESSOR_IDENTIFICATION_ALL Id)
  478. {
  479. // No ARM KD support.
  480. return E_NOTIMPL;
  481. }