Windows NT 4.0 source code leak
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.

883 lines
24 KiB

4 years ago
  1. /*++
  2. Copyright (c) 1992 Microsoft Corporation
  3. Module Name:
  4. mach.c
  5. Abstract:
  6. This file contains the MIPS specific code for dealing with
  7. machine dependent issues that invlove registers, instruction
  8. disassembly, function calling and other interesting things.
  9. Author:
  10. Jim Schaad (jimsch)
  11. Environment:
  12. Win32 - User
  13. Notes:
  14. --*/
  15. #include "precomp.h"
  16. extern LPDM_MSG LpDmMsg;
  17. extern CRITICAL_SECTION csContinueQueue;
  18. typedef enum _MIPS_InstrType
  19. {
  20. mips_itype_Imm,
  21. mips_itype_Jump,
  22. mips_itype_Reg,
  23. mips_itype_dont_care
  24. }
  25. MIPS_InstrType;
  26. BOOL
  27. IsRet(
  28. HTHDX hthd,
  29. LPADDR addr
  30. )
  31. {
  32. DWORD instr;
  33. DWORD cBytes;
  34. if (!AddrReadMemory( hthd->hprc, hthd, addr, &instr, 4, &cBytes )) {
  35. return FALSE;
  36. }
  37. return (instr == 0x03e00008); // JR r31
  38. }
  39. void
  40. IsCall (
  41. HTHDX hthd,
  42. LPADDR lpaddr,
  43. LPINT lpf,
  44. BOOL fStepOver
  45. )
  46. /*++
  47. Routine Description:
  48. IsCall
  49. Arguments:
  50. hthd - Supplies the handle to the thread
  51. lpaddr - Supplies the address to be check for a call instruction
  52. lpf - Returns class of instruction:
  53. CALL
  54. BREAKPOINT_INSTRUCTION
  55. SOFTWARE_INTERRUPT
  56. FALSE
  57. Return Value:
  58. None.
  59. --*/
  60. {
  61. ULONG opcode;
  62. ADDR firaddr = *lpaddr;
  63. DWORD length;
  64. ULONGLONG *regArray = &hthd->context.XIntZero;
  65. INSTR disinstr;
  66. BOOL r;
  67. if (hthd->fIsCallDone) {
  68. *lpaddr = hthd->addrIsCall;
  69. *lpf = hthd->iInstrIsCall;
  70. return;
  71. }
  72. /*
  73. * Assume that this is not a call instruction
  74. */
  75. *lpf = FALSE;
  76. /*
  77. * Read in the dword which contains the instruction under
  78. * inspection.
  79. */
  80. r = AddrReadMemory(hthd->hprc,
  81. hthd,
  82. &firaddr,
  83. &disinstr.instruction,
  84. sizeof(DWORD),
  85. &length );
  86. if (!r || length != sizeof(DWORD)) {
  87. goto done;
  88. }
  89. /*
  90. * Assume that this is a jump instruction and get the opcode.
  91. * This is the top 6 bits of the instruction dword.
  92. */
  93. opcode = disinstr.jump_instr.Opcode;
  94. /*
  95. * The first thing to check for is the SPECIAL instruction.
  96. *
  97. * BREAK and JALR
  98. */
  99. if (opcode == 0x00L) {
  100. /*
  101. * There are one opcode in the SPECIAL range which need to
  102. * be treaded specially.
  103. *
  104. * BREAK:
  105. * If the value is 0x16 then this was a "breakpoint" set
  106. * by the debugger. Other values represent different
  107. * exceptions which were programmed in by the code writer.
  108. */
  109. if (disinstr.break_instr.Function == 0x0D) {
  110. if (disinstr.break_instr.Code == 0x16) {
  111. *lpf = INSTR_BREAKPOINT;
  112. } else {
  113. *lpf = INSTR_SOFT_INTERRUPT;
  114. }
  115. } else if (disinstr.special_instr.Funct == 0x09L) {
  116. *lpf = INSTR_IS_CALL;
  117. }
  118. }
  119. /*
  120. * Next item is REGIMM
  121. *
  122. * BLTZAL, BGEZAL, BLTZALL, BGEZALL
  123. */
  124. else if (opcode == 0x01L) {
  125. if (((disinstr.immed_instr.RT & ~0x3) == 0x10) &&
  126. ((((LONGLONG)regArray[disinstr.immed_instr.RS]) >= 0) ==
  127. (BOOL)(disinstr.immed_instr.RT & 0x01))) {
  128. *lpf = INSTR_IS_CALL;
  129. }
  130. }
  131. /*
  132. * Next item is JAL
  133. */
  134. else if (opcode == 0x03) {
  135. *lpf = INSTR_IS_CALL;
  136. }
  137. DPRINT(1, ("(IsCall?) FIR=%08x Type=%s\n", GetAddrOff(firaddr),
  138. (*lpf==INSTR_IS_CALL? "CALL":
  139. (*lpf==INSTR_BREAKPOINT? "BREAKPOINT":
  140. (*lpf==INSTR_SOFT_INTERRUPT? "INTERRUPT":
  141. "NORMAL"))) ) );
  142. done:
  143. if (*lpf==INSTR_IS_CALL) {
  144. lpaddr->addr.off += BP_SIZE + DELAYED_BRANCH_SLOT_SIZE;
  145. hthd->addrIsCall = *lpaddr;
  146. } else if ( *lpf==INSTR_SOFT_INTERRUPT ) {
  147. lpaddr->addr.off += BP_SIZE;
  148. }
  149. hthd->iInstrIsCall = *lpf;
  150. return;
  151. } /* IsCall() */
  152. ULONG
  153. GetNextOffset (
  154. HTHDX hthd,
  155. BOOL fStep
  156. )
  157. /*++
  158. Routine Description:
  159. From a limited disassembly of the instruction pointed
  160. by the FIR register, compute the offset of the next
  161. instruction for either a trace or step operation.
  162. Arguments:
  163. hthd - Supplies the handle to the thread to get the next offset for
  164. fStep - Supplies TRUE for STEP offset and FALSE for trace offset
  165. Return Value:
  166. Offset to place breakpoint at for doing a STEP or TRACE
  167. --*/
  168. {
  169. ULONG returnvalue;
  170. ULONG opcode;
  171. ADDR firaddr;
  172. DWORD length;
  173. ULONGLONG *regArray = &hthd->context.XIntZero;
  174. INSTR disinstr;
  175. BOOL r;
  176. AddrFromHthdx(&firaddr, hthd);
  177. r = AddrReadMemory(hthd->hprc,
  178. hthd,
  179. &firaddr,
  180. &disinstr.instruction,
  181. sizeof(DWORD),
  182. &length);
  183. if (!r || length != sizeof(DWORD)) {
  184. DPRINT(1, ("GetNextOffset: AddrReadMemory failed %x\n", GetAddrOff(firaddr)) );
  185. assert(FALSE);
  186. return 4;
  187. }
  188. opcode = disinstr.jump_instr.Opcode;
  189. returnvalue = firaddr.addr.off + sizeof(ULONG) * 2; /* assume delay slot */
  190. if (disinstr.instruction == 0x0000000c) {
  191. // stepping over a syscall instruction must set the breakpoint
  192. // at the caller's return address, not the inst after the syscall
  193. returnvalue = (DWORD)hthd->context.XIntRa;
  194. }
  195. else
  196. if (opcode == 0x00L /* SPECIAL */
  197. && (disinstr.special_instr.Funct & ~0x01L) == 0x08L) {
  198. /* jr/jalr only */
  199. if (disinstr.special_instr.Funct == 0x08L || !fStep) /* jr or trace */
  200. returnvalue = (DWORD)regArray[disinstr.special_instr.RS];
  201. }
  202. else if (opcode == 0x01L) {
  203. /*
  204. * For BCOND opcode, RT values 0x00 - 0x03, 0x10 - 0x13
  205. * are defined as conditional jumps. A 16-bit relative
  206. * offset is taken if:
  207. *
  208. * (RT is even and (RS) < 0 (0x00 = BLTZ, 0x02 = BLTZL,
  209. * 0x10 = BLTZAL, 0x12 = BLTZALL)
  210. * OR
  211. * RT is odd and (RS) >= 0 (0x01 = BGEZ, 0x03 = BGEZL
  212. * 0x11 = BGEZAL, 0x13 = BGEZALL))
  213. * AND
  214. * (RT is 0x00 to 0x03 (BLTZ BGEZ BLTZL BGEZL non-linking)
  215. * OR
  216. * fStep is FALSE (linking and not stepping over))
  217. */
  218. if (((disinstr.immed_instr.RT & ~0x13) == 0x00) &&
  219. (((LONGLONG)regArray[disinstr.immed_instr.RS] >= 0) ==
  220. (BOOL)(disinstr.immed_instr.RT & 0x01)) &&
  221. (((disinstr.immed_instr.RT & 0x10) == 0x00) || !fStep))
  222. returnvalue = ((LONG)(SHORT)disinstr.immed_instr.Value << 2)
  223. + firaddr.addr.off + sizeof(ULONG);
  224. }
  225. else if ((opcode & ~0x01L) == 0x02) {
  226. /*
  227. * J and JAL opcodes (0x02 and 0x03). Target is
  228. * 26-bit absolute offset using high four bits of the
  229. * instruction location. Return target if J opcode or
  230. * not stepping over JAL.
  231. */
  232. if (opcode == 0x02 || !fStep)
  233. returnvalue = (disinstr.jump_instr.Target << 2)
  234. + (firaddr.addr.off & 0xf0000000);
  235. }
  236. else if ((opcode & ~0x11L) == 0x04) {
  237. /* BEQ, BNE, BEQL, BNEL opcodes (0x04, 0x05, 0x14, 0x15).
  238. * Target is 16-bit relative offset to next instruction.
  239. * Return target if (BEQ or BEQL) and (RS) == (RT),
  240. * or (BNE or BNEL) and (RS) != (RT).
  241. */
  242. if ((BOOL)(opcode & 0x01) ==
  243. (BOOL)(regArray[disinstr.immed_instr.RS] !=
  244. regArray[disinstr.immed_instr.RT]))
  245. returnvalue = ((LONG)(SHORT)disinstr.immed_instr.Value << 2)
  246. + firaddr.addr.off + sizeof(ULONG);
  247. }
  248. else if ((opcode & ~0x11L) == 0x06) {
  249. /* BLEZ, BGTZ, BLEZL, BGTZL opcodes (0x06, 0x07, 0x16, 0x17).
  250. * Target is 16-bit relative offset to next instruction.
  251. * Return target if (BLEZ or BLEZL) and (RS) <= 0,
  252. * or (BGTZ or BGTZL) and (RS) > 0.
  253. */
  254. if ((BOOL)(opcode & 0x01) ==
  255. (BOOL)((LONGLONG)regArray[disinstr.immed_instr.RS] > 0))
  256. returnvalue = ((LONG)(SHORT)disinstr.immed_instr.Value << 2)
  257. + firaddr.addr.off + sizeof(ULONG);
  258. }
  259. else if (opcode == 0x11L
  260. && (disinstr.immed_instr.RS & ~0x04L) == 0x08L
  261. && (disinstr.immed_instr.RT & ~0x03L) == 0x00L) {
  262. /* COP1 opcode (0x11) with (RS) == 0x08 or (RS) == 0x0c and
  263. * (RT) == 0x00 to 0x03, producing BC1F, BC1T, BC1FL, BC1TL
  264. * instructions. Return target if (BC1F or BC1FL) and floating
  265. * point condition is FALSE or if (BC1T or BC1TL) and condition TRUE.
  266. *
  267. * NOTENOTE - JLS -- I don't know that this is correct. rs = 0x3
  268. * will also use CP3
  269. */
  270. // if ((disinstr.immed_instr.RT & 0x01) == GetRegFlagValue(FLAGFPC))
  271. if ((disinstr.immed_instr.RT & 0x01) == ((hthd->context.XFsr>>23)&1)) {
  272. returnvalue = ((LONG)(SHORT)disinstr.immed_instr.Value << 2)
  273. + firaddr.addr.off + sizeof(ULONG);
  274. }
  275. }
  276. else {
  277. returnvalue -= sizeof(ULONG); /* remove delay slot */
  278. }
  279. return returnvalue;
  280. } /* GetNextOffset() */
  281. XOSD
  282. SetupFunctionCall(
  283. LPEXECUTE_OBJECT_DM lpeo,
  284. LPEXECUTE_STRUCT lpes
  285. )
  286. {
  287. /*
  288. * Can only execute functions on the current stopped thread. Therefore
  289. * assert that the current thread is stopped.
  290. */
  291. assert(lpeo->hthd->tstate & ts_stopped);
  292. if (!(lpeo->hthd->tstate & ts_stopped)) {
  293. #ifdef OSDEBUG4
  294. return xosdBadThread;
  295. #else
  296. return xosdInvalidThread;
  297. #endif
  298. }
  299. /*
  300. * Now get the current stack offset.
  301. */
  302. lpeo->addrStack.addr.off = (DWORD)lpeo->hthd->context.XIntSp;
  303. /*
  304. * Now place the return address correctly
  305. */
  306. lpeo->hthd->context.XFir = (LONG)lpeo->addrStart.addr.off;
  307. lpeo->hthd->context.XIntRa = (LONG)lpeo->addrStart.addr.off;
  308. /*
  309. * Set the instruction pointer to the starting addresses
  310. * and write the context back out
  311. */
  312. lpeo->hthd->context.XFir = (LONG)lpeo->addrStart.addr.off;
  313. lpeo->hthd->fContextDirty = TRUE;
  314. return xosdNone;
  315. }
  316. BOOL
  317. CompareStacks(
  318. LPEXECUTE_OBJECT_DM lpeo
  319. )
  320. /*++
  321. Routine Description:
  322. This routine is used to determine if the stack pointers are currect
  323. for terminating function evaluation.
  324. Arguments:
  325. lpeo - Supplies the pointer to the DM Execute Object description
  326. Return Value:
  327. TRUE if the evaluation is to be terminated and FALSE otherwise
  328. --*/
  329. {
  330. if (lpeo->addrStack.addr.off <= (DWORD)lpeo->hthd->context.XIntSp) {
  331. return TRUE;
  332. }
  333. return FALSE;
  334. } /* CompareStacks() */
  335. #ifndef KERNEL
  336. VOID
  337. MakeThreadSuspendItselfHelper(
  338. HTHDX hthd,
  339. FARPROC lpSuspendThread
  340. )
  341. {
  342. //
  343. // set up the args to SuspendThread
  344. //
  345. // GetCurrentThread always returns a magic cookie, safe for any thread.
  346. hthd->context.XIntA0 = (DWORD)GetCurrentThread();
  347. hthd->context.XIntRa = (LONG)PC(hthd);
  348. PC(hthd) = (DWORD)lpSuspendThread;
  349. hthd->fContextDirty = TRUE;
  350. }
  351. #endif
  352. BOOL
  353. ProcessFrameStackWalkNextCmd(
  354. HPRCX hprc,
  355. HTHDX hthd,
  356. PCONTEXT context,
  357. LPVOID pctxPtrs
  358. )
  359. {
  360. return FALSE;
  361. }
  362. DWORD
  363. BranchUnassemble(
  364. void *Memory,
  365. ADDR *Addr,
  366. BOOL *IsBranch,
  367. BOOL *TargetKnown,
  368. BOOL *IsCall,
  369. BOOL *IsTable,
  370. ADDR *Target
  371. )
  372. {
  373. ULONG OpCode;
  374. INSTR *Instr;
  375. UOFF32 Offset;
  376. UOFF32 TargetOffset;
  377. MIPS_InstrType itype = mips_itype_dont_care;
  378. assert( Memory );
  379. assert( IsBranch );
  380. assert( TargetKnown );
  381. assert( IsCall );
  382. assert( Target );
  383. Offset = GetAddrOff( *Addr );
  384. TargetOffset = 0;
  385. *IsBranch = FALSE;
  386. *IsTable = FALSE;
  387. Instr = (INSTR *)Memory;
  388. OpCode = Instr->jump_instr.Opcode;
  389. switch ( OpCode ) {
  390. case 0x00L:
  391. //
  392. // Special
  393. //
  394. switch ( Instr->special_instr.Funct ) {
  395. case 0x09L:
  396. //
  397. // JALR
  398. //
  399. *IsBranch = TRUE;
  400. *IsCall = TRUE;
  401. *TargetKnown = FALSE;
  402. itype = mips_itype_dont_care;
  403. break;
  404. case 0x08L:
  405. //
  406. // JR
  407. //
  408. *IsBranch = TRUE;
  409. *IsCall = FALSE;
  410. *TargetKnown = FALSE;
  411. itype = mips_itype_dont_care;
  412. break;
  413. }
  414. break;
  415. case 0x03:
  416. //
  417. // JAL
  418. //
  419. *IsBranch = TRUE;
  420. *IsCall = TRUE;
  421. *TargetKnown = TRUE;
  422. itype = mips_itype_Jump;
  423. break;
  424. case 0x02:
  425. //
  426. // J
  427. //
  428. *IsBranch = TRUE;
  429. *IsCall = FALSE;
  430. *TargetKnown = TRUE;
  431. itype = mips_itype_Jump;
  432. break;
  433. case 0x10:
  434. case 0x11:
  435. case 0x12:
  436. case 0x13:
  437. //
  438. // BCz
  439. //
  440. *IsBranch = TRUE;
  441. *IsCall = FALSE;
  442. *TargetKnown = TRUE;
  443. itype = mips_itype_Imm;
  444. break;
  445. case 0x04: // BEQ
  446. case 0x14: // BEQL
  447. case 0x05: // BNE
  448. case 0x15: // BNEL
  449. *IsBranch = TRUE;
  450. *IsCall = FALSE;
  451. *TargetKnown = TRUE;
  452. itype = mips_itype_Imm;
  453. break;
  454. case 0x01:
  455. //
  456. // REGIMM
  457. //
  458. itype = mips_itype_Imm;
  459. switch ( Instr->immed_instr.RT ) {
  460. case 0x00: // BLTZ
  461. case 0x01: // BGEZ
  462. case 0x02: // BLTZL
  463. case 0x03: // BGEZL
  464. *IsBranch = TRUE;
  465. *IsCall = FALSE;
  466. *TargetKnown = TRUE;
  467. break;
  468. case 0x10: // BLTZAL
  469. case 0x11: // BGEZAL
  470. case 0x12: // BLTZALL
  471. case 0x13: // BGEZALL
  472. *IsBranch = TRUE;
  473. *IsCall = TRUE;
  474. *TargetKnown = TRUE;
  475. break;
  476. }
  477. break;
  478. case 0x07: // BGTZ ?
  479. case 0x17: // BGTZL ?
  480. case 0x06: // BLEZ ?
  481. case 0x16: // BLEZL ?
  482. if ( Instr->immed_instr.RT == 0x00 ) {
  483. *IsBranch = TRUE;
  484. *IsCall = FALSE;
  485. *TargetKnown = TRUE;
  486. itype = mips_itype_Imm;
  487. }
  488. break;
  489. default:
  490. break;
  491. }
  492. if (*TargetKnown)
  493. {
  494. switch (itype)
  495. {
  496. default:
  497. case (mips_itype_Reg):
  498. case (mips_itype_dont_care):
  499. break;
  500. case (mips_itype_Imm):
  501. TargetOffset
  502. = (UOFF32)(LONG)((SHORT)Instr->immed_instr.Value << 2 )
  503. +
  504. (Offset + sizeof(DWORD));
  505. break;
  506. case (mips_itype_Jump):
  507. TargetOffset = (UOFF32)(Instr->jump_instr.Target << 2 )
  508. |
  509. ((Offset + sizeof(DWORD)) & 0xF0000000);
  510. break;
  511. }
  512. }
  513. AddrInit( Target, 0, 0, TargetOffset, TRUE, TRUE, FALSE, FALSE );
  514. return sizeof( DWORD );
  515. }
  516. /********************************************************
  517. note: "z" refers to a co-processor, with value = 0, 1, 2, or 3
  518. instr opcode rs/rt/imm (Imm)
  519. mnemonic op type mnemonic rs/rt/rd/sa/fn (Reg)
  520. -------- -- ---- -------- --/--/--/--/---
  521. ADD 00 Reg SPECIAL xx/xx/xx/00/20
  522. ADDI 08 Imm ADDI xx/xx/xxxx
  523. ADDIU 09 Imm ADDIU xx/xx/xxxx
  524. ADDU 00 Reg SPECIAL xx/xx/xx/00/21
  525. AND 00 Reg SPECIAL xx/xx/xx/00/24
  526. ANDI 0a Imm ANDI xx/xx/xxxx
  527. * BCzF 1z Imm COPz 08/00/xxxx
  528. * BCzFL 1z Imm COPz 08/02/xxxx
  529. * BCzT 1z Imm COPz 08/01/xxxx
  530. * BCzTL 1z Imm COPz 08/03/xxxx
  531. * BEQ 04 Imm BEQ xx/xx/xxxx
  532. * BEQL 14 Imm BEQL xx/xx/xxxx
  533. * BGEZ 01 Imm REGIMM xx/01/xxxx
  534. * BGEZAL 01 Imm REGIMM xx/11/xxxx
  535. * BGEZALL 01 Imm REGIMM xx/13/xxxx
  536. * BGEZL 01 Imm REGIMM xx/03/xxxx
  537. * BGTZ 07 Imm BGTZ xx/00/xxxx
  538. * BGTZL 17 Imm BGTZL xx/00/xxxx
  539. * BLEZ 06 Imm BLEZ xx/00/xxxx
  540. * BLEZL 16 Imm BLEZL xx/00/xxxx
  541. * BLTZ 01 Imm REGIMM xx/00/xxxx
  542. * BLTZAL 01 Imm REGIMM xx/10/xxxx
  543. * BLTZALL 01 Imm REGIMM xx/12/xxxx
  544. * BLTZL 01 Imm REGIMM xx/02/xxxx
  545. * BNE 05 Imm BNE xx/xx/xxxx
  546. * BNEL 15 Imm BNEL xx/xx/xxxx
  547. BREAK 00 ? SPECIAL xx/xx/xx/xx/0c
  548. CACHE 2f Imm CACHE xx/xx/xxxx
  549. CFCz 1z ? COPz 02/xx/xx/xx/00
  550. ? COPz 1z ? COPz 1x/xx/xxxx
  551. CTCz 1z Imm COPz 06/xx/xx/??/00
  552. DADD 00 Reg SPECIAL xx/xx/xx/00/2c
  553. DADDI 18 Imm DADDI xx/xx/xxxx
  554. DADDIU 19 Imm DADDIU xx/xx/xxxx
  555. DADDU 00 Reg SPECIAL xx/xx/xx/00/2d
  556. DDIV 00 Reg SPECIAL xx/xx/00/00/1e
  557. DDIVU 00 Reg SPECIAL xx/xx/00/00/1f
  558. DIV 00 Reg SPECIAL xx/xx/00/00/1a
  559. DIVU 00 Imm SPECIAL xx/xx/00/00/1b
  560. DMFC0 10 Reg COP0 01/xx/xx/00/00
  561. DMFC0 10 Reg COP0 05/xx/xx/00/00
  562. DMULT 00 Reg SPECIAL xx/xx/00/00/1c
  563. DMULTU 00 Reg SPECIAL xx/xx/00/00/1d
  564. DSLL 00 Reg SPECIAL 00/xx/xx/xx/38
  565. DSLLV 00 Reg SPECIAL 00/xx/xx/xx/14
  566. DSLL32 00 Reg SPECIAL 00/xx/xx/xx/3c
  567. DSRA 00 Reg SPECIAL 00/xx/xx/xx/3b
  568. DSRAV 00 Reg SPECIAL 00/xx/xx/xx/17
  569. DSRA32 00 Reg SPECIAL 00/xx/xx/xx/3f
  570. DSRL 00 Reg SPECIAL 00/xx/xx/xx/3a
  571. DSRLV 00 Reg SPECIAL 00/xx/xx/xx/16
  572. DSRL32 00 Reg SPECIAL 00/xx/xx/xx/3e
  573. DSUB 00 Reg SPECIAL xx/xx/xx/00/2e
  574. DSUBU 00 Reg SPECIAL xx/xx/xx/00/2f
  575. ERET 10 Reg COP0 10/00/00/00/28
  576. * J 02 Jump J xxxxxxx
  577. * JAL 03 Jump JAL xxxxxxx
  578. * JALR 00 Reg SPECIAL xx/00/xx/00/09
  579. * JR 00 Reg SPECIAL xx/00/00/00/08
  580. LB 30 Imm LB xx/xx/xxxx
  581. LBU 34 Imm LBU xx/xx/xxxx
  582. LD 37 Imm LD xx/xx/xxxx
  583. LDCz 3? Imm LDCz xx/xx/xxxx
  584. LDL 1a Imm LDL xx/xx/xxxx
  585. LDR 1b Imm LDR xx/xx/xxxx
  586. LH 21 Imm LH xx/xx/xxxx
  587. LHU 25 Imm LHU xx/xx/xxxx
  588. LL 30 Imm LL xx/xx/xxxx
  589. LLD 34 Imm LLD xx/xx/xxxx
  590. LUI 1f Imm LUI 00/xx/xxxx
  591. LW 23 Imm LW xx/xx/xxxx
  592. LWCz 3z Imm LWCz xx/xx/xxxx
  593. LWL 22 Imm LWL xx/xx/xxxx
  594. LWR 25 Imm LWR xx/xx/xxxx
  595. LWU 2f Imm LWU xx/xx/xxxx
  596. MFC0 10 Reg COP0 00/xx/xx/00/00
  597. MFCz 1z Reg COPz 00/xx/xx/00/00
  598. MFHI 00 Reg SPECIAL 00/00/xx/00/10
  599. MFLO 00 Reg SPECIAL 00/00/xx/00/12
  600. MTC0 10 Reg COP0 04/xx/xx/00/00
  601. MTCz 1z Reg COPz 04/xx/xx/00/00
  602. MTHI 00 Reg SPECIAL xx/00/00/00/11
  603. MTLO 00 Reg SPECIAL xx/00/00/00/13
  604. MULT 00 Reg SPECIAL xx/xx/00/00/18
  605. MULTU 00 Reg SPECIAL xx/xx/00/00/19
  606. NOR 00 Reg SPECIAL xx/xx/xx/00/37
  607. OR 00 Reg SPECIAL xx/xx/xx/00/35
  608. ORI 0d Imm ORI xx/xx/xxxx
  609. SB 28 Imm SB xx/xx/xxxx
  610. SC 38 Imm SC xx/xx/xxxx
  611. SCD 3c Imm SCD xx/xx/xxxx
  612. SCDz 3? Imm SCDz xx/xx/xxxx
  613. SDL 2c Imm SDL xx/xx/xxxx
  614. SDR 2d Imm SDR xx/xx/xxxx
  615. SH 29 Imm SH xx/xx/xxxx
  616. SLL 00 Reg SPECIAL xx/xx/xx/xx/00
  617. SLLV 00 Reg SPECIAL xx/xx/xx/xx/04
  618. SLT 00 Reg SPECIAL xx/xx/xx/xx/2a
  619. SLTI 0a Imm SLTI xx/xx/xxxx
  620. SLTIU 0b Imm SLTIU xx/xx/xxxx
  621. SLTU 00 Reg SPECIAL xx/xx/xx/xx/2b
  622. SRA 00 Reg SPECIAL 00/xx/xx/xx/03
  623. SRAV 00 Reg SPECIAL xx/xx/xx/00/07
  624. SRL 00 Reg SPECIAL 00/xx/xx/xx/02
  625. SRLV 00 Reg SPECIAL xx/xx/xx/00/06
  626. SUB 00 Reg SPECIAL xx/xx/xx/00/22
  627. SUBU 00 Reg SPECIAL xx/xx/xx/00/23
  628. SW 2b Imm SW xx/xx/xxxx
  629. SWCz 3? Imm SWCz xx/xx/xxxx
  630. SWL 2a Reg SWL xx/xx/xxxx
  631. SWR 2d Reg SWR xx/xx/xxxx
  632. SYNC 00 Reg SPECIAL 00/00/00/00/0f
  633. SYSCALL 00 Reg SPECIAL xx/xx/xx/xx/0c
  634. TEQ 00 Reg SPECIAL xx/xx/xx/xx/36
  635. TEQI 01 Imm REGIMM xx/0c/xxxx
  636. TGE 00 Reg SPECIAL xx/xx/xx/xx/30
  637. TGEI 01 Reg REGIMM xx/08/xxxx
  638. TGEIU 01 Imm REGIMM xx/09/xxxx
  639. TGEU 00 Reg SPECIAL xx/xx/xx/xx/31
  640. TLBP 10 Reg COP0 10/00/00/00/08
  641. TLBR 10 Reg COP0 10/00/00/00/01
  642. TLBWI 10 Reg COP0 10/00/00/00/02
  643. TLBWR 10 Reg COP0 10/00/00/00/06
  644. TLT 00 Reg SPECIAL xx/xx/xx/xx/32
  645. TLTI 01 Imm REGIMM xx/0a/xxxx
  646. TLTIU 01 Imm REGIMM xx/0b/xxxx
  647. TLTU 00 Reg SPECIAL xx/xx/xx/xx/33
  648. TNE 00 Reg SPECIAL xx/xx/xx/xx/3c
  649. TNEI 01 Imm REGIMM xx/0e/xxxx
  650. XOR 00 Reg SPECIAL xx/xx/xx/00/26
  651. XORI 0c Imm XORI xx/xx/xxxx
  652. ********************************************************/
  653. BOOL
  654. DecodeSingleStepEvent(
  655. HTHDX hthd,
  656. DEBUG_EVENT *de,
  657. PDWORD eventCode,
  658. PDWORD subClass
  659. )
  660. /*++
  661. Routine Description:
  662. Arguments:
  663. hthd - Supplies thread that has a single step exception pending
  664. de - Supplies the DEBUG_EVENT structure for the exception
  665. eventCode - Returns the remapped debug event id
  666. subClass - Returns the remapped subClass id
  667. Return Value:
  668. TRUE if event was a real single step or was successfully mapped
  669. to a breakpoint. FALSE if a register breakpoint occurred which was
  670. not expected.
  671. --*/
  672. {
  673. return FALSE;
  674. }
  675. BOOL
  676. CoerceContext64To32(
  677. PCONTEXT pContext
  678. )
  679. {
  680. PULONGLONG Src;
  681. PULONG Dst;
  682. ULONG Index;
  683. //
  684. // If the target system is running a kernel with 64-bit addressing
  685. // enabled in user mode, then coerce the 64-bit context to 32-bits.
  686. //
  687. DPRINT(1, ("ConvertContext64To32: ContextFlags == %08x\n", pContext->ContextFlags));
  688. if ((pContext->ContextFlags & CONTEXT_EXTENDED_INTEGER) == CONTEXT_EXTENDED_INTEGER) {
  689. DPRINT(1, ("ConvertContext64To32: Ra == %016Lx\n", pContext->XIntRa));
  690. Src = &pContext->XIntZero;
  691. Dst = &pContext->IntZero;
  692. for (Index = 0; Index < 32; Index += 1) {
  693. *Dst++ = (ULONG)*Src++;
  694. }
  695. pContext->ContextFlags &= ~CONTEXT_EXTENDED_INTEGER;
  696. pContext->ContextFlags |= CONTEXT_INTEGER;
  697. return TRUE;
  698. }
  699. return FALSE;
  700. }
  701. BOOL
  702. CoerceContext32To64 (
  703. PCONTEXT pContext
  704. )
  705. {
  706. PULONG Src;
  707. PULONGLONG Dst;
  708. ULONG Index;
  709. //
  710. // If the target system is running a kernel with 64-bit addressing
  711. // enabled in user mode, then coerce the 32-bit context to 64-bits.
  712. //
  713. DPRINT(1, ("ConvertContext32To64: ContextFlags == %08x\n", pContext->ContextFlags));
  714. if ((pContext->ContextFlags & CONTEXT_EXTENDED_INTEGER) != CONTEXT_EXTENDED_INTEGER) {
  715. DPRINT(1, ("ConvertContext32To64: Ra == %08x\n", pContext->IntRa));
  716. Dst = &pContext->XIntZero;
  717. Src = &pContext->IntZero;
  718. for (Index = 0; Index < 32; Index += 1) {
  719. *Dst++ = (LONG)*Src++;
  720. }
  721. pContext->ContextFlags |= CONTEXT_EXTENDED_INTEGER;
  722. return TRUE;
  723. }
  724. return FALSE;
  725. }