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.

1832 lines
48 KiB

  1. //----------------------------------------------------------------------------
  2. //
  3. // Disassembly portions of ARM machine implementation.
  4. //
  5. // Copyright (C) Microsoft Corporation, 2001-2002.
  6. //
  7. //----------------------------------------------------------------------------
  8. #include "ntsdp.hpp"
  9. #include "arminst.h"
  10. PSTR g_ArmCond[] =
  11. {
  12. "eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",
  13. "hi", "ls", "ge", "lt", "gt", "le", "al", "nv",
  14. };
  15. PSTR g_ArmShift[] =
  16. {
  17. "lsl", "lsr", "asr", "ror", "rrx",
  18. };
  19. enum ARM_DECODE
  20. {
  21. ARMDEC_INVALID,
  22. ARMDEC_ARTH_IMM,
  23. ARMDEC_ARTH_ISHF,
  24. ARMDEC_ARTH_RSHF,
  25. ARMDEC_BI,
  26. ARMDEC_BKPT,
  27. ARMDEC_BXI,
  28. ARMDEC_BXR,
  29. ARMDEC_CDP,
  30. ARMDEC_CLZ,
  31. ARMDEC_CMP_IMM,
  32. ARMDEC_CMP_ISHF,
  33. ARMDEC_CMP_RSHF,
  34. ARMDEC_LDC,
  35. ARMDEC_LDM,
  36. ARMDEC_LDR_IMM,
  37. ARMDEC_LDR_RSHF,
  38. ARMDEC_LDRH_IMM,
  39. ARMDEC_LDRH_REG,
  40. ARMDEC_MCR,
  41. ARMDEC_MCRR,
  42. ARMDEC_MOV_IMM,
  43. ARMDEC_MOV_ISHF,
  44. ARMDEC_MOV_RSHF,
  45. ARMDEC_MRC,
  46. ARMDEC_MRRC,
  47. ARMDEC_MRS,
  48. ARMDEC_MSR_IMM,
  49. ARMDEC_MSR_REG,
  50. ARMDEC_MUL,
  51. ARMDEC_QADD,
  52. ARMDEC_SMLA,
  53. ARMDEC_SMLAL,
  54. ARMDEC_SMUL,
  55. ARMDEC_SWI,
  56. ARMDEC_SWP,
  57. ARMDEC_UNDEF,
  58. };
  59. struct ArmDecode
  60. {
  61. ULONG Mask;
  62. ULONG Encoded;
  63. ARM_DECODE Op;
  64. PSTR Name;
  65. };
  66. #define ARTH_OP(Op, Name) \
  67. 0xffe00000, 0x02000000 | ((Op) << 21), ARMDEC_ARTH_IMM, Name, \
  68. 0xffe00010, 0x00000000 | ((Op) << 21), ARMDEC_ARTH_ISHF, Name, \
  69. 0xffe00090, 0x00000010 | ((Op) << 21), ARMDEC_ARTH_RSHF, Name
  70. #define MOV_OP(Op, Name) \
  71. 0xffef0000, 0x02000000 | ((Op) << 21), ARMDEC_MOV_IMM, Name, \
  72. 0xffef0010, 0x00000000 | ((Op) << 21), ARMDEC_MOV_ISHF, Name, \
  73. 0xffef0090, 0x00000010 | ((Op) << 21), ARMDEC_MOV_RSHF, Name
  74. #define CMP_OP(Op, Name) \
  75. 0xfff0f000, 0x02100000 | ((Op) << 21), ARMDEC_CMP_IMM, Name, \
  76. 0xfff0f010, 0x00100000 | ((Op) << 21), ARMDEC_CMP_ISHF, Name, \
  77. 0xfff0f090, 0x00100010 | ((Op) << 21), ARMDEC_CMP_RSHF, Name
  78. #define LDC_OP(Op, Name) \
  79. 0xfe100000, 0x0c000000 | ((Op) << 20), ARMDEC_LDC, Name, \
  80. 0xfe100000, 0xfc000000 | ((Op) << 20), ARMDEC_LDC, Name ## "2"
  81. #define LDM_OP(Op, Name) \
  82. 0xfe500000, 0x08000000 | ((Op) << 20), ARMDEC_LDM, Name, \
  83. 0xfe700000, 0x08400000 | ((Op) << 20), ARMDEC_LDM, Name
  84. #define LDR_OP(Op, Name) \
  85. 0xfe100000, 0x04000000 | ((Op) << 20), ARMDEC_LDR_IMM, Name, \
  86. 0xfe100000, 0x06000000 | ((Op) << 20), ARMDEC_LDR_RSHF, Name
  87. ArmDecode g_ArmDecode[] =
  88. {
  89. // Undefined instruction space.
  90. 0xf6000010, 0x06000010, ARMDEC_UNDEF, "???",
  91. ARTH_OP(OP_ADC, "adc"),
  92. ARTH_OP(OP_ADD, "add"),
  93. ARTH_OP(OP_AND, "and"),
  94. 0xff000000, 0x0a000000, ARMDEC_BI, "b",
  95. 0xff000000, 0x0b000000, ARMDEC_BI, "bl",
  96. ARTH_OP(OP_BIC, "bic"),
  97. 0xfff000f0, 0x01200070, ARMDEC_BKPT, "bkpt",
  98. 0xfe000000, 0xfa000000, ARMDEC_BXI, "blx",
  99. 0xfffffff0, 0x012fff30, ARMDEC_BXR, "blx",
  100. 0xfffffff0, 0x012fff10, ARMDEC_BXR, "bx",
  101. 0xff000010, 0x0e000000, ARMDEC_CDP, "cdp",
  102. 0xff000010, 0xfe000000, ARMDEC_CDP, "cdp2",
  103. 0xffff0ff0, 0x016f0f10, ARMDEC_CLZ, "clz",
  104. CMP_OP(OP_CMN, "cmn"),
  105. CMP_OP(OP_CMP, "cmp"),
  106. ARTH_OP(OP_EOR, "eor"),
  107. LDC_OP(1, "ldc"),
  108. LDM_OP(1, "ldm"),
  109. LDR_OP(1, "ldr"),
  110. 0xfe5000f0, 0x004000d0, ARMDEC_LDRH_IMM, "ldr",
  111. 0xfe500ff0, 0x000000d0, ARMDEC_LDRH_REG, "ldr",
  112. 0xfe5000f0, 0x005000b0, ARMDEC_LDRH_IMM, "ldr",
  113. 0xfe500ff0, 0x001000b0, ARMDEC_LDRH_REG, "ldr",
  114. 0xfe5000f0, 0x005000d0, ARMDEC_LDRH_IMM, "ldr",
  115. 0xfe500ff0, 0x001000d0, ARMDEC_LDRH_REG, "ldr",
  116. 0xfe5000f0, 0x005000f0, ARMDEC_LDRH_IMM, "ldr",
  117. 0xfe500ff0, 0x001000f0, ARMDEC_LDRH_REG, "ldr",
  118. 0xff100010, 0x0e000010, ARMDEC_MCR, "mcr",
  119. 0xff100010, 0xfe000010, ARMDEC_MCR, "mcr2",
  120. 0xfff00000, 0x0e400000, ARMDEC_MCRR, "mcrr",
  121. 0xffe000f0, 0x00200090, ARMDEC_MUL, "mla",
  122. MOV_OP(OP_MOV, "mov"),
  123. 0xff100010, 0x0e100010, ARMDEC_MRC, "mrc",
  124. 0xff100010, 0xfe100010, ARMDEC_MRC, "mrc2",
  125. 0xfff00000, 0x0e500000, ARMDEC_MRRC, "mrrc",
  126. 0xffbf0fff, 0x010f0000, ARMDEC_MRS, "mrs",
  127. 0xffb0f000, 0x0320f000, ARMDEC_MSR_IMM, "msr",
  128. 0xffb0f0f0, 0x0120f000, ARMDEC_MSR_REG, "msr",
  129. 0xffe0f0f0, 0x00000090, ARMDEC_MUL, "mul",
  130. MOV_OP(OP_MVN, "mvn"),
  131. ARTH_OP(OP_ORR, "orr"),
  132. ARTH_OP(OP_RSB, "rsb"),
  133. ARTH_OP(OP_RSC, "rsc"),
  134. ARTH_OP(OP_SBC, "sbc"),
  135. 0xfff00090, 0x01000080, ARMDEC_SMLA, "smla",
  136. 0xfff00090, 0x01400080, ARMDEC_SMLAL, "smlal",
  137. 0xffe000f0, 0x00e00090, ARMDEC_MUL, "smlal",
  138. 0xfff000b0, 0x01200080, ARMDEC_SMLA, "smlaw",
  139. 0xfff0f090, 0x01600080, ARMDEC_SMUL, "smulb",
  140. 0xffe000f0, 0x00c00090, ARMDEC_MUL, "smull",
  141. 0xfff0f0b0, 0x016000a0, ARMDEC_SMUL, "smulw",
  142. 0xff70f000, 0xf750f000, ARMDEC_LDR_IMM, "pld",
  143. 0xff70f000, 0xf550f000, ARMDEC_LDR_RSHF, "pld",
  144. 0xfff00ff0, 0x01000050, ARMDEC_QADD, "qadd",
  145. 0xfff00ff0, 0x01400050, ARMDEC_QADD, "qdadd",
  146. 0xfff00ff0, 0x01600050, ARMDEC_QADD, "qdsub",
  147. 0xfff00ff0, 0x01200050, ARMDEC_QADD, "qsub",
  148. LDC_OP(0, "stc"),
  149. LDM_OP(0, "stm"),
  150. LDR_OP(0, "str"),
  151. 0xfe5000f0, 0x004000f0, ARMDEC_LDRH_IMM, "str",
  152. 0xfe500ff0, 0x000000f0, ARMDEC_LDRH_REG, "str",
  153. 0xfe5000f0, 0x004000b0, ARMDEC_LDRH_IMM, "str",
  154. 0xfe500ff0, 0x000000b0, ARMDEC_LDRH_REG, "str",
  155. ARTH_OP(OP_SUB, "sub"),
  156. 0xff000000, 0x0f000000, ARMDEC_SWI, "swi",
  157. 0xffb00ff0, 0x01000090, ARMDEC_SWP, "swp",
  158. CMP_OP(OP_TEQ, "teq"),
  159. CMP_OP(OP_TST, "tst"),
  160. 0xffe000f0, 0x00a00090, ARMDEC_MUL, "umlal",
  161. 0xffe000f0, 0x00800090, ARMDEC_MUL, "umull",
  162. // End marker.
  163. 0x00000000, 0x00000000, ARMDEC_INVALID, NULL,
  164. };
  165. BOOL
  166. ArmMachineInfo::Disassemble(ProcessInfo* Process,
  167. PADDR Addr, PSTR Buffer, BOOL EffAddr)
  168. {
  169. ARMI Instr;
  170. m_DisStart = *Addr;
  171. ADDRFLAT(&m_EffAddr, 0);
  172. m_EaSize = 0;
  173. m_BufStart = m_Buf = Buffer;
  174. sprintAddr(&m_Buf, Addr);
  175. *m_Buf++ = ' ';
  176. if (m_Target->
  177. ReadAllVirtual(Process, Flat(*Addr), &Instr, sizeof(Instr)) != S_OK)
  178. {
  179. AddrAdd(Addr, 4);
  180. if (!(g_AsmOptions & DEBUG_ASMOPT_NO_CODE_BYTES))
  181. {
  182. BufferString("???????? ");
  183. }
  184. BufferString("???\n");
  185. *m_Buf = 0;
  186. return FALSE;
  187. }
  188. m_ArgCol = 19;
  189. if (!(g_AsmOptions & DEBUG_ASMOPT_NO_CODE_BYTES))
  190. {
  191. BufferHex(Instr.instruction, 8, FALSE);
  192. *m_Buf++ = ' ';
  193. *m_Buf++ = ' ';
  194. m_ArgCol += 10;
  195. }
  196. //
  197. // All of the condition bits are AND'ed before being
  198. // used to search the decode table. This allows simple
  199. // matching and filtering for unconditional instructions.
  200. //
  201. ULONG InstrBits = Instr.instruction;
  202. if ((InstrBits & COND_MASK) != COND_NV)
  203. {
  204. InstrBits &= ~COND_MASK;
  205. }
  206. ArmDecode* Decode = g_ArmDecode;
  207. while (Decode->Mask)
  208. {
  209. if ((InstrBits & Decode->Mask) == Decode->Encoded)
  210. {
  211. break;
  212. }
  213. Decode++;
  214. }
  215. if (!Decode->Mask || Decode->Op == ARMDEC_UNDEF)
  216. {
  217. BufferString("???");
  218. }
  219. else
  220. {
  221. BufferString(Decode->Name);
  222. BufferCond(Instr.instruction & COND_MASK);
  223. switch(Decode->Op)
  224. {
  225. case ARMDEC_ARTH_IMM:
  226. case ARMDEC_ARTH_ISHF:
  227. case ARMDEC_ARTH_RSHF:
  228. DisArmArth(Decode, &Instr);
  229. break;
  230. case ARMDEC_BI:
  231. DisArmBi(Decode, &Instr);
  232. break;
  233. case ARMDEC_BKPT:
  234. DisArmBkpt(Decode, &Instr);
  235. break;
  236. case ARMDEC_BXI:
  237. DisArmBxi(Decode, &Instr);
  238. break;
  239. case ARMDEC_BXR:
  240. DisArmBxr(Decode, &Instr);
  241. break;
  242. case ARMDEC_CDP:
  243. DisArmCdp(Decode, &Instr);
  244. break;
  245. case ARMDEC_CLZ:
  246. DisArmClz(Decode, &Instr);
  247. break;
  248. case ARMDEC_CMP_IMM:
  249. case ARMDEC_CMP_ISHF:
  250. case ARMDEC_CMP_RSHF:
  251. DisArmCmp(Decode, &Instr);
  252. break;
  253. case ARMDEC_LDC:
  254. DisArmLdc(Decode, &Instr);
  255. break;
  256. case ARMDEC_LDM:
  257. DisArmLdm(Decode, &Instr);
  258. break;
  259. case ARMDEC_LDR_IMM:
  260. case ARMDEC_LDR_RSHF:
  261. DisArmLdr(Decode, &Instr);
  262. break;
  263. case ARMDEC_LDRH_IMM:
  264. case ARMDEC_LDRH_REG:
  265. DisArmLdrh(Decode, &Instr);
  266. break;
  267. case ARMDEC_MCR:
  268. case ARMDEC_MRC:
  269. DisArmMcr(Decode, &Instr);
  270. break;
  271. case ARMDEC_MCRR:
  272. case ARMDEC_MRRC:
  273. DisArmMcrr(Decode, &Instr);
  274. break;
  275. case ARMDEC_MOV_IMM:
  276. case ARMDEC_MOV_ISHF:
  277. case ARMDEC_MOV_RSHF:
  278. DisArmMov(Decode, &Instr);
  279. break;
  280. case ARMDEC_MRS:
  281. DisArmMrs(Decode, &Instr);
  282. break;
  283. case ARMDEC_MSR_IMM:
  284. case ARMDEC_MSR_REG:
  285. DisArmMsr(Decode, &Instr);
  286. break;
  287. case ARMDEC_MUL:
  288. DisArmMul(Decode, &Instr);
  289. break;
  290. case ARMDEC_QADD:
  291. DisArmQadd(Decode, &Instr);
  292. break;
  293. case ARMDEC_SMLA:
  294. DisArmSmla(Decode, &Instr);
  295. break;
  296. case ARMDEC_SMLAL:
  297. DisArmSmlal(Decode, &Instr);
  298. break;
  299. case ARMDEC_SMUL:
  300. DisArmSmul(Decode, &Instr);
  301. break;
  302. case ARMDEC_SWI:
  303. DisArmSwi(Decode, &Instr);
  304. break;
  305. case ARMDEC_SWP:
  306. DisArmSwp(Decode, &Instr);
  307. break;
  308. default:
  309. BufferString("** ARM diassembly bug **");
  310. break;
  311. }
  312. }
  313. *m_Buf++ = '\n';
  314. *m_Buf = 0;
  315. AddrAdd(Addr, 4);
  316. return TRUE;
  317. }
  318. void
  319. ArmMachineInfo::DisArmArth(ArmDecode* Decode, PARMI Instr)
  320. {
  321. if (Instr->dataproc.s)
  322. {
  323. *m_Buf++ = 's';
  324. }
  325. BufferBlanks(m_ArgCol);
  326. BufferRegName(Instr->dataproc.rd);
  327. *m_Buf++ = ',';
  328. *m_Buf++ = ' ';
  329. BufferRegName(Instr->dataproc.rn);
  330. BufferArmDpArg(Instr);
  331. }
  332. void
  333. ArmMachineInfo::DisArmBi(ArmDecode* Decode, PARMI Instr)
  334. {
  335. BufferBlanks(m_ArgCol);
  336. BufferEffectiveAddress(Flat(m_DisStart) + 8 +
  337. ((LONG)Instr->bl.offset << 2), 4);
  338. }
  339. void
  340. ArmMachineInfo::DisArmBkpt(ArmDecode* Decode, PARMI Instr)
  341. {
  342. BufferBlanks(m_ArgCol);
  343. *m_Buf++ = '#';
  344. *m_Buf++ = '0';
  345. *m_Buf++ = 'x';
  346. BufferHex((Instr->bkpt.immed2 << 4) || Instr->bkpt.immed1,
  347. 4, FALSE);
  348. }
  349. void
  350. ArmMachineInfo::DisArmBxi(ArmDecode* Decode, PARMI Instr)
  351. {
  352. BufferBlanks(m_ArgCol);
  353. BufferEffectiveAddress(Flat(m_DisStart) + 8 +
  354. ((LONG)Instr->blxi.offset << 2) +
  355. (Instr->blxi.h << 1), 4);
  356. }
  357. void
  358. ArmMachineInfo::DisArmBxr(ArmDecode* Decode, PARMI Instr)
  359. {
  360. BufferBlanks(m_ArgCol);
  361. BufferRegName(Instr->bx.rn);
  362. }
  363. void
  364. ArmMachineInfo::DisArmCdp(ArmDecode* Decode, PARMI Instr)
  365. {
  366. BufferBlanks(m_ArgCol);
  367. *m_Buf++ = 'p';
  368. BufferInt(Instr->cpdo.cpn, 0, FALSE);
  369. *m_Buf++ = ',';
  370. *m_Buf++ = ' ';
  371. BufferInt(Instr->cpdo.cpop, 0, FALSE);
  372. *m_Buf++ = ',';
  373. *m_Buf++ = ' ';
  374. *m_Buf++ = 'c';
  375. BufferInt(Instr->cpdo.crd, 0, FALSE);
  376. *m_Buf++ = ',';
  377. *m_Buf++ = ' ';
  378. *m_Buf++ = 'c';
  379. BufferInt(Instr->cpdo.crn, 0, FALSE);
  380. *m_Buf++ = ',';
  381. *m_Buf++ = ' ';
  382. *m_Buf++ = 'c';
  383. BufferInt(Instr->cpdo.crm, 0, FALSE);
  384. *m_Buf++ = ',';
  385. *m_Buf++ = ' ';
  386. BufferInt(Instr->cpdo.cp, 0, FALSE);
  387. }
  388. void
  389. ArmMachineInfo::DisArmClz(ArmDecode* Decode, PARMI Instr)
  390. {
  391. BufferBlanks(m_ArgCol);
  392. BufferRegName(Instr->clz.rd);
  393. *m_Buf++ = ',';
  394. *m_Buf++ = ' ';
  395. BufferRegName(Instr->clz.rm);
  396. }
  397. void
  398. ArmMachineInfo::DisArmCmp(ArmDecode* Decode, PARMI Instr)
  399. {
  400. BufferBlanks(m_ArgCol);
  401. BufferRegName(Instr->dataproc.rn);
  402. BufferArmDpArg(Instr);
  403. }
  404. void
  405. ArmMachineInfo::DisArmLdc(ArmDecode* Decode, PARMI Instr)
  406. {
  407. if (Instr->cpdt.n)
  408. {
  409. *m_Buf++ = 'l';
  410. }
  411. BufferBlanks(m_ArgCol);
  412. *m_Buf++ = 'p';
  413. BufferInt(Instr->cpdt.cpn, 0, FALSE);
  414. *m_Buf++ = ',';
  415. *m_Buf++ = ' ';
  416. *m_Buf++ = 'c';
  417. BufferInt(Instr->cpdt.crd, 0, FALSE);
  418. *m_Buf++ = ',';
  419. *m_Buf++ = ' ';
  420. *m_Buf++ = '[';
  421. BufferRegName(Instr->cpdt.rn);
  422. if (!Instr->cpdt.p)
  423. {
  424. *m_Buf++ = ']';
  425. }
  426. if (Instr->cpdt.offset)
  427. {
  428. *m_Buf++ = ',';
  429. *m_Buf++ = ' ';
  430. *m_Buf++ = '#';
  431. *m_Buf++ = '0';
  432. *m_Buf++ = 'x';
  433. BufferHex(Instr->cpdt.offset, 2, FALSE);
  434. }
  435. if (Instr->cpdt.p)
  436. {
  437. *m_Buf++ = ']';
  438. }
  439. if (Instr->cpdt.w)
  440. {
  441. *m_Buf++ = '!';
  442. }
  443. }
  444. void
  445. ArmMachineInfo::DisArmLdm(ArmDecode* Decode, PARMI Instr)
  446. {
  447. ULONG i;
  448. BOOL Separate = FALSE;
  449. if (Instr->ldm.rn == ARM_SP)
  450. {
  451. *m_Buf++ = Instr->ldm.p ? 'e' : 'f';
  452. *m_Buf++ = Instr->ldm.u ? 'd' : 'a';
  453. }
  454. else
  455. {
  456. *m_Buf++ = Instr->ldm.u ? 'i' : 'd';
  457. *m_Buf++ = Instr->ldm.p ? 'b' : 'a';
  458. }
  459. BufferBlanks(m_ArgCol);
  460. BufferRegName(Instr->ldm.rn);
  461. if (Instr->ldm.w)
  462. {
  463. *m_Buf++ = '!';
  464. }
  465. *m_Buf++ = ',';
  466. *m_Buf++ = ' ';
  467. *m_Buf++ = '{';
  468. for (i = 0; i < 16; i++)
  469. {
  470. if (Instr->ldm.reglist & (1 << i))
  471. {
  472. ULONG Len = 0;
  473. if (Separate)
  474. {
  475. *m_Buf++ = ',';
  476. *m_Buf++ = ' ';
  477. }
  478. else
  479. {
  480. Separate = TRUE;
  481. }
  482. BufferRegName(i);
  483. do
  484. {
  485. Len++;
  486. i++;
  487. } while (i < 16 && (Instr->ldm.reglist & (1 << i)));
  488. if (Len > 1)
  489. {
  490. if (Len > 2)
  491. {
  492. *m_Buf++ = ' ';
  493. *m_Buf++ = '-';
  494. }
  495. else
  496. {
  497. *m_Buf++ = ',';
  498. }
  499. *m_Buf++ = ' ';
  500. BufferRegName(i - 1);
  501. }
  502. }
  503. }
  504. *m_Buf++ = '}';
  505. if (Instr->ldm.s)
  506. {
  507. *m_Buf++ = '^';
  508. }
  509. }
  510. void
  511. ArmMachineInfo::DisArmLdr(ArmDecode* Decode, PARMI Instr)
  512. {
  513. if (Instr->ldr.b)
  514. {
  515. *m_Buf++ = 'b';
  516. }
  517. if (!Instr->ldr.p && Instr->ldr.w)
  518. {
  519. *m_Buf++ = 't';
  520. }
  521. BufferBlanks(m_ArgCol);
  522. BufferRegName(Instr->ldr.rd);
  523. *m_Buf++ = ',';
  524. *m_Buf++ = ' ';
  525. *m_Buf++ = '[';
  526. BufferRegName(Instr->ldr.rn);
  527. if (Instr->ldr.p)
  528. {
  529. if (Instr->ldr.offset)
  530. {
  531. *m_Buf++ = ',';
  532. *m_Buf++ = ' ';
  533. if (!Instr->ldr.i)
  534. {
  535. *m_Buf++ = '#';
  536. if (!Instr->ldr.u)
  537. {
  538. *m_Buf++ = '-';
  539. }
  540. *m_Buf++ = '0';
  541. *m_Buf++ = 'x';
  542. BufferHex(Instr->ldr.offset, 3, FALSE);
  543. }
  544. else
  545. {
  546. *m_Buf++ = Instr->ldr.u ? '+' : '-';
  547. BufferArmShift(Instr->ldr.offset);
  548. }
  549. }
  550. *m_Buf++ = ']';
  551. }
  552. else
  553. {
  554. *m_Buf++ = ']';
  555. *m_Buf++ = ',';
  556. *m_Buf++ = ' ';
  557. if (!Instr->ldr.i)
  558. {
  559. *m_Buf++ = '#';
  560. if (!Instr->ldr.u)
  561. {
  562. *m_Buf++ = '-';
  563. }
  564. *m_Buf++ = '0';
  565. *m_Buf++ = 'x';
  566. BufferHex(Instr->ldr.offset, 3, FALSE);
  567. }
  568. else
  569. {
  570. *m_Buf++ = Instr->ldr.u ? '+' : '-';
  571. BufferArmShift(Instr->ldr.offset);
  572. }
  573. }
  574. if (Instr->ldr.w)
  575. {
  576. *m_Buf++ = '!';
  577. }
  578. }
  579. void
  580. ArmMachineInfo::DisArmLdrh(ArmDecode* Decode, PARMI Instr)
  581. {
  582. if (!Instr->miscdt.l && Instr->miscdt.s)
  583. {
  584. *m_Buf++ = 'd';
  585. }
  586. else
  587. {
  588. if (Instr->miscdt.s)
  589. {
  590. *m_Buf++ = 's';
  591. }
  592. *m_Buf++ = Instr->miscdt.h ? 'h' : 'b';
  593. }
  594. BufferBlanks(m_ArgCol);
  595. BufferRegName(Instr->miscdt.rd);
  596. *m_Buf++ = ',';
  597. *m_Buf++ = ' ';
  598. *m_Buf++ = '[';
  599. BufferRegName(Instr->miscdt.rn);
  600. if (!Instr->miscdt.p)
  601. {
  602. *m_Buf++ = ']';
  603. }
  604. if (Instr->miscdt.i)
  605. {
  606. ULONG Offset =
  607. (Instr->miscdt.operand2 << 4) | Instr->miscdt.operand1;
  608. if (Offset)
  609. {
  610. *m_Buf++ = ',';
  611. *m_Buf++ = ' ';
  612. *m_Buf++ = '#';
  613. if (!Instr->miscdt.u)
  614. {
  615. *m_Buf++ = '-';
  616. }
  617. *m_Buf++ = '0';
  618. *m_Buf++ = 'x';
  619. BufferHex(Offset, 2, FALSE);
  620. }
  621. }
  622. else
  623. {
  624. *m_Buf++ = ',';
  625. *m_Buf++ = ' ';
  626. *m_Buf++ = Instr->miscdt.u ? '+' : '-';
  627. BufferRegName(Instr->miscdt.operand1);
  628. }
  629. if (Instr->miscdt.p)
  630. {
  631. *m_Buf++ = ']';
  632. if (Instr->miscdt.w)
  633. {
  634. *m_Buf++ = '!';
  635. }
  636. }
  637. }
  638. void
  639. ArmMachineInfo::DisArmMcr(ArmDecode* Decode, PARMI Instr)
  640. {
  641. BufferBlanks(m_ArgCol);
  642. *m_Buf++ = 'p';
  643. BufferInt(Instr->cprt.cpn, 0, FALSE);
  644. *m_Buf++ = ',';
  645. *m_Buf++ = ' ';
  646. BufferInt(Instr->cprt.cpop, 0, FALSE);
  647. *m_Buf++ = ',';
  648. *m_Buf++ = ' ';
  649. BufferRegName(Instr->cprt.rd);
  650. *m_Buf++ = ',';
  651. *m_Buf++ = ' ';
  652. *m_Buf++ = 'c';
  653. BufferInt(Instr->cprt.crn, 0, FALSE);
  654. *m_Buf++ = ',';
  655. *m_Buf++ = ' ';
  656. *m_Buf++ = 'c';
  657. BufferInt(Instr->cprt.crm, 0, FALSE);
  658. if (Instr->cprt.cp)
  659. {
  660. *m_Buf++ = ',';
  661. *m_Buf++ = ' ';
  662. BufferInt(Instr->cprt.cp, 0, FALSE);
  663. }
  664. }
  665. void
  666. ArmMachineInfo::DisArmMcrr(ArmDecode* Decode, PARMI Instr)
  667. {
  668. BufferBlanks(m_ArgCol);
  669. *m_Buf++ = 'p';
  670. BufferInt(Instr->mcrr.cpn, 0, FALSE);
  671. *m_Buf++ = ',';
  672. *m_Buf++ = ' ';
  673. BufferInt(Instr->mcrr.cpop, 0, FALSE);
  674. *m_Buf++ = ',';
  675. *m_Buf++ = ' ';
  676. BufferRegName(Instr->mcrr.rd);
  677. *m_Buf++ = ',';
  678. *m_Buf++ = ' ';
  679. BufferInt(Instr->mcrr.rn, 0, FALSE);
  680. *m_Buf++ = ',';
  681. *m_Buf++ = ' ';
  682. *m_Buf++ = 'c';
  683. BufferInt(Instr->mcrr.crm, 0, FALSE);
  684. }
  685. void
  686. ArmMachineInfo::DisArmMov(ArmDecode* Decode, PARMI Instr)
  687. {
  688. if (Instr->dataproc.s)
  689. {
  690. *m_Buf++ = 's';
  691. }
  692. BufferBlanks(m_ArgCol);
  693. BufferRegName(Instr->dataproc.rd);
  694. BufferArmDpArg(Instr);
  695. }
  696. void
  697. ArmMachineInfo::DisArmMrs(ArmDecode* Decode, PARMI Instr)
  698. {
  699. BufferBlanks(m_ArgCol);
  700. BufferRegName(Instr->dpmrs.rd);
  701. *m_Buf++ = ',';
  702. *m_Buf++ = ' ';
  703. BufferString("psr");
  704. }
  705. void
  706. ArmMachineInfo::DisArmMsr(ArmDecode* Decode, PARMI Instr)
  707. {
  708. BufferBlanks(m_ArgCol);
  709. BufferString("psr_");
  710. if (Instr->dpmsr.fc)
  711. {
  712. *m_Buf++ = 'c';
  713. }
  714. if (Instr->dpmsr.fx)
  715. {
  716. *m_Buf++ = 'x';
  717. }
  718. if (Instr->dpmsr.fs)
  719. {
  720. *m_Buf++ = 's';
  721. }
  722. if (Instr->dpmsr.ff)
  723. {
  724. *m_Buf++ = 'f';
  725. }
  726. if (Instr->dpmsr.i)
  727. {
  728. BufferArmDpArg(Instr);
  729. }
  730. else
  731. {
  732. *m_Buf++ = ',';
  733. *m_Buf++ = ' ';
  734. BufferRegName(Instr->dpmsr.operand & 0xf);
  735. }
  736. }
  737. void
  738. ArmMachineInfo::DisArmMul(ArmDecode* Decode, PARMI Instr)
  739. {
  740. if (Instr->mul.s)
  741. {
  742. *m_Buf++ = 's';
  743. }
  744. BufferBlanks(m_ArgCol);
  745. if (Instr->mul.lng)
  746. {
  747. BufferRegName(Instr->mul.rn);
  748. *m_Buf++ = ',';
  749. *m_Buf++ = ' ';
  750. }
  751. BufferRegName(Instr->mul.rd);
  752. *m_Buf++ = ',';
  753. *m_Buf++ = ' ';
  754. BufferRegName(Instr->mul.rm);
  755. *m_Buf++ = ',';
  756. *m_Buf++ = ' ';
  757. BufferRegName(Instr->mul.rs);
  758. if (Instr->mul.a && !Instr->mul.lng)
  759. {
  760. *m_Buf++ = ',';
  761. *m_Buf++ = ' ';
  762. BufferRegName(Instr->mul.rn);
  763. }
  764. }
  765. void
  766. ArmMachineInfo::DisArmQadd(ArmDecode* Decode, PARMI Instr)
  767. {
  768. BufferBlanks(m_ArgCol);
  769. BufferRegName(Instr->qadd.rd);
  770. *m_Buf++ = ',';
  771. *m_Buf++ = ' ';
  772. BufferRegName(Instr->qadd.rm);
  773. *m_Buf++ = ',';
  774. *m_Buf++ = ' ';
  775. BufferRegName(Instr->qadd.rn);
  776. }
  777. void
  778. ArmMachineInfo::DisArmSmla(ArmDecode* Decode, PARMI Instr)
  779. {
  780. if (strcmp(Decode->Name, "smlaw"))
  781. {
  782. *m_Buf++ = Instr->smla.x ? 't' : 'b';
  783. }
  784. *m_Buf++ = Instr->smla.y ? 't' : 'b';
  785. BufferBlanks(m_ArgCol);
  786. BufferRegName(Instr->smla.rd);
  787. *m_Buf++ = ',';
  788. *m_Buf++ = ' ';
  789. BufferRegName(Instr->smla.rm);
  790. *m_Buf++ = ',';
  791. *m_Buf++ = ' ';
  792. BufferRegName(Instr->smla.rs);
  793. *m_Buf++ = ',';
  794. *m_Buf++ = ' ';
  795. BufferRegName(Instr->smla.rn);
  796. }
  797. void
  798. ArmMachineInfo::DisArmSmlal(ArmDecode* Decode, PARMI Instr)
  799. {
  800. *m_Buf++ = Instr->smla.x ? 't' : 'b';
  801. *m_Buf++ = Instr->smla.y ? 't' : 'b';
  802. BufferBlanks(m_ArgCol);
  803. BufferRegName(Instr->smlal.rdlo);
  804. *m_Buf++ = ',';
  805. *m_Buf++ = ' ';
  806. BufferRegName(Instr->smlal.rdhi);
  807. *m_Buf++ = ',';
  808. *m_Buf++ = ' ';
  809. BufferRegName(Instr->smlal.rm);
  810. *m_Buf++ = ',';
  811. *m_Buf++ = ' ';
  812. BufferRegName(Instr->smlal.rs);
  813. }
  814. void
  815. ArmMachineInfo::DisArmSmul(ArmDecode* Decode, PARMI Instr)
  816. {
  817. if (strcmp(Decode->Name, "smulw"))
  818. {
  819. *m_Buf++ = Instr->smul.x ? 't' : 'b';
  820. }
  821. *m_Buf++ = Instr->smul.y ? 't' : 'b';
  822. BufferBlanks(m_ArgCol);
  823. BufferRegName(Instr->smul.rd);
  824. *m_Buf++ = ',';
  825. *m_Buf++ = ' ';
  826. BufferRegName(Instr->smul.rm);
  827. *m_Buf++ = ',';
  828. *m_Buf++ = ' ';
  829. BufferRegName(Instr->smlal.rs);
  830. }
  831. void
  832. ArmMachineInfo::DisArmSwi(ArmDecode* Decode, PARMI Instr)
  833. {
  834. BufferBlanks(m_ArgCol);
  835. *m_Buf++ = '#';
  836. *m_Buf++ = '0';
  837. *m_Buf++ = 'x';
  838. BufferHex(Instr->swi.comment, 6, FALSE);
  839. }
  840. void
  841. ArmMachineInfo::DisArmSwp(ArmDecode* Decode, PARMI Instr)
  842. {
  843. if (Instr->swp.b)
  844. {
  845. *m_Buf++ = 'b';
  846. }
  847. BufferBlanks(m_ArgCol);
  848. BufferRegName(Instr->swp.rd);
  849. *m_Buf++ = ',';
  850. *m_Buf++ = ' ';
  851. BufferRegName(Instr->swp.rm);
  852. *m_Buf++ = ',';
  853. *m_Buf++ = ' ';
  854. *m_Buf++ = '[';
  855. BufferRegName(Instr->swp.rn);
  856. *m_Buf++ = ']';
  857. }
  858. void
  859. ArmMachineInfo::BufferEffectiveAddress(ULONG64 Offset, ULONG Size)
  860. {
  861. CHAR Symbol[MAX_SYMBOL_LEN];
  862. ULONG64 Disp;
  863. GetSymbol(Offset, Symbol, sizeof(Symbol), &Disp);
  864. if (Symbol[0])
  865. {
  866. BufferString(Symbol);
  867. if (Disp)
  868. {
  869. *m_Buf++ = '+';
  870. *m_Buf++ = '0';
  871. *m_Buf++ = 'x';
  872. BufferHex(Disp, 8, TRUE);
  873. }
  874. *m_Buf++ = ' ';
  875. *m_Buf++ = '(';
  876. BufferHex(Offset, 8, FALSE);
  877. *m_Buf++ = ')';
  878. }
  879. else
  880. {
  881. BufferHex(Offset, 8, FALSE);
  882. }
  883. // Save EA.
  884. ADDRFLAT(&m_EffAddr, Offset);
  885. m_EaSize = Size;
  886. }
  887. void
  888. ArmMachineInfo::BufferArmDpArg(PARMI Instr)
  889. {
  890. *m_Buf++ = ',';
  891. *m_Buf++ = ' ';
  892. if (Instr->dataproc.bits & 1)
  893. {
  894. ULONG64 Immed;
  895. *m_Buf++ = '#';
  896. *m_Buf++ = '0';
  897. *m_Buf++ = 'x';
  898. // The immediate forms takes the low 8 bits as an unsigned
  899. // value and rotates it right by twice the upper 4 bits to
  900. // form a 32-bit immediate.
  901. // Emulate the rotate by shifting a 64-bit value and piecing
  902. // together the appropriate parts.
  903. Immed = (((ULONG64)(Instr->dataproc.operand2 & 0xff)) << 32) >>
  904. ((Instr->dataproc.operand2 >> 7) & 0x1e);
  905. BufferHex((ULONG)((Immed & 0xffffffff) | (Immed >> 32)), 8, FALSE);
  906. }
  907. else
  908. {
  909. BufferArmShift(Instr->dataproc.operand2);
  910. }
  911. }
  912. void
  913. ArmMachineInfo::BufferArmShift(ULONG Shift)
  914. {
  915. ULONG Op = (Shift >> 5) & 3;
  916. ULONG Amount = (Shift >> 7) & 0x1f;
  917. if (Op == 3 && !(Shift & 0x10) && Amount == 0)
  918. {
  919. // ror #0 is replaced by rrx.
  920. Op = 4;
  921. }
  922. BufferRegName(Shift & 0xf);
  923. if (Op == 0 && Amount == 0)
  924. {
  925. // No shift.
  926. return;
  927. }
  928. *m_Buf++ = ',';
  929. *m_Buf++ = ' ';
  930. BufferString(g_ArmShift[Op]);
  931. *m_Buf++ = ' ';
  932. if (Shift & 0x10)
  933. {
  934. DBG_ASSERT(!(Shift & 0x80));
  935. BufferRegName((Shift >> 8) & 0xf);
  936. }
  937. else
  938. {
  939. if ((Op == 1 || Op == 2) && Amount == 0)
  940. {
  941. // lsr #0 and asr #0 are actually [la]sr #32.
  942. Amount = 32;
  943. }
  944. *m_Buf++ = '#';
  945. BufferInt(Amount, 0, FALSE);
  946. }
  947. }
  948. void
  949. ArmMachineInfo::BufferRegName(ULONG Reg)
  950. {
  951. PCSTR Name = RegNameFromIndex(Reg + ARM_INT_FIRST);
  952. if (Name)
  953. {
  954. BufferString(Name);
  955. }
  956. else
  957. {
  958. BufferString("ArmMachineInfo::BufferRegName invalid arg");
  959. }
  960. }
  961. void
  962. ArmMachineInfo::BufferCond(ULONG Cond)
  963. {
  964. if (Cond != COND_AL && Cond != COND_NV)
  965. {
  966. BufferString(g_ArmCond[Cond >> COND_SHIFT]);
  967. }
  968. }
  969. BOOL
  970. ArmMachineInfo::IsBreakpointInstruction(ProcessInfo* Process, PADDR Addr)
  971. {
  972. // XXX drewb - Presumably some form of BKPT, but what?
  973. return FALSE;
  974. }
  975. HRESULT
  976. ArmMachineInfo::InsertBreakpointInstruction(PUSER_DEBUG_SERVICES Services,
  977. ULONG64 Process,
  978. ULONG64 Offset,
  979. ULONG Flags,
  980. PUCHAR SaveInstr,
  981. PULONG64 ChangeStart,
  982. PULONG ChangeLen)
  983. {
  984. if (Flags != IBI_DEFAULT)
  985. {
  986. return E_INVALIDARG;
  987. }
  988. return E_NOTIMPL;
  989. }
  990. HRESULT
  991. ArmMachineInfo::RemoveBreakpointInstruction(PUSER_DEBUG_SERVICES Services,
  992. ULONG64 Process,
  993. ULONG64 Offset,
  994. PUCHAR SaveInstr,
  995. PULONG64 ChangeStart,
  996. PULONG ChangeLen)
  997. {
  998. return E_NOTIMPL;
  999. }
  1000. void
  1001. ArmMachineInfo::AdjustPCPastBreakpointInstruction(PADDR Addr,
  1002. ULONG BreakType)
  1003. {
  1004. DBG_ASSERT(BreakType == DEBUG_BREAKPOINT_CODE);
  1005. AddrAdd(Addr, 4);
  1006. SetPC(Addr);
  1007. }
  1008. BOOL
  1009. ArmMachineInfo::IsCallDisasm(PCSTR Disasm)
  1010. {
  1011. // XXX.
  1012. return FALSE;
  1013. }
  1014. BOOL
  1015. ArmMachineInfo::IsReturnDisasm(PCSTR Disasm)
  1016. {
  1017. // XXX.
  1018. return FALSE;
  1019. }
  1020. BOOL
  1021. ArmMachineInfo::IsSystemCallDisasm(PCSTR Disasm)
  1022. {
  1023. // XXX.
  1024. return FALSE;
  1025. }
  1026. BOOL
  1027. ArmMachineInfo::IsDelayInstruction(PADDR Addr)
  1028. {
  1029. // ARM does not have delay slots.
  1030. return FALSE;
  1031. }
  1032. void
  1033. ArmMachineInfo::GetEffectiveAddr(PADDR Addr, PULONG Size)
  1034. {
  1035. *Addr = m_EffAddr;
  1036. *Size = m_EaSize;
  1037. }
  1038. BOOL
  1039. ArmCheckConditionCodes(
  1040. PARM_CONTEXT Context,
  1041. DWORD instr
  1042. )
  1043. /*++
  1044. Routine Description:
  1045. Checks the condition codes of the instruction and the values of the
  1046. condition flags in the current program status register, and determines
  1047. whether or not the instruction will be executed.
  1048. Return Value:
  1049. TRUE if the instruction will be executed, FALSE otherwise.
  1050. --*/
  1051. {
  1052. BOOL Execute = FALSE;
  1053. BOOL Nset = (Context->Psr & 0x80000000L) == 0x80000000L;
  1054. BOOL Zset = (Context->Psr & 0x40000000L) == 0x40000000L;
  1055. BOOL Cset = (Context->Psr & 0x20000000L) == 0x20000000L;
  1056. BOOL Vset = (Context->Psr & 0x10000000L) == 0x10000000L;
  1057. instr &= COND_MASK;
  1058. switch( instr )
  1059. {
  1060. case COND_EQ: // Z set
  1061. if ( Zset ) Execute = TRUE;
  1062. break;
  1063. case COND_NE: // Z clear
  1064. if ( !Zset ) Execute = TRUE;
  1065. break;
  1066. case COND_CS: // C set
  1067. if ( Cset ) Execute = TRUE;
  1068. break;
  1069. case COND_CC: // C clear
  1070. if ( !Cset ) Execute = TRUE;
  1071. break;
  1072. case COND_MI: // N set
  1073. if ( Nset ) Execute = TRUE;
  1074. break;
  1075. case COND_PL: // N clear
  1076. if ( !Nset ) Execute = TRUE;
  1077. break;
  1078. case COND_VS: // V set
  1079. if ( Vset ) Execute = TRUE;
  1080. break;
  1081. case COND_VC: // V clear
  1082. if ( !Vset ) Execute = TRUE;
  1083. break;
  1084. case COND_HI: // C set and Z clear
  1085. if ( Cset && !Zset ) Execute = TRUE;
  1086. break;
  1087. case COND_LS: // C clear or Z set
  1088. if ( !Cset || Zset ) Execute = TRUE;
  1089. break;
  1090. case COND_GE: // N == V
  1091. if (( Nset && Vset ) || ( !Nset && !Vset )) Execute = TRUE;
  1092. break;
  1093. case COND_LT: // N != V
  1094. if (( Nset && !Vset ) || ( !Nset && Vset )) Execute = TRUE;
  1095. break;
  1096. case COND_GT: // Z clear, and N == V
  1097. if ( !Zset &&
  1098. (( Nset && Vset ) || ( !Nset && !Vset ))) Execute = TRUE;
  1099. break;
  1100. case COND_LE: // Z set, and N != V
  1101. if ( Zset &&
  1102. (( Nset && !Vset ) || ( !Nset && Vset ))) Execute = TRUE;
  1103. break;
  1104. case COND_AL: // Always execute
  1105. case COND_NV:
  1106. Execute = TRUE;
  1107. break;
  1108. default:
  1109. DBG_ASSERT(FALSE);
  1110. break;
  1111. }
  1112. return Execute;
  1113. }
  1114. void
  1115. ArmMachineInfo::GetNextOffset(ProcessInfo* Process,
  1116. BOOL StepOver,
  1117. PADDR NextAddr, PULONG NextMachine)
  1118. {
  1119. ARMI instr;
  1120. PULONG Register = &m_Context.ArmContext.R0;
  1121. ULONG returnvalue;
  1122. BOOL QualifyReturnAddress = FALSE; // ADDED for ARM WINCE, fixes up LR
  1123. BOOL Ldm_instr = FALSE;
  1124. *NextMachine = m_ExecTypes[0];
  1125. GetPC(NextAddr);
  1126. if (m_Target->ReadAllVirtual(Process, Flat(*NextAddr), &instr.instruction,
  1127. sizeof(instr.instruction)) != S_OK)
  1128. {
  1129. // Couldn't read the instruction so just return the
  1130. // next offset.
  1131. AddrAdd(NextAddr, 4);
  1132. return;
  1133. }
  1134. //
  1135. // We are only testing for data processing, load multiple, bx and bl
  1136. // instructions. We might have to check regular loads and stores that
  1137. // have the PC as the destination.
  1138. //
  1139. if (!ArmCheckConditionCodes(&m_Context.ArmContext, instr.instruction))
  1140. {
  1141. //
  1142. // Instruction will not be executed. Bump PC normally.
  1143. //
  1144. AddrAdd(NextAddr, 4);
  1145. return;
  1146. }
  1147. if (( instr.instruction & BX_MASK ) == BX_INSTR )
  1148. {
  1149. ULONG Rn;
  1150. //
  1151. // Check Rn (lower 4 bits). To compute the target address:
  1152. // Mask out the T bit. We don't care if we're transferring to Thumb
  1153. // Shift bits 31-1 left 1 bit.
  1154. //
  1155. Rn = Register[ instr.bx.rn ];
  1156. Rn &= 0xfffffffe;
  1157. returnvalue = Rn << 1;
  1158. }
  1159. else if (( instr.instruction & DATA_PROC_MASK ) == DP_PC_INSTR )
  1160. {
  1161. ULONG Op1, Op2;
  1162. ULONG Cflag = (m_Context.ArmContext.Psr & 0x20000000L) == 0x20000000L;
  1163. ULONG shift;
  1164. //
  1165. // We are not making sure that data processing instructions are not the
  1166. // multiply instructions, because we are checking to make sure that the
  1167. // PC is the destination register. The PC is not a legal destination
  1168. // register on multiply instructions.
  1169. //
  1170. // Currently only the MOV instruction (returns, branches) and the ADDLS
  1171. // instruction (switch statement) are used. Both of these instructions
  1172. // use the addressing mode "Register, Logical shift left by immediate."
  1173. // I'm leaving the other cases in case they are used in the future.
  1174. //
  1175. //
  1176. // Figure out the addressing mode (there are 11 of them), and get the
  1177. // operands.
  1178. //
  1179. Op1 = Register[ instr.dataproc.rn ];
  1180. if ( instr.dataproc.rn == 15 )
  1181. {
  1182. //
  1183. // If this is the PC, add 8.
  1184. //
  1185. Op1 += 8;
  1186. }
  1187. if ( instr.dataproc.bits == 0x1 )
  1188. {
  1189. //
  1190. // Immediate addressing - Type 1
  1191. //
  1192. Op2 = _lrotr( instr.dpi.immediate, instr.dpi.rotate * 2 );
  1193. }
  1194. else
  1195. {
  1196. //
  1197. // Register addressing - start by getting the value of Rm.
  1198. //
  1199. Op2 = Register[ instr.dpshi.rm ];
  1200. if ( instr.dpshi.rm == 15 )
  1201. {
  1202. //
  1203. // If this is the PC, add 8.
  1204. //
  1205. Op2 += 8;
  1206. }
  1207. if ( instr.dprre.bits == 0x6 )
  1208. {
  1209. //
  1210. // Rotate right with extended - Type 11
  1211. //
  1212. Op2 = ( Cflag << 31 ) | ( Op2 >> 1 );
  1213. }
  1214. else if ( instr.dataproc.operand2 & 0x10 )
  1215. {
  1216. //
  1217. // Register shifts. Types 4, 6, 8, and 10
  1218. //
  1219. //
  1220. // Get the shift value from the least-significant byte of the
  1221. // shift register.
  1222. //
  1223. shift = Register[ instr.dpshr.rs ];
  1224. shift &= 0xff;
  1225. switch( instr.dpshr.bits )
  1226. {
  1227. case 0x1: // 4 Logical shift left by register
  1228. if ( shift >= 32 )
  1229. {
  1230. Op2 = 0;
  1231. }
  1232. else
  1233. {
  1234. Op2 = Op2 << shift;
  1235. }
  1236. break;
  1237. case 0x3: // 6 Logical shift right by register
  1238. if ( shift >= 32 )
  1239. {
  1240. Op2 = 0;
  1241. }
  1242. else
  1243. {
  1244. Op2 = Op2 >> shift;
  1245. }
  1246. break;
  1247. case 0x5: // 8 Arithmetic shift right by register
  1248. if ( shift >= 32 )
  1249. {
  1250. if ( Op2 & 0x80000000 )
  1251. {
  1252. Op2 = 0xffffffff;
  1253. }
  1254. else
  1255. {
  1256. Op2 = 0;
  1257. }
  1258. }
  1259. else
  1260. {
  1261. Op2 = (LONG)Op2 >> shift;
  1262. }
  1263. break;
  1264. case 0x7: // 10 Rotate right by register
  1265. if ( !( shift == 0 ) && !(( shift & 0xf ) == 0 ) )
  1266. {
  1267. Op2 = _lrotl( Op2, shift );
  1268. }
  1269. break;
  1270. default:
  1271. break;
  1272. }
  1273. }
  1274. else
  1275. {
  1276. //
  1277. // Immediate shifts. Types 2, 3, 5, 7, and 9
  1278. //
  1279. //
  1280. // Get the shift value from the instruction.
  1281. //
  1282. shift = instr.dpshi.shift;
  1283. switch( instr.dpshi.bits )
  1284. {
  1285. case 0x0: // 2,3 Register, Logical shift left by immediate
  1286. if ( shift != 0 )
  1287. {
  1288. Op2 = Op2 << shift;
  1289. }
  1290. break;
  1291. case 0x2: // 5 Logical shift right by immediate
  1292. if ( shift == 0 )
  1293. {
  1294. Op2 = 0;
  1295. }
  1296. else
  1297. {
  1298. Op2 = Op2 >> shift;
  1299. }
  1300. break;
  1301. case 0x4: // 7 Arithmetic shift right by immediate
  1302. if ( shift == 0 )
  1303. {
  1304. Op2 = 0;
  1305. }
  1306. else
  1307. {
  1308. Op2 = (LONG)Op2 >> shift;
  1309. }
  1310. break;
  1311. case 0x6: // 9 Rotate right by immediate
  1312. Op2 = _lrotl( Op2, shift );
  1313. break;
  1314. default:
  1315. break;
  1316. }
  1317. }
  1318. }
  1319. //
  1320. // Determine the result (the new PC), based on the opcode.
  1321. //
  1322. switch( instr.dataproc.opcode )
  1323. {
  1324. case OP_AND:
  1325. returnvalue = Op1 & Op2;
  1326. break;
  1327. case OP_EOR:
  1328. returnvalue = Op1 ^ Op2;
  1329. break;
  1330. case OP_SUB:
  1331. returnvalue = Op1 - Op2;
  1332. break;
  1333. case OP_RSB:
  1334. returnvalue = Op2 - Op1;
  1335. break;
  1336. case OP_ADD:
  1337. returnvalue = Op1 + Op2;
  1338. break;
  1339. case OP_ADC:
  1340. returnvalue = (Op1 + Op2) + Cflag;
  1341. break;
  1342. case OP_SBC:
  1343. returnvalue = (Op1 - Op2) - ~Cflag;
  1344. break;
  1345. case OP_RSC:
  1346. returnvalue = (Op2 - Op1) - ~Cflag;
  1347. break;
  1348. case OP_ORR:
  1349. returnvalue = Op1 | Op2;
  1350. break;
  1351. case OP_MOV:
  1352. if (( instr.dataproc.operand2 != 0xe ) && StepOver )
  1353. {
  1354. //
  1355. // A move from any register but LR to the PC is a call.
  1356. // We are stepping over, so bump the PC normally.
  1357. //
  1358. returnvalue = (ULONG)Flat(*NextAddr) + sizeof(ARMI);
  1359. }
  1360. else
  1361. {
  1362. //ie: mov pc, lr
  1363. returnvalue = Op2;
  1364. //[Moonshot 6841]: fix up the LR reg.
  1365. QualifyReturnAddress = TRUE;
  1366. }
  1367. break;
  1368. case OP_BIC:
  1369. returnvalue = Op1 & ~Op2;
  1370. break;
  1371. case OP_MVN:
  1372. returnvalue = ~Op2;
  1373. break;
  1374. case OP_TST:
  1375. case OP_TEQ:
  1376. case OP_CMP:
  1377. case OP_CMN:
  1378. default:
  1379. //
  1380. // This really isn't a branch. Bump the PC normally.
  1381. //
  1382. returnvalue = (ULONG)Flat(*NextAddr) + sizeof(ARMI);
  1383. break;
  1384. }
  1385. }
  1386. else if (( instr.instruction & LDM_PC_MASK ) == LDM_PC_INSTR )
  1387. {
  1388. // ie: ldmia sp!, {pc}
  1389. // Load multiple with the PC bit set. We don't need to check the
  1390. // step over flag in this case, because a load multiple is never a
  1391. // call, only a return.
  1392. //
  1393. ULONG RegList, i, count = 0, Rn;
  1394. //
  1395. // Get the address from Rn.
  1396. //
  1397. Rn = Register[ instr.ldm.rn ];
  1398. if ( instr.ldm.u )
  1399. {
  1400. //
  1401. // Increment the address. Check to see how many other registers
  1402. // are to be read.
  1403. //
  1404. RegList = instr.ldm.reglist;
  1405. for ( i = 0; i < 15; i++ )
  1406. {
  1407. if ( RegList & 0x1 ) count++;
  1408. RegList = RegList >> 1;
  1409. }
  1410. //
  1411. // Check the p bit to see how big to make the offset to the PC.
  1412. //
  1413. if ( instr.ldm.p )
  1414. {
  1415. // Before
  1416. count = (count + 1) * sizeof(ARMI);
  1417. }
  1418. else
  1419. {
  1420. // After
  1421. count = count * sizeof(ARMI);
  1422. }
  1423. Rn += count;
  1424. }
  1425. else
  1426. {
  1427. //
  1428. // Decrement the address. If we decrement before, we need to
  1429. // subract the instruction size now. Otherwise, do nothing.
  1430. //
  1431. if ( instr.ldm.p )
  1432. {
  1433. // Before
  1434. Rn -= sizeof(ARMI);
  1435. }
  1436. }
  1437. // reading values from the stack
  1438. if (m_Target->ReadAllVirtual(Process, EXTEND64(Rn), &returnvalue,
  1439. sizeof(returnvalue)) != S_OK)
  1440. {
  1441. // Unable to read, so what should be returned?
  1442. returnvalue = (ULONG)Flat(*NextAddr) + sizeof(ARMI);
  1443. }
  1444. //[Moonshot 6838]: fix up the LR reg.
  1445. QualifyReturnAddress = TRUE;
  1446. Ldm_instr = TRUE;
  1447. }
  1448. else if ((( instr.instruction & B_BL_MASK ) == B_INSTR ) ||
  1449. (( instr.instruction & B_BL_MASK ) == BL_INSTR ))
  1450. {
  1451. //
  1452. // If this is a call (branch and link), and we are stepping over, the
  1453. // next offset is the addr + 8.
  1454. //
  1455. if ( instr.bl.link && StepOver )
  1456. {
  1457. returnvalue = (ULONG)Flat(*NextAddr) + sizeof(ARMI);
  1458. }
  1459. else
  1460. {
  1461. LONG BranchOffset;
  1462. //
  1463. // To calculate the branch target:
  1464. // Shift the 24-bit offset left 2 bits
  1465. // Sign-extend it to 32 bits
  1466. // Add it to the contents of the PC
  1467. // (Which would be the current address + 8);
  1468. //
  1469. BranchOffset = instr.bl.offset;
  1470. BranchOffset <<= 2;
  1471. if( BranchOffset & 0x2000000 )
  1472. {
  1473. BranchOffset |= 0xfc000000;
  1474. }
  1475. returnvalue = (ULONG)Flat(*NextAddr) + BranchOffset;
  1476. returnvalue += 8;
  1477. }
  1478. }
  1479. else if ( instr.instruction == LDR_THUNK_2 )
  1480. {
  1481. //
  1482. // Need to handle import DLL thunk type branches to destination func Foo
  1483. //
  1484. // 0001ACA0: ldr r12, [pc] ; pc+8+0 = 0x0001ACA8
  1485. // 0001ACA4: ldr pc, [r12]
  1486. // 0001ACA8: DCD 0x0001C020 ; This memory location holds the address, of the address, of Foo
  1487. //
  1488. // 0001C020: DCD Foo ; This memory location holds the address of Foo
  1489. //
  1490. //
  1491. // Get the address of Foo from Rn.
  1492. // simple register indirect. no offsets, no scaling, no indexing addressing mode
  1493. //
  1494. if (m_Target->ReadAllVirtual(Process, EXTEND64(Register[instr.ldr.rn]),
  1495. &returnvalue,
  1496. sizeof(returnvalue)) != S_OK)
  1497. {
  1498. // Unable to read, so what should be returned?
  1499. returnvalue = (ULONG)Flat(*NextAddr) + sizeof(ARMI);
  1500. }
  1501. }
  1502. else
  1503. {
  1504. // Bump PC normally
  1505. returnvalue = (ULONG)Flat(*NextAddr) + sizeof(ARMI);
  1506. }
  1507. #if 0
  1508. //jvp
  1509. //[Moonshot 6838, 6841]: fix up the LR register.
  1510. // Taken from the same function in ppcmach.c
  1511. // The value we get from the LR register is not necessarily fully
  1512. // qualified. In WINCE, when a process is running it is mapped into the
  1513. // ZERO slot, meaning that the upper 6 bits contain 0. To fully
  1514. // qualify an address, the upper 6 bits contain the current process. The
  1515. // LR regs is set at runtime so we need to fix it up so breakpoint
  1516. // comparisons make sense.
  1517. if (QualifyReturnAddress == TRUE)
  1518. {
  1519. ULONG Status, NextOffset;
  1520. ARMI I1;
  1521. ADDR addr;
  1522. NextOffset = returnvalue;
  1523. ZeroMemory(&addr, sizeof(ADDR));
  1524. GetAddrOff(addr) = NextOffset;
  1525. TranslateAddress(hthd->hprc, 0, &addr, TRUE);
  1526. NextOffset = GetAddrOff(addr);
  1527. Status = STATUS_SUCCESS;
  1528. //
  1529. // Because the next offset translation is meant for NK, the
  1530. // stub and simulator will return STATUS_UNSUCCESSFUL.
  1531. //
  1532. // On a successful transaction our new address will be fully qualified
  1533. // otherwise, just leave.
  1534. if (Status == STATUS_SUCCESS)
  1535. {
  1536. if (!Ldm_instr)
  1537. {
  1538. // DP_PC_INSTR; Moonshot 6841
  1539. returnvalue = NextOffset; // fully qualified.
  1540. }
  1541. //since this is a ldm instruction, it's reading values from the stack;
  1542. //so do error checking to make sure that these values must be a valid
  1543. //instruction. At this moment, we know that NextOffset contains the address
  1544. //of the instruction after the branch instruction (also contains the value
  1545. //of LR). So make sure that the previous instruction (from the NextOffset)
  1546. //must be a branch instruction.
  1547. else if (NextOffset && (!(NextOffset % 4)))
  1548. {
  1549. AddrInit( &memaddr, 0, 0, NextOffset-4, TRUE, TRUE, FALSE, FALSE );
  1550. AddrReadMemory( hthd->hprc, //read previous instruction.
  1551. hthd,
  1552. &memaddr,
  1553. &I1.instruction,
  1554. sizeof(ARMI),
  1555. &cBytes );
  1556. //previous instruction must be a branch instruction.
  1557. if ( ((I1.instruction & BX_MASK ) == BX_INSTR ) ||
  1558. ((I1.instruction & B_BL_MASK ) == B_INSTR) ||
  1559. ((I1.instruction & B_BL_MASK ) == BL_INSTR) )
  1560. {
  1561. returnvalue = NextOffset; //fully qualified.
  1562. }
  1563. }
  1564. }
  1565. }
  1566. {
  1567. // make sure a fully fixed up offset is returned
  1568. ADDR addr;
  1569. DWORD dwTemp;
  1570. DWORD dwPC;
  1571. BOOL bReturn;
  1572. ZeroMemory(&addr, sizeof(ADDR));
  1573. GetAddrOff(addr) = returnvalue;
  1574. TranslateAddress(hthd->hprc, 0, &addr, TRUE);
  1575. if (!StepOver)
  1576. {
  1577. cBytes = 0;
  1578. dwTemp = 0;
  1579. returnvalue = GetAddrOff(addr);
  1580. bReturn = DbgReadMemory(hthd->hprc,
  1581. (LPVOID)returnvalue,
  1582. &dwTemp,
  1583. sizeof(DWORD),
  1584. &cBytes);
  1585. if (!bReturn || cBytes != sizeof(DWORD) || dwTemp == 0 )
  1586. {
  1587. returnvalue = pcaddr.addr.off + sizeof(ARMI);
  1588. GetAddrOff(addr) = returnvalue;
  1589. TranslateAddress(hthd->hprc, 0, &addr, TRUE);
  1590. dwPC = 0;
  1591. }
  1592. else
  1593. {
  1594. dwPC = returnvalue;
  1595. }
  1596. // Now need to find if its a thunk, if yes, we need to
  1597. // probe the thunk destination
  1598. if ( dwPC )
  1599. {
  1600. while (IsThunk(hthd, dwPC, NULL, &dwPC, NULL ) && dwPC)
  1601. {
  1602. GetAddrOff(addr) = dwPC;
  1603. TranslateAddress(hthd->hprc, 0, &addr, FALSE);
  1604. dwPC = GetAddrOff(addr);
  1605. cBytes = 0;
  1606. dwTemp = 0;
  1607. bReturn = DbgReadMemory(hthd->hprc,
  1608. (LPVOID)dwPC,
  1609. &dwTemp,
  1610. sizeof(DWORD),
  1611. &cBytes);
  1612. if (!bReturn || cBytes != sizeof(DWORD) || dwTemp == 0 )
  1613. {
  1614. returnvalue = pcaddr.addr.off + sizeof(ARMI);
  1615. GetAddrOff(addr) = returnvalue;
  1616. TranslateAddress(hthd->hprc, 0, &addr, TRUE);
  1617. break;
  1618. }
  1619. }
  1620. }
  1621. }
  1622. returnvalue = GetAddrOff(addr);
  1623. }
  1624. #endif
  1625. ADDRFLAT(NextAddr, EXTEND64(returnvalue));
  1626. }
  1627. void
  1628. ArmMachineInfo::IncrementBySmallestInstruction(PADDR Addr)
  1629. {
  1630. AddrAdd(Addr, 4);
  1631. }
  1632. void
  1633. ArmMachineInfo::DecrementBySmallestInstruction(PADDR Addr)
  1634. {
  1635. AddrSub(Addr, 4);
  1636. }
  1637. void
  1638. ArmMachineInfo::Assemble(ProcessInfo* Process,
  1639. PADDR Address, PSTR Input)
  1640. {
  1641. // Not going to implement assemble command at this time
  1642. ErrOut("No assemble support for ARM\n");
  1643. }