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.

1409 lines
33 KiB

  1. //----------------------------------------------------------------------------
  2. //
  3. // Abstraction of processor-specific information.
  4. //
  5. // Copyright (C) Microsoft Corporation, 1999-2002.
  6. //
  7. //----------------------------------------------------------------------------
  8. #include "ntsdp.hpp"
  9. ULONG g_PossibleProcessorTypes[MACHIDX_COUNT] =
  10. {
  11. IMAGE_FILE_MACHINE_I386,
  12. IMAGE_FILE_MACHINE_IA64,
  13. IMAGE_FILE_MACHINE_AMD64,
  14. IMAGE_FILE_MACHINE_ARM,
  15. };
  16. // TRUE when symbol prefixing should be done.
  17. BOOL g_PrefixSymbols;
  18. // TRUE if context changed while processing
  19. BOOL g_ContextChanged;
  20. //
  21. // Pushed context space cache.
  22. //
  23. #define CONTEXT_PUSH_CACHE_SIZE 2
  24. ContextSave* g_ContextPushCache[CONTEXT_PUSH_CACHE_SIZE];
  25. //----------------------------------------------------------------------------
  26. //
  27. // MachineInfo.
  28. //
  29. //----------------------------------------------------------------------------
  30. MachineInfo::MachineInfo(TargetInfo* Target)
  31. {
  32. m_Target = Target;
  33. }
  34. MachineInfo::~MachineInfo(void)
  35. {
  36. if (g_Machine == this)
  37. {
  38. g_Machine = NULL;
  39. }
  40. if (g_EventMachine == this)
  41. {
  42. g_EventMachine = NULL;
  43. }
  44. }
  45. HRESULT
  46. MachineInfo::Initialize(void)
  47. {
  48. m_TraceMode = TRACE_NONE;
  49. m_ContextState = MCTX_NONE;
  50. m_ContextIsReadOnly = FALSE;
  51. m_MainCodeSeg = 0;
  52. m_NumRegs = 0;
  53. // Every machine supports basic integer and FP registers.
  54. m_AllMaskBits = DEBUG_REGISTERS_ALL;
  55. m_SymPrefixLen = m_SymPrefix != NULL ? strlen(m_SymPrefix) : 0;
  56. ZeroMemory(m_PageDirectories, sizeof(m_PageDirectories));
  57. m_Translating = FALSE;
  58. ULONG i;
  59. for (i = 0; i < SEGREG_COUNT; i++)
  60. {
  61. m_SegRegDesc[i].Flags = SEGDESC_INVALID;
  62. }
  63. ZeroMemory(&m_Context, sizeof(m_Context));
  64. InitializeContextFlags(&m_Context, m_SverCanonicalContext);
  65. DBG_ASSERT(m_MaxDataBreakpoints <= MAX_DATA_BREAKS);
  66. //
  67. // Count register definitions.
  68. //
  69. RegisterGroup* Group;
  70. DBG_ASSERT(m_NumGroups <= MAX_REGISTER_GROUPS);
  71. for (i = 0; i < m_NumGroups; i++)
  72. {
  73. Group = m_Groups[i];
  74. Group->NumberRegs = 0;
  75. REGDEF* Def = Group->Regs;
  76. while (Def->Name != NULL)
  77. {
  78. Group->NumberRegs++;
  79. Def++;
  80. }
  81. m_NumRegs += Group->NumberRegs;
  82. REGALLDESC* Desc = Group->AllExtraDesc;
  83. if (Desc != NULL)
  84. {
  85. while (Desc->Bit != 0)
  86. {
  87. m_AllMaskBits |= Desc->Bit;
  88. Desc++;
  89. }
  90. }
  91. }
  92. return S_OK;
  93. }
  94. HRESULT
  95. MachineInfo::InitializeForProcessor(void)
  96. {
  97. // Placeholder.
  98. return S_OK;
  99. }
  100. ULONG
  101. MachineInfo::CvRegToMachine(CV_HREG_e CvReg)
  102. {
  103. int Low, High, Mid;
  104. // Assume that a zero means no register. This
  105. // is true enough for CV mappings other than the 68K.
  106. if (CvReg == 0)
  107. {
  108. return CvReg;
  109. }
  110. Low = 0;
  111. High = m_CvRegMapSize - 1;
  112. while (Low <= High)
  113. {
  114. Mid = (Low + High) / 2;
  115. if (m_CvRegMap[Mid].CvReg == CvReg)
  116. {
  117. return m_CvRegMap[Mid].Machine;
  118. }
  119. else if (m_CvRegMap[Mid].CvReg < CvReg)
  120. {
  121. Low = Mid + 1;
  122. }
  123. else
  124. {
  125. High = Mid - 1;
  126. }
  127. }
  128. ErrOut("CvRegToMachine(%s) conversion failure for 0x%x\n",
  129. m_AbbrevName, CvReg);
  130. return 0;
  131. }
  132. HRESULT
  133. MachineInfo::GetContextState(ULONG State)
  134. {
  135. if (m_Target->m_RegContextThread == NULL)
  136. {
  137. // No error message here as this can get hit during
  138. // Reload("NT") initialization when accessing paged-out memory.
  139. // It's also noisy in other failure cases, so rely
  140. // on higher-level error output.
  141. return E_UNEXPECTED;
  142. }
  143. for (ULONG i = 0; i < m_Target->m_Machine->m_NumExecTypes; i++)
  144. {
  145. if (m_Target->m_Machine->m_ExecTypes[i] == m_ExecTypes[0])
  146. {
  147. break;
  148. }
  149. }
  150. if (i >= m_Target->m_Machine->m_NumExecTypes)
  151. {
  152. ErrOut("Machine is not a possible execution machine\n");
  153. return E_UNEXPECTED;
  154. }
  155. if (State == MCTX_DIRTY)
  156. {
  157. g_ContextChanged = TRUE;
  158. }
  159. if (m_ContextState >= State)
  160. {
  161. return S_OK;
  162. }
  163. HRESULT Status = E_UNEXPECTED;
  164. // Dump support is built into the Ud/Kd routines.
  165. if (IS_USER_TARGET(m_Target))
  166. {
  167. Status = UdGetContextState(State);
  168. }
  169. else if (IS_KERNEL_TARGET(m_Target))
  170. {
  171. Status = KdGetContextState(State);
  172. }
  173. if (Status != S_OK)
  174. {
  175. ErrOut("GetContextState failed, 0x%X\n", Status);
  176. return Status;
  177. }
  178. if (State == MCTX_DIRTY)
  179. {
  180. DBG_ASSERT(m_ContextState >= MCTX_FULL);
  181. m_ContextState = State;
  182. }
  183. DBG_ASSERT(State <= m_ContextState);
  184. return S_OK;
  185. }
  186. HRESULT
  187. MachineInfo::SetContext(void)
  188. {
  189. if (m_ContextState != MCTX_DIRTY)
  190. {
  191. // Nothing to write.
  192. return S_OK;
  193. }
  194. if (m_Target->m_RegContextThread == NULL)
  195. {
  196. ErrOut("No current thread in SetContext\n");
  197. return E_UNEXPECTED;
  198. }
  199. if (m_ContextIsReadOnly)
  200. {
  201. ErrOut("Context cannot be modified\n");
  202. return E_UNEXPECTED;
  203. }
  204. for (ULONG i = 0; i < m_Target->m_Machine->m_NumExecTypes; i++)
  205. {
  206. if (m_Target->m_Machine->m_ExecTypes[i] == m_ExecTypes[0])
  207. {
  208. break;
  209. }
  210. }
  211. if (i >= m_Target->m_Machine->m_NumExecTypes)
  212. {
  213. ErrOut("Machine is not a possible execution machine\n");
  214. return E_UNEXPECTED;
  215. }
  216. HRESULT Status = E_UNEXPECTED;
  217. if (IS_DUMP_TARGET(m_Target))
  218. {
  219. ErrOut("Can't set dump file contexts\n");
  220. return E_UNEXPECTED;
  221. }
  222. else if (IS_USER_TARGET(m_Target))
  223. {
  224. Status = UdSetContext();
  225. }
  226. else if (IS_KERNEL_TARGET(m_Target))
  227. {
  228. Status = KdSetContext();
  229. }
  230. if (Status != S_OK)
  231. {
  232. ErrOut("SetContext failed, 0x%X\n", Status);
  233. return Status;
  234. }
  235. // No longer dirty.
  236. m_ContextState = MCTX_FULL;
  237. return S_OK;
  238. }
  239. HRESULT
  240. MachineInfo::UdGetContextState(ULONG State)
  241. {
  242. // MCTX_CONTEXT and MCTX_FULL are the same in user mode.
  243. if (State >= MCTX_CONTEXT && m_ContextState < MCTX_FULL)
  244. {
  245. HRESULT Status = m_Target->
  246. GetContext(m_Target->m_RegContextThread->m_Handle,
  247. &m_Context);
  248. if (Status != S_OK)
  249. {
  250. return Status;
  251. }
  252. Status = m_Target->GetTargetSegRegDescriptors
  253. (m_Target->m_RegContextThread->m_Handle,
  254. 0, SEGREG_COUNT, m_SegRegDesc);
  255. if (Status != S_OK)
  256. {
  257. return Status;
  258. }
  259. m_ContextState = MCTX_FULL;
  260. }
  261. return S_OK;
  262. }
  263. HRESULT
  264. MachineInfo::UdSetContext(void)
  265. {
  266. return m_Target->SetContext(m_Target->m_RegContextThread->m_Handle,
  267. &m_Context);
  268. }
  269. void
  270. MachineInfo::InvalidateContext(void)
  271. {
  272. m_ContextState = MCTX_NONE;
  273. m_Target->InvalidateTargetContext();
  274. ULONG i;
  275. for (i = 0; i < SEGREG_COUNT; i++)
  276. {
  277. m_SegRegDesc[i].Flags = SEGDESC_INVALID;
  278. }
  279. }
  280. HRESULT
  281. MachineInfo::GetContextFromTaskSegment(ULONG64 TssBase,
  282. PCROSS_PLATFORM_CONTEXT Context,
  283. BOOL Verbose)
  284. {
  285. // Only x86 has task segments, so fail everywhere else.
  286. if (Verbose)
  287. {
  288. ErrOut("Processor does not have task segments\n");
  289. }
  290. return E_UNEXPECTED;
  291. }
  292. void
  293. MachineInfo::GetStackDefaultsFromContext(PCROSS_PLATFORM_CONTEXT Context,
  294. LPADDRESS64 Instr,
  295. LPADDRESS64 Stack,
  296. LPADDRESS64 Frame)
  297. {
  298. // Zeroed addresses are interpreted as defaults by
  299. // the dbghelp stack walking code. Any pure-flat-address
  300. // processor can use this.
  301. ZeroMemory(Instr, sizeof(*Instr));
  302. ZeroMemory(Stack, sizeof(*Stack));
  303. ZeroMemory(Frame, sizeof(*Frame));
  304. }
  305. void
  306. MachineInfo::SanitizeMemoryContext(PCROSS_PLATFORM_CONTEXT Context)
  307. {
  308. // Nothing to do.
  309. }
  310. HRESULT
  311. MachineInfo::GetExdiContext(IUnknown* Exdi, PEXDI_CONTEXT Context,
  312. EXDI_CONTEXT_TYPE CtxType)
  313. {
  314. return E_NOTIMPL;
  315. }
  316. HRESULT
  317. MachineInfo::SetExdiContext(IUnknown* Exdi, PEXDI_CONTEXT Context,
  318. EXDI_CONTEXT_TYPE CtxType)
  319. {
  320. return E_NOTIMPL;
  321. }
  322. void
  323. MachineInfo::ConvertExdiContextFromContext(PCROSS_PLATFORM_CONTEXT Context,
  324. PEXDI_CONTEXT ExdiContext,
  325. EXDI_CONTEXT_TYPE CtxType)
  326. {
  327. // Nothing to do.
  328. }
  329. void
  330. MachineInfo::ConvertExdiContextToContext(PEXDI_CONTEXT ExdiContext,
  331. EXDI_CONTEXT_TYPE CtxType,
  332. PCROSS_PLATFORM_CONTEXT Context)
  333. {
  334. // Nothing to do.
  335. }
  336. void
  337. MachineInfo::ConvertExdiContextToSegDescs(PEXDI_CONTEXT ExdiContext,
  338. EXDI_CONTEXT_TYPE CtxType,
  339. ULONG Start, ULONG Count,
  340. PDESCRIPTOR64 Descs)
  341. {
  342. // Nothing to do.
  343. }
  344. void
  345. MachineInfo::ConvertExdiContextFromSpecial
  346. (PCROSS_PLATFORM_KSPECIAL_REGISTERS Special,
  347. PEXDI_CONTEXT ExdiContext, EXDI_CONTEXT_TYPE CtxType)
  348. {
  349. // Nothing to do.
  350. }
  351. void
  352. MachineInfo::ConvertExdiContextToSpecial
  353. (PEXDI_CONTEXT ExdiContext, EXDI_CONTEXT_TYPE CtxType,
  354. PCROSS_PLATFORM_KSPECIAL_REGISTERS Special)
  355. {
  356. // Nothing to do.
  357. }
  358. ULONG
  359. MachineInfo::GetSegRegNum(ULONG SegReg)
  360. {
  361. return 0;
  362. }
  363. HRESULT
  364. MachineInfo::GetSegRegDescriptor(ULONG SegReg, PDESCRIPTOR64 Desc)
  365. {
  366. return E_UNEXPECTED;
  367. }
  368. HRESULT
  369. MachineInfo::SetAndOutputTaskSegment(ULONG64 TssBase,
  370. PCROSS_PLATFORM_CONTEXT Context,
  371. BOOL Extended)
  372. {
  373. ErrOut("Processor does not have task segments\n");
  374. return E_UNEXPECTED;
  375. }
  376. void
  377. MachineInfo::KdUpdateControlSet(PDBGKD_ANY_CONTROL_SET ControlSet)
  378. {
  379. // Nothing to do.
  380. }
  381. HRESULT
  382. MachineInfo::SetDefaultPageDirectories(ThreadInfo* Thread, ULONG Mask)
  383. {
  384. HRESULT Status;
  385. ULONG i;
  386. ULONG64 OldDirs[PAGE_DIR_COUNT];
  387. //
  388. // Triage dumps only have virtual memory and no physical
  389. // translations so we want to catch any usage of page
  390. // directories as they have no effect.
  391. DBG_ASSERT(IS_KERNEL_TARGET(m_Target) && !IS_KERNEL_TRIAGE_DUMP(m_Target));
  392. memcpy(OldDirs, m_PageDirectories, sizeof(m_PageDirectories));
  393. i = 0;
  394. while (i < PAGE_DIR_COUNT)
  395. {
  396. // Pass on the set to machine-specific code.
  397. if (Mask & (1 << i))
  398. {
  399. if ((Status = SetPageDirectory(Thread, i, 0, &i)) != S_OK)
  400. {
  401. memcpy(m_PageDirectories, OldDirs, sizeof(m_PageDirectories));
  402. return Status;
  403. }
  404. }
  405. else
  406. {
  407. i++;
  408. }
  409. }
  410. // Try and validate that the new kernel page directory is
  411. // valid by checking an address that should always
  412. // be available.
  413. if ((Mask & (1 << PAGE_DIR_KERNEL)) &&
  414. IS_KERNEL_TARGET(m_Target) &&
  415. m_Target->m_KdDebuggerData.PsLoadedModuleList)
  416. {
  417. LIST_ENTRY64 List;
  418. if ((Status = m_Target->
  419. ReadListEntry(m_Target->m_ProcessHead,
  420. this, m_Target->m_KdDebuggerData.PsLoadedModuleList,
  421. &List)) != S_OK)
  422. {
  423. // This page directory doesn't seem valid so restore
  424. // the previous setting and fail.
  425. memcpy(m_PageDirectories, OldDirs, sizeof(m_PageDirectories));
  426. }
  427. }
  428. return Status;
  429. }
  430. HRESULT
  431. MachineInfo::NewBreakpoint(DebugClient* Client,
  432. ULONG Type,
  433. ULONG Id,
  434. Breakpoint** RetBp)
  435. {
  436. return E_NOINTERFACE;
  437. }
  438. void
  439. MachineInfo::InsertThreadDataBreakpoints(void)
  440. {
  441. // Nothing to do.
  442. }
  443. void
  444. MachineInfo::RemoveThreadDataBreakpoints(void)
  445. {
  446. // Nothing to do.
  447. }
  448. ULONG
  449. MachineInfo::IsBreakpointOrStepException(PEXCEPTION_RECORD64 Record,
  450. ULONG FirstChance,
  451. PADDR BpAddr,
  452. PADDR RelAddr)
  453. {
  454. return Record->ExceptionCode == STATUS_BREAKPOINT ?
  455. EXBS_BREAKPOINT_ANY : EXBS_NONE;
  456. }
  457. void
  458. MachineInfo::GetRetAddr(PADDR Addr)
  459. {
  460. DEBUG_STACK_FRAME StackFrame;
  461. if (StackTrace(NULL,
  462. 0, 0, 0, STACK_ALL_DEFAULT,
  463. &StackFrame, 1, 0, 0, FALSE) > 0)
  464. {
  465. ADDRFLAT(Addr, StackFrame.ReturnOffset);
  466. }
  467. else
  468. {
  469. ErrOut("StackTrace failed\n");
  470. ADDRFLAT(Addr, 0);
  471. }
  472. }
  473. BOOL
  474. MachineInfo::GetPrefixedSymbolOffset(ProcessInfo* Proces,
  475. ULONG64 SymOffset,
  476. ULONG Flags,
  477. PULONG64 PrefixedSymOffset)
  478. {
  479. DBG_ASSERT(m_SymPrefix == NULL);
  480. // This routine should never be called since there's no prefix.
  481. return FALSE;
  482. }
  483. HRESULT
  484. MachineInfo::ReadDynamicFunctionTable(ProcessInfo* Process,
  485. ULONG64 Table,
  486. PULONG64 NextTable,
  487. PULONG64 MinAddress,
  488. PULONG64 MaxAddress,
  489. PULONG64 BaseAddress,
  490. PULONG64 TableData,
  491. PULONG TableSize,
  492. PWSTR OutOfProcessDll,
  493. PCROSS_PLATFORM_DYNAMIC_FUNCTION_TABLE RawTable)
  494. {
  495. // No dynamic function table support.
  496. return E_UNEXPECTED;
  497. }
  498. PVOID
  499. MachineInfo::FindDynamicFunctionEntry(PCROSS_PLATFORM_DYNAMIC_FUNCTION_TABLE Table,
  500. ULONG64 Address,
  501. PVOID TableData,
  502. ULONG TableSize)
  503. {
  504. // No dynamic function tables so no match.
  505. return NULL;
  506. }
  507. HRESULT
  508. MachineInfo::GetUnwindInfoBounds(ProcessInfo* Process,
  509. ULONG64 TableBase,
  510. PVOID RawTableEntries,
  511. ULONG EntryIndex,
  512. PULONG64 Start,
  513. PULONG Size)
  514. {
  515. // No dynamic function tables.
  516. return E_UNEXPECTED;
  517. }
  518. void
  519. MachineInfo::FlushPerExecutionCaches(void)
  520. {
  521. // Dump targets don't really execute so there's no need
  522. // to throw away settings, plus the page directories
  523. // are set to important values during initialization so
  524. // throwing them away would lead to problems.
  525. if (!IS_DUMP_TARGET(m_Target))
  526. {
  527. ZeroMemory(m_PageDirectories, sizeof(m_PageDirectories));
  528. }
  529. m_Translating = FALSE;
  530. }
  531. HRESULT
  532. MachineInfo::GetAlternateTriageDumpDataRanges(ULONG64 PrcbBase,
  533. ULONG64 ThreadBase,
  534. PADDR_RANGE Ranges)
  535. {
  536. return E_NOTIMPL;
  537. }
  538. void
  539. MachineInfo::PrintStackFrameAddressesTitle(ULONG Flags)
  540. {
  541. if (!(Flags & DEBUG_STACK_FRAME_ADDRESSES_RA_ONLY))
  542. {
  543. PrintMultiPtrTitle("Child-SP", 1);
  544. }
  545. PrintMultiPtrTitle("RetAddr", 1);
  546. }
  547. void
  548. MachineInfo::PrintStackFrameAddresses(ULONG Flags,
  549. PDEBUG_STACK_FRAME StackFrame)
  550. {
  551. if (!(Flags & DEBUG_STACK_FRAME_ADDRESSES_RA_ONLY))
  552. {
  553. dprintf("%s ", FormatAddr64(StackFrame->StackOffset));
  554. }
  555. dprintf("%s ", FormatAddr64(StackFrame->ReturnOffset));
  556. }
  557. void
  558. MachineInfo::PrintStackArgumentsTitle(ULONG Flags)
  559. {
  560. dprintf(": ");
  561. PrintMultiPtrTitle("Args to Child", 4);
  562. dprintf(": ");
  563. }
  564. void
  565. MachineInfo::PrintStackArguments(ULONG Flags,
  566. PDEBUG_STACK_FRAME StackFrame)
  567. {
  568. dprintf(": %s %s %s %s : ",
  569. FormatAddr64(StackFrame->Params[0]),
  570. FormatAddr64(StackFrame->Params[1]),
  571. FormatAddr64(StackFrame->Params[2]),
  572. FormatAddr64(StackFrame->Params[3]));
  573. }
  574. void
  575. MachineInfo::PrintStackCallSiteTitle(ULONG Flags)
  576. {
  577. dprintf("Call Site");
  578. }
  579. void
  580. MachineInfo::PrintStackCallSite(ULONG Flags,
  581. PDEBUG_STACK_FRAME StackFrame,
  582. PSYMBOL_INFO SiteSymbol,
  583. PSTR SymName,
  584. DWORD64 Displacement)
  585. {
  586. if (SymName[0])
  587. {
  588. dprintf("%s", SymName);
  589. if (!(Flags & DEBUG_STACK_PARAMETERS) ||
  590. !ShowFunctionParameters(StackFrame))
  591. {
  592. // We dont see the parameters
  593. }
  594. if (Displacement)
  595. {
  596. dprintf("+");
  597. }
  598. }
  599. if (Displacement || !SymName[0])
  600. {
  601. dprintf("0x%s", FormatDisp64(Displacement));
  602. }
  603. }
  604. void
  605. MachineInfo::PrintStackNonvolatileRegisters(ULONG Flags,
  606. PDEBUG_STACK_FRAME StackFrame,
  607. PCROSS_PLATFORM_CONTEXT Context,
  608. ULONG FrameNum)
  609. {
  610. // Empty base implementation.
  611. }
  612. void
  613. MachineInfo::PrintStackFrameMemoryUsage(PDEBUG_STACK_FRAME CurFrame,
  614. PDEBUG_STACK_FRAME PrevFrame)
  615. {
  616. if (CurFrame->FrameOffset >= PrevFrame->FrameOffset)
  617. {
  618. dprintf(" %6x ",
  619. (ULONG)(CurFrame->StackOffset - PrevFrame->StackOffset));
  620. }
  621. else
  622. {
  623. dprintf(" ");
  624. }
  625. }
  626. HRESULT
  627. MachineInfo::FullGetVal(ULONG Reg, REGVAL* Val)
  628. {
  629. HRESULT Status;
  630. int Type;
  631. REGSUBDEF* SubDef;
  632. Type = GetType(Reg);
  633. if (Type == REGVAL_SUB32 || Type == REGVAL_SUB64)
  634. {
  635. SubDef = RegSubDefFromIndex(Reg);
  636. if (SubDef == NULL)
  637. {
  638. return E_INVALIDARG;
  639. }
  640. Reg = SubDef->FullReg;
  641. }
  642. if ((Status = GetVal(Reg, Val)) != S_OK)
  643. {
  644. return Status;
  645. }
  646. if (Type == REGVAL_SUB32 || Type == REGVAL_SUB64)
  647. {
  648. if (Val->Type == REGVAL_SUB32)
  649. {
  650. Val->I64Parts.High = 0;
  651. }
  652. Val->Type = Type;
  653. Val->I64 = (Val->I64 >> SubDef->Shift) & SubDef->Mask;
  654. }
  655. return S_OK;
  656. }
  657. HRESULT
  658. MachineInfo::FullSetVal(ULONG Reg, REGVAL* Val)
  659. {
  660. HRESULT Status;
  661. REGSUBDEF* SubDef;
  662. REGVAL BaseVal;
  663. if (Val->Type == REGVAL_SUB32 || Val->Type == REGVAL_SUB64)
  664. {
  665. // Look up subreg definition.
  666. SubDef = RegSubDefFromIndex(Reg);
  667. if (SubDef == NULL)
  668. {
  669. return E_INVALIDARG;
  670. }
  671. Reg = SubDef->FullReg;
  672. if ((Status = GetVal(Reg, &BaseVal)) != S_OK)
  673. {
  674. return Status;
  675. }
  676. if (Val->Type == REGVAL_SUB32)
  677. {
  678. Val->I64Parts.High = 0;
  679. }
  680. if (Val->I64 > SubDef->Mask)
  681. {
  682. return E_INVALIDARG;
  683. }
  684. BaseVal.I64 =
  685. (BaseVal.I64 & ~(SubDef->Mask << SubDef->Shift)) |
  686. ((Val->I64 & SubDef->Mask) << SubDef->Shift);
  687. Val = &BaseVal;
  688. }
  689. if ((Status = SetVal(Reg, Val)) != S_OK)
  690. {
  691. return Status;
  692. }
  693. return S_OK;
  694. }
  695. void
  696. MachineInfo::FormAddr(ULONG SegOrReg, ULONG64 Off,
  697. ULONG Flags, PADDR Address)
  698. {
  699. PDESCRIPTOR64 SegDesc = NULL;
  700. DESCRIPTOR64 Desc;
  701. Address->off = Off;
  702. if (Flags & FORM_SEGREG)
  703. {
  704. ULONG SegRegNum = GetSegRegNum(SegOrReg);
  705. if (SegRegNum)
  706. {
  707. Address->seg = GetReg16(SegRegNum);
  708. }
  709. else
  710. {
  711. Address->seg = 0;
  712. }
  713. }
  714. else
  715. {
  716. Address->seg = (USHORT)SegOrReg;
  717. }
  718. if (Flags & FORM_VM86)
  719. {
  720. Address->type = ADDR_V86;
  721. }
  722. else if (Address->seg == 0)
  723. {
  724. // A segment wasn't used or segmentation doesn't exist.
  725. Address->type = ADDR_FLAT;
  726. }
  727. else
  728. {
  729. HRESULT Status;
  730. if (Flags & FORM_SEGREG)
  731. {
  732. Status = GetSegRegDescriptor(SegOrReg, &Desc);
  733. }
  734. else
  735. {
  736. Status = m_Target->
  737. GetSelDescriptor(m_Target->m_RegContextThread, this,
  738. SegOrReg, &Desc);
  739. }
  740. if (Status == S_OK)
  741. {
  742. SegDesc = &Desc;
  743. if (((Flags & FORM_CODE) && (Desc.Flags & X86_DESC_LONG_MODE)) ||
  744. ((Flags & FORM_CODE) == 0 && g_Amd64InCode64))
  745. {
  746. Address->type = ADDR_1664;
  747. }
  748. else if (Desc.Flags & X86_DESC_DEFAULT_BIG)
  749. {
  750. Address->type = ADDR_1632;
  751. }
  752. else
  753. {
  754. Address->type = ADDR_16;
  755. }
  756. if ((Flags & FORM_CODE) &&
  757. ((m_ExecTypes[0] == IMAGE_FILE_MACHINE_I386 &&
  758. Address->type == ADDR_1632) ||
  759. (m_ExecTypes[0] == IMAGE_FILE_MACHINE_AMD64 &&
  760. Address->type == ADDR_1664)))
  761. {
  762. if ( m_MainCodeSeg == 0 )
  763. {
  764. if ( Desc.Base == 0 )
  765. {
  766. m_MainCodeSeg = Address->seg;
  767. }
  768. }
  769. if ( Address->seg == m_MainCodeSeg )
  770. {
  771. Address->type = ADDR_FLAT;
  772. }
  773. }
  774. }
  775. else
  776. {
  777. Address->type = ADDR_16;
  778. }
  779. }
  780. ComputeFlatAddress(Address, SegDesc);
  781. }
  782. REGSUBDEF*
  783. MachineInfo::RegSubDefFromIndex(ULONG Index)
  784. {
  785. RegisterGroup* Group;
  786. REGSUBDEF* SubDef;
  787. ULONG GroupIdx;
  788. for (GroupIdx = 0;
  789. GroupIdx < m_NumGroups;
  790. GroupIdx++)
  791. {
  792. Group = m_Groups[GroupIdx];
  793. SubDef = Group->SubRegs;
  794. if (SubDef == NULL)
  795. {
  796. continue;
  797. }
  798. while (SubDef->SubReg != REG_ERROR)
  799. {
  800. if (SubDef->SubReg == Index)
  801. {
  802. return SubDef;
  803. }
  804. SubDef++;
  805. }
  806. }
  807. return NULL;
  808. }
  809. REGDEF*
  810. MachineInfo::RegDefFromIndex(ULONG Index)
  811. {
  812. REGDEF* Def;
  813. RegisterGroup* Group;
  814. ULONG GroupIdx;
  815. for (GroupIdx = 0;
  816. GroupIdx < m_NumGroups;
  817. GroupIdx++)
  818. {
  819. Group = m_Groups[GroupIdx];
  820. Def = Group->Regs;
  821. while (Def->Name != NULL)
  822. {
  823. if (Def->Index == Index)
  824. {
  825. return Def;
  826. }
  827. Def++;
  828. }
  829. }
  830. return NULL;
  831. }
  832. REGDEF*
  833. MachineInfo::RegDefFromCount(ULONG Count)
  834. {
  835. RegisterGroup* Group;
  836. ULONG GroupIdx;
  837. for (GroupIdx = 0;
  838. GroupIdx < m_NumGroups;
  839. GroupIdx++)
  840. {
  841. Group = m_Groups[GroupIdx];
  842. if (Count < Group->NumberRegs)
  843. {
  844. return Group->Regs + Count;
  845. }
  846. Count -= Group->NumberRegs;
  847. }
  848. return NULL;
  849. }
  850. ULONG
  851. MachineInfo::RegCountFromIndex(ULONG Index)
  852. {
  853. REGDEF* Def;
  854. RegisterGroup* Group;
  855. ULONG Count;
  856. ULONG GroupIdx;
  857. Count = 0;
  858. for (GroupIdx = 0;
  859. GroupIdx < m_NumGroups;
  860. GroupIdx++)
  861. {
  862. Group = m_Groups[GroupIdx];
  863. Def = Group->Regs;
  864. while (Def->Name != NULL)
  865. {
  866. if (Def->Index == Index)
  867. {
  868. return Count + (ULONG)(Def - Group->Regs);
  869. }
  870. Def++;
  871. }
  872. Count += Group->NumberRegs;
  873. }
  874. return NULL;
  875. }
  876. ContextSave*
  877. MachineInfo::PushContext(PCROSS_PLATFORM_CONTEXT Context)
  878. {
  879. ULONG i;
  880. ContextSave* Save;
  881. Save = NULL;
  882. for (i = 0; i < CONTEXT_PUSH_CACHE_SIZE; i++)
  883. {
  884. if (g_ContextPushCache[i])
  885. {
  886. Save = g_ContextPushCache[i];
  887. g_ContextPushCache[i] = NULL;
  888. break;
  889. }
  890. }
  891. if (!Save)
  892. {
  893. // If this allocation fails we simply don't push
  894. // and the current context is destroyed. This
  895. // is detected in pop and things are set up
  896. // to recover whatever context is possible.
  897. Save = new ContextSave;
  898. if (!Save)
  899. {
  900. ErrOut("ERROR: Unable to allocate push context\n");
  901. }
  902. }
  903. if (Save)
  904. {
  905. Save->ContextState = m_ContextState;
  906. Save->ReadOnly = m_ContextIsReadOnly;
  907. Save->Context = m_Context;
  908. Save->Special = m_Special;
  909. memcpy(Save->SegRegDesc, m_SegRegDesc, sizeof(m_SegRegDesc));
  910. }
  911. if (Context)
  912. {
  913. m_Context = *Context;
  914. m_ContextState = MCTX_FULL;
  915. m_ContextIsReadOnly = TRUE;
  916. }
  917. else
  918. {
  919. m_ContextState = MCTX_NONE;
  920. m_Target->InvalidateTargetContext();
  921. m_ContextIsReadOnly = FALSE;
  922. }
  923. return Save;
  924. }
  925. void
  926. MachineInfo::PopContext(ContextSave* Save)
  927. {
  928. DBG_ASSERT(m_ContextState != MCTX_DIRTY);
  929. // If target context reloads were allowed we have
  930. // to reset the target context to get back any
  931. // previous state.
  932. if (!m_ContextIsReadOnly)
  933. {
  934. m_Target->InvalidateTargetContext();
  935. }
  936. if (!Save)
  937. {
  938. // There was an allocation failure during push and
  939. // the context was destroyed. Reset things to
  940. // a no-context state.
  941. m_ContextState = MCTX_NONE;
  942. m_ContextIsReadOnly = FALSE;
  943. }
  944. else
  945. {
  946. ULONG i;
  947. m_ContextState = Save->ContextState;
  948. m_ContextIsReadOnly = Save->ReadOnly;
  949. m_Context = Save->Context;
  950. m_Special = Save->Special;
  951. memcpy(m_SegRegDesc, Save->SegRegDesc, sizeof(m_SegRegDesc));
  952. for (i = 0; i < CONTEXT_PUSH_CACHE_SIZE; i++)
  953. {
  954. if (!g_ContextPushCache[i])
  955. {
  956. g_ContextPushCache[i] = Save;
  957. break;
  958. }
  959. }
  960. if (i >= CONTEXT_PUSH_CACHE_SIZE)
  961. {
  962. delete Save;
  963. }
  964. }
  965. }
  966. //----------------------------------------------------------------------------
  967. //
  968. // Functions.
  969. //
  970. //----------------------------------------------------------------------------
  971. MachineInfo*
  972. NewMachineInfo(ULONG Index, ULONG BaseMachineType,
  973. TargetInfo* Target)
  974. {
  975. switch(Index)
  976. {
  977. case MACHIDX_I386:
  978. // There are different X86 machines due to
  979. // the emulations available on various systems and CPUs.
  980. switch(BaseMachineType)
  981. {
  982. case IMAGE_FILE_MACHINE_IA64:
  983. return new X86OnIa64MachineInfo(Target);
  984. case IMAGE_FILE_MACHINE_AMD64:
  985. return new X86OnAmd64MachineInfo(Target);
  986. default:
  987. return new X86MachineInfo(Target);
  988. }
  989. break;
  990. case MACHIDX_IA64:
  991. return new Ia64MachineInfo(Target);
  992. case MACHIDX_AMD64:
  993. return new Amd64MachineInfo(Target);
  994. case MACHIDX_ARM:
  995. return new ArmMachineInfo(Target);
  996. }
  997. return NULL;
  998. }
  999. MachineIndex
  1000. MachineTypeIndex(ULONG Machine)
  1001. {
  1002. switch(Machine)
  1003. {
  1004. case IMAGE_FILE_MACHINE_I386:
  1005. return MACHIDX_I386;
  1006. case IMAGE_FILE_MACHINE_IA64:
  1007. return MACHIDX_IA64;
  1008. case IMAGE_FILE_MACHINE_AMD64:
  1009. return MACHIDX_AMD64;
  1010. case IMAGE_FILE_MACHINE_ARM:
  1011. return MACHIDX_ARM;
  1012. default:
  1013. return MACHIDX_COUNT;
  1014. }
  1015. }
  1016. void
  1017. CacheReportInstructions(ULONG64 Pc, ULONG Count, PUCHAR Stream)
  1018. {
  1019. // There was a long-standing bug in the kernel
  1020. // where it didn't properly remove all breakpoints
  1021. // present in the instruction stream reported to
  1022. // the debugger. If this kernel suffers from the
  1023. // problem just ignore the stream contents.
  1024. if (Count == 0 || g_Target->m_BuildNumber < 2300)
  1025. {
  1026. return;
  1027. }
  1028. g_Process->m_VirtualCache.Add(Pc, Stream, Count);
  1029. }
  1030. BOOL
  1031. IsImageMachineType64(DWORD MachineType)
  1032. {
  1033. switch (MachineType)
  1034. {
  1035. case IMAGE_FILE_MACHINE_AXP64:
  1036. case IMAGE_FILE_MACHINE_IA64:
  1037. case IMAGE_FILE_MACHINE_AMD64:
  1038. return TRUE;
  1039. default:
  1040. return FALSE;
  1041. }
  1042. }
  1043. //----------------------------------------------------------------------------
  1044. //
  1045. // Common code and constants.
  1046. //
  1047. //----------------------------------------------------------------------------
  1048. UCHAR g_HexDigit[16] =
  1049. {
  1050. '0', '1', '2', '3', '4', '5', '6', '7',
  1051. '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
  1052. };
  1053. void
  1054. MachineInfo::BufferHex(ULONG64 Value,
  1055. ULONG Length,
  1056. BOOL Signed)
  1057. {
  1058. CHAR Digit[32];
  1059. LONG Index = 0;
  1060. DBG_ASSERT(Length <= sizeof(Digit));
  1061. if (Signed && (LONG64)Value < 0)
  1062. {
  1063. *m_Buf++ = '-';
  1064. Value = -(LONG64)Value;
  1065. }
  1066. do
  1067. {
  1068. Digit[Index++] = g_HexDigit[Value & 0xf];
  1069. Value >>= 4;
  1070. }
  1071. while ((Signed && Value) || (!Signed && Index < (LONG)Length));
  1072. while (--Index >= 0)
  1073. {
  1074. *m_Buf++ = Digit[Index];
  1075. }
  1076. }
  1077. void
  1078. MachineInfo::BufferInt(ULONG64 Value,
  1079. ULONG MinLength,
  1080. BOOL Signed)
  1081. {
  1082. CHAR Digit[97];
  1083. LONG Index = 0, MaxDig;
  1084. BOOL Neg;
  1085. DBG_ASSERT(MinLength <= sizeof(Digit));
  1086. if (Signed && (LONG64)Value < 0)
  1087. {
  1088. Neg = TRUE;
  1089. Value = -(LONG64)Value;
  1090. }
  1091. else
  1092. {
  1093. Neg = FALSE;
  1094. }
  1095. do
  1096. {
  1097. Digit[Index++] = (char)((Value % 10) + '0');
  1098. Value /= 10;
  1099. }
  1100. while (Value);
  1101. if (Neg)
  1102. {
  1103. Digit[Index++] = '-';
  1104. }
  1105. MaxDig = Index;
  1106. while ((ULONG)Index < MinLength)
  1107. {
  1108. *m_Buf++ = ' ';
  1109. Index++;
  1110. }
  1111. while (--MaxDig >= 0)
  1112. {
  1113. *m_Buf++ = Digit[MaxDig];
  1114. }
  1115. }
  1116. void
  1117. MachineInfo::BufferBlanks(ULONG Count)
  1118. {
  1119. // Guarantees that at least one blank is always buffered.
  1120. do
  1121. {
  1122. *m_Buf++ = ' ';
  1123. }
  1124. while (m_Buf < m_BufStart + Count);
  1125. }
  1126. void
  1127. MachineInfo::BufferString(PCSTR String)
  1128. {
  1129. while (*String)
  1130. {
  1131. *m_Buf++ = *String++;
  1132. }
  1133. }
  1134. void
  1135. MachineInfo::PrintMultiPtrTitle(const CHAR* Title, USHORT PtrNum)
  1136. {
  1137. size_t PtrLen = (strlen(FormatAddr64(0)) + 1) * PtrNum;
  1138. size_t TitleLen = strlen(Title);
  1139. if (PtrLen < TitleLen)
  1140. {
  1141. // Extremly rare case so keep it simple while slow
  1142. for (size_t i = 0; i < PtrLen - 1; ++i)
  1143. {
  1144. dprintf("%c", Title[i]);
  1145. }
  1146. dprintf(" ");
  1147. }
  1148. else
  1149. {
  1150. dprintf(Title);
  1151. if (PtrLen > TitleLen)
  1152. {
  1153. char Format[16];
  1154. _snprintf(Format, sizeof(Format) - 1,
  1155. "%% %ds", PtrLen - TitleLen);
  1156. dprintf(Format, "");
  1157. }
  1158. }
  1159. }
  1160. CHAR g_F0[] = "f0";
  1161. CHAR g_F1[] = "f1";
  1162. CHAR g_F2[] = "f2";
  1163. CHAR g_F3[] = "f3";
  1164. CHAR g_F4[] = "f4";
  1165. CHAR g_F5[] = "f5";
  1166. CHAR g_F6[] = "f6";
  1167. CHAR g_F7[] = "f7";
  1168. CHAR g_F8[] = "f8";
  1169. CHAR g_F9[] = "f9";
  1170. CHAR g_F10[] = "f10";
  1171. CHAR g_F11[] = "f11";
  1172. CHAR g_F12[] = "f12";
  1173. CHAR g_F13[] = "f13";
  1174. CHAR g_F14[] = "f14";
  1175. CHAR g_F15[] = "f15";
  1176. CHAR g_F16[] = "f16";
  1177. CHAR g_F17[] = "f17";
  1178. CHAR g_F18[] = "f18";
  1179. CHAR g_F19[] = "f19";
  1180. CHAR g_F20[] = "f20";
  1181. CHAR g_F21[] = "f21";
  1182. CHAR g_F22[] = "f22";
  1183. CHAR g_F23[] = "f23";
  1184. CHAR g_F24[] = "f24";
  1185. CHAR g_F25[] = "f25";
  1186. CHAR g_F26[] = "f26";
  1187. CHAR g_F27[] = "f27";
  1188. CHAR g_F28[] = "f28";
  1189. CHAR g_F29[] = "f29";
  1190. CHAR g_F30[] = "f30";
  1191. CHAR g_F31[] = "f31";
  1192. CHAR g_R0[] = "r0";
  1193. CHAR g_R1[] = "r1";
  1194. CHAR g_R2[] = "r2";
  1195. CHAR g_R3[] = "r3";
  1196. CHAR g_R4[] = "r4";
  1197. CHAR g_R5[] = "r5";
  1198. CHAR g_R6[] = "r6";
  1199. CHAR g_R7[] = "r7";
  1200. CHAR g_R8[] = "r8";
  1201. CHAR g_R9[] = "r9";
  1202. CHAR g_R10[] = "r10";
  1203. CHAR g_R11[] = "r11";
  1204. CHAR g_R12[] = "r12";
  1205. CHAR g_R13[] = "r13";
  1206. CHAR g_R14[] = "r14";
  1207. CHAR g_R15[] = "r15";
  1208. CHAR g_R16[] = "r16";
  1209. CHAR g_R17[] = "r17";
  1210. CHAR g_R18[] = "r18";
  1211. CHAR g_R19[] = "r19";
  1212. CHAR g_R20[] = "r20";
  1213. CHAR g_R21[] = "r21";
  1214. CHAR g_R22[] = "r22";
  1215. CHAR g_R23[] = "r23";
  1216. CHAR g_R24[] = "r24";
  1217. CHAR g_R25[] = "r25";
  1218. CHAR g_R26[] = "r26";
  1219. CHAR g_R27[] = "r27";
  1220. CHAR g_R28[] = "r28";
  1221. CHAR g_R29[] = "r29";
  1222. CHAR g_R30[] = "r30";
  1223. CHAR g_R31[] = "r31";