5db.c 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341
  1. /*
  2. * This file is part of the UCB release of Plan 9. It is subject to the license
  3. * terms in the LICENSE file found in the top-level directory of this
  4. * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
  5. * part of the UCB release of Plan 9, including this file, may be copied,
  6. * modified, propagated, or distributed except according to the terms contained
  7. * in the LICENSE file.
  8. */
  9. #include <u.h>
  10. #include <libc.h>
  11. #include <bio.h>
  12. #include <mach.h>
  13. static int debug = 0;
  14. #define BITS(a, b) ((1<<(b+1))-(1<<a))
  15. #define LSR(v, s) ((unsigned long)(v) >> (s))
  16. #define ASR(v, s) ((int32_t)(v) >> (s))
  17. #define ROR(v, s) (LSR((v), (s)) | (((v) & ((1 << (s))-1)) << (32 - (s))))
  18. typedef struct Instr Instr;
  19. struct Instr
  20. {
  21. Map *map;
  22. uint32_t w;
  23. uint64_t addr;
  24. uint8_t op; /* super opcode */
  25. uint8_t cond; /* bits 28-31 */
  26. uint8_t store; /* bit 20 */
  27. uint8_t rd; /* bits 12-15 */
  28. uint8_t rn; /* bits 16-19 */
  29. uint8_t rs; /* bits 0-11 (shifter operand) */
  30. int32_t imm; /* rotated imm */
  31. char* curr; /* fill point in buffer */
  32. char* end; /* end of buffer */
  33. char* err; /* error message */
  34. };
  35. typedef struct Opcode Opcode;
  36. struct Opcode
  37. {
  38. char* o;
  39. void (*fmt)(Opcode*, Instr*);
  40. uint64_t (*foll)(Map*, Rgetter, Instr*, uint64_t);
  41. char* a;
  42. };
  43. static void format(char*, Instr*, char*);
  44. static char FRAMENAME[] = ".frame";
  45. /*
  46. * Arm-specific debugger interface
  47. */
  48. static char *armexcep(Map*, Rgetter);
  49. static int armfoll(Map*, uint64_t, Rgetter, uint64_t*);
  50. static int arminst(Map*, uint64_t, char, char*, int);
  51. static int armdas(Map*, uint64_t, char*, int);
  52. static int arminstlen(Map*, uint64_t);
  53. /*
  54. * Debugger interface
  55. */
  56. Machdata armmach =
  57. {
  58. {0x70, 0x00, 0x20, 0xE1}, /* break point */ /* E1200070 */
  59. 4, /* break point size */
  60. leswab, /* short to local byte order */
  61. leswal, /* long to local byte order */
  62. leswav, /* long to local byte order */
  63. risctrace, /* C traceback */
  64. riscframe, /* Frame finder */
  65. armexcep, /* print exception */
  66. 0, /* breakpoint fixup */
  67. 0, /* single precision float printer */
  68. 0, /* double precision float printer */
  69. armfoll, /* following addresses */
  70. arminst, /* print instruction */
  71. armdas, /* dissembler */
  72. arminstlen, /* instruction size */
  73. };
  74. static char*
  75. armexcep(Map *map, Rgetter rget)
  76. {
  77. uint64_t c;
  78. c = (*rget)(map, "TYPE");
  79. switch ((int)c&0x1f) {
  80. case 0x11:
  81. return "Fiq interrupt";
  82. case 0x12:
  83. return "Mirq interrupt";
  84. case 0x13:
  85. return "SVC/SWI Exception";
  86. case 0x17:
  87. return "Prefetch Abort/Breakpoint";
  88. case 0x18:
  89. return "Data Abort";
  90. case 0x1b:
  91. return "Undefined instruction/Breakpoint";
  92. case 0x1f:
  93. return "Sys trap";
  94. default:
  95. return "Undefined trap";
  96. }
  97. }
  98. static
  99. char* cond[16] =
  100. {
  101. "EQ", "NE", "CS", "CC",
  102. "MI", "PL", "VS", "VC",
  103. "HI", "LS", "GE", "LT",
  104. "GT", "LE", 0, "NV"
  105. };
  106. static
  107. char* shtype[4] =
  108. {
  109. "<<", ">>", "->", "@>"
  110. };
  111. static
  112. char *hb[4] =
  113. {
  114. "???", "HU", "B", "H"
  115. };
  116. static
  117. char* addsub[2] =
  118. {
  119. "-", "+",
  120. };
  121. int
  122. armclass(int32_t w)
  123. {
  124. int op, done, cp;
  125. op = (w >> 25) & 0x7;
  126. switch(op) {
  127. case 0: /* data processing r,r,r */
  128. if((w & 0x0ff00080) == 0x01200000) {
  129. op = (w >> 4) & 0x7;
  130. if(op == 7)
  131. op = 124; /* bkpt */
  132. else if (op > 0 && op < 4)
  133. op += 124; /* bx, blx */
  134. else
  135. op = 92; /* unk */
  136. break;
  137. }
  138. op = ((w >> 4) & 0xf);
  139. if(op == 0x9) {
  140. op = 48+16; /* mul, swp or *rex */
  141. if((w & 0x0ff00fff) == 0x01900f9f) {
  142. op = 93; /* ldrex */
  143. break;
  144. }
  145. if((w & 0x0ff00ff0) == 0x01800f90) {
  146. op = 94; /* strex */
  147. break;
  148. }
  149. if(w & (1<<24)) {
  150. op += 2;
  151. if(w & (1<<22))
  152. op++; /* swpb */
  153. break;
  154. }
  155. if(w & (1<<23)) { /* mullu */
  156. op = (48+24+4+4+2+2+4);
  157. if(w & (1<<22)) /* mull */
  158. op += 2;
  159. }
  160. if(w & (1<<21))
  161. op++; /* mla */
  162. break;
  163. }
  164. if((op & 0x9) == 0x9) /* ld/st byte/half s/u */
  165. {
  166. op = (48+16+4) + ((w >> 22) & 0x1) + ((w >> 19) & 0x2);
  167. break;
  168. }
  169. op = (w >> 21) & 0xf;
  170. if(w & (1<<4))
  171. op += 32;
  172. else
  173. if((w & (31<<7)) || (w & (1<<5)))
  174. op += 16;
  175. break;
  176. case 1: /* data processing i,r,r */
  177. op = (48) + ((w >> 21) & 0xf);
  178. break;
  179. case 2: /* load/store byte/word i(r) */
  180. if ((w & 0xffffff8f) == 0xf57ff00f) { /* barriers, clrex */
  181. done = 1;
  182. switch ((w >> 4) & 7) {
  183. case 1:
  184. op = 95; /* clrex */
  185. break;
  186. case 4:
  187. op = 96; /* dsb */
  188. break;
  189. case 5:
  190. op = 97; /* dmb */
  191. break;
  192. case 6:
  193. op = 98; /* isb */
  194. break;
  195. default:
  196. done = 0;
  197. break;
  198. }
  199. if (done)
  200. break;
  201. }
  202. op = (48+24) + ((w >> 22) & 0x1) + ((w >> 19) & 0x2);
  203. break;
  204. case 3: /* load/store byte/word (r)(r) */
  205. op = (48+24+4) + ((w >> 22) & 0x1) + ((w >> 19) & 0x2);
  206. break;
  207. case 4: /* block data transfer (r)(r) */
  208. if ((w & 0xfe50ffff) == 0xf8100a00) { /* v7 RFE */
  209. op = 99;
  210. break;
  211. }
  212. op = (48+24+4+4) + ((w >> 20) & 0x1);
  213. break;
  214. case 5: /* branch / branch link */
  215. op = (48+24+4+4+2) + ((w >> 24) & 0x1);
  216. break;
  217. case 7: /* coprocessor crap */
  218. cp = (w >> 8) & 0xF;
  219. if(cp == 10 || cp == 11){ /* vfp */
  220. if((w >> 4) & 0x1){
  221. /* vfp register transfer */
  222. switch((w >> 21) & 0x7){
  223. case 0:
  224. op = 118 + ((w >> 20) & 0x1);
  225. break;
  226. case 7:
  227. op = 118+2 + ((w >> 20) & 0x1);
  228. break;
  229. default:
  230. op = (48+24+4+4+2+2+4+4);
  231. break;
  232. }
  233. break;
  234. }
  235. /* vfp data processing */
  236. if(((w >> 23) & 0x1) == 0){
  237. op = 100 + ((w >> 19) & 0x6) + ((w >> 6) & 0x1);
  238. break;
  239. }
  240. switch(((w >> 19) & 0x6) + ((w >> 6) & 0x1)){
  241. case 0:
  242. op = 108;
  243. break;
  244. case 7:
  245. if(((w >> 19) & 0x1) == 0){
  246. if(((w >> 17) & 0x1) == 0)
  247. op = 109 + ((w >> 16) & 0x4) +
  248. ((w >> 15) & 0x2) +
  249. ((w >> 7) & 0x1);
  250. else if(((w >> 16) & 0x7) == 0x7)
  251. op = 117;
  252. }else
  253. switch((w >> 16) & 0x7){
  254. case 0:
  255. case 4:
  256. case 5:
  257. op = 117;
  258. break;
  259. }
  260. break;
  261. }
  262. if(op == 7)
  263. op = (48+24+4+4+2+2+4+4);
  264. break;
  265. }
  266. op = (48+24+4+4+2+2) + ((w >> 3) & 0x2) + ((w >> 20) & 0x1);
  267. break;
  268. case 6: /* vfp load / store */
  269. if(((w >> 21) &0x9) == 0x8){
  270. op = 122 + ((w >> 20) & 0x1);
  271. break;
  272. }
  273. /* fall through */
  274. default:
  275. op = (48+24+4+4+2+2+4+4);
  276. break;
  277. }
  278. return op;
  279. }
  280. static int
  281. decode(Map *map, uint64_t pc, Instr *i)
  282. {
  283. uint32_t w;
  284. if(get4(map, pc, &w) < 0) {
  285. werrstr("can't read instruction: %r");
  286. return -1;
  287. }
  288. i->w = w;
  289. i->addr = pc;
  290. i->cond = (w >> 28) & 0xF;
  291. i->op = armclass(w);
  292. i->map = map;
  293. return 1;
  294. }
  295. #pragma varargck argpos bprint 2
  296. static void
  297. bprint(Instr *i, char *fmt, ...)
  298. {
  299. va_list arg;
  300. va_start(arg, fmt);
  301. i->curr = vseprint(i->curr, i->end, fmt, arg);
  302. va_end(arg);
  303. }
  304. static int
  305. plocal(Instr *i)
  306. {
  307. char *reg;
  308. Symbol s;
  309. char *fn;
  310. int class;
  311. int offset;
  312. if(!findsym(i->addr, CTEXT, &s)) {
  313. if(debug)fprint(2,"fn not found @%llux: %r\n", i->addr);
  314. return 0;
  315. }
  316. fn = s.name;
  317. if (!findlocal(&s, FRAMENAME, &s)) {
  318. if(debug)fprint(2,"%s.%s not found @%s: %r\n", fn, FRAMENAME, s.name);
  319. return 0;
  320. }
  321. if(s.value > i->imm) {
  322. class = CAUTO;
  323. offset = s.value-i->imm;
  324. reg = "(SP)";
  325. } else {
  326. class = CPARAM;
  327. offset = i->imm-s.value-4;
  328. reg = "(FP)";
  329. }
  330. if(!getauto(&s, offset, class, &s)) {
  331. if(debug)fprint(2,"%s %s not found @%ux: %r\n", fn,
  332. class == CAUTO ? " auto" : "param", offset);
  333. return 0;
  334. }
  335. bprint(i, "%s%c%lld%s", s.name, class == CPARAM ? '+' : '-', s.value, reg);
  336. return 1;
  337. }
  338. /*
  339. * Print value v as name[+offset]
  340. */
  341. static int
  342. gsymoff(char *buf, int n, uint32_t v, int space)
  343. {
  344. Symbol s;
  345. int r;
  346. int32_t delta;
  347. r = delta = 0; /* to shut compiler up */
  348. if (v) {
  349. r = findsym(v, space, &s);
  350. if (r)
  351. delta = v-s.value;
  352. if (delta < 0)
  353. delta = -delta;
  354. }
  355. if (v == 0 || r == 0 || delta >= 4096)
  356. return snprint(buf, n, "#%lux", v);
  357. if (strcmp(s.name, ".string") == 0)
  358. return snprint(buf, n, "#%lux", v);
  359. if (!delta)
  360. return snprint(buf, n, "%s", s.name);
  361. if (s.type != 't' && s.type != 'T')
  362. return snprint(buf, n, "%s+%llux", s.name, v-s.value);
  363. else
  364. return snprint(buf, n, "#%lux", v);
  365. }
  366. static void
  367. armdps(Opcode *o, Instr *i)
  368. {
  369. i->store = (i->w >> 20) & 1;
  370. i->rn = (i->w >> 16) & 0xf;
  371. i->rd = (i->w >> 12) & 0xf;
  372. i->rs = (i->w >> 0) & 0xf;
  373. if(i->rn == 15 && i->rs == 0) {
  374. if(i->op == 8) {
  375. format("MOVW", i,"CPSR, R%d");
  376. return;
  377. } else
  378. if(i->op == 10) {
  379. format("MOVW", i,"SPSR, R%d");
  380. return;
  381. }
  382. } else
  383. if(i->rn == 9 && i->rd == 15) {
  384. if(i->op == 9) {
  385. format("MOVW", i, "R%s, CPSR");
  386. return;
  387. } else
  388. if(i->op == 11) {
  389. format("MOVW", i, "R%s, SPSR");
  390. return;
  391. }
  392. }
  393. if(i->rd == 15) {
  394. if(i->op == 120) {
  395. format("MOVW", i, "PSR, %x");
  396. return;
  397. } else
  398. if(i->op == 121) {
  399. format("MOVW", i, "%x, PSR");
  400. return;
  401. }
  402. }
  403. format(o->o, i, o->a);
  404. }
  405. static void
  406. armdpi(Opcode *o, Instr *i)
  407. {
  408. uint32_t v;
  409. int c;
  410. v = (i->w >> 0) & 0xff;
  411. c = (i->w >> 8) & 0xf;
  412. while(c) {
  413. v = (v<<30) | (v>>2);
  414. c--;
  415. }
  416. i->imm = v;
  417. i->store = (i->w >> 20) & 1;
  418. i->rn = (i->w >> 16) & 0xf;
  419. i->rd = (i->w >> 12) & 0xf;
  420. i->rs = i->w&0x0f;
  421. /* RET is encoded as ADD #0,R14,R15 */
  422. if((i->w & 0x0fffffff) == 0x028ef000){
  423. format("RET%C", i, "");
  424. return;
  425. }
  426. if((i->w & 0x0ff0ffff) == 0x0280f000){
  427. format("B%C", i, "0(R%n)");
  428. return;
  429. }
  430. format(o->o, i, o->a);
  431. }
  432. static void
  433. armsdti(Opcode *o, Instr *i)
  434. {
  435. uint32_t v;
  436. v = i->w & 0xfff;
  437. if(!(i->w & (1<<23)))
  438. v = -v;
  439. i->store = ((i->w >> 23) & 0x2) | ((i->w >>21) & 0x1);
  440. i->imm = v;
  441. i->rn = (i->w >> 16) & 0xf;
  442. i->rd = (i->w >> 12) & 0xf;
  443. /* RET is encoded as LW.P x,R13,R15 */
  444. if ((i->w & 0x0ffff000) == 0x049df000)
  445. {
  446. format("RET%C%p", i, "%I");
  447. return;
  448. }
  449. format(o->o, i, o->a);
  450. }
  451. static void
  452. armvstdi(Opcode *o, Instr *i)
  453. {
  454. uint32_t v;
  455. v = (i->w & 0xff) << 2;
  456. if(!(i->w & (1<<23)))
  457. v = -v;
  458. i->imm = v;
  459. i->rn = (i->w >> 16) & 0xf;
  460. i->rd = (i->w >> 12) & 0xf;
  461. format(o->o, i, o->a);
  462. }
  463. /* arm V4 ld/st halfword, signed byte */
  464. static void
  465. armhwby(Opcode *o, Instr *i)
  466. {
  467. i->store = ((i->w >> 23) & 0x2) | ((i->w >>21) & 0x1);
  468. i->imm = (i->w & 0xf) | ((i->w >> 8) & 0xf);
  469. if (!(i->w & (1 << 23)))
  470. i->imm = - i->imm;
  471. i->rn = (i->w >> 16) & 0xf;
  472. i->rd = (i->w >> 12) & 0xf;
  473. i->rs = (i->w >> 0) & 0xf;
  474. format(o->o, i, o->a);
  475. }
  476. static void
  477. armsdts(Opcode *o, Instr *i)
  478. {
  479. i->store = ((i->w >> 23) & 0x2) | ((i->w >>21) & 0x1);
  480. i->rs = (i->w >> 0) & 0xf;
  481. i->rn = (i->w >> 16) & 0xf;
  482. i->rd = (i->w >> 12) & 0xf;
  483. format(o->o, i, o->a);
  484. }
  485. static void
  486. armbdt(Opcode *o, Instr *i)
  487. {
  488. i->store = (i->w >> 21) & 0x3; /* S & W bits */
  489. i->rn = (i->w >> 16) & 0xf;
  490. i->imm = i->w & 0xffff;
  491. if(i->w == 0xe8fd8000)
  492. format("RFE", i, "");
  493. else
  494. format(o->o, i, o->a);
  495. }
  496. static void
  497. armund(Opcode *o, Instr *i)
  498. {
  499. format(o->o, i, o->a);
  500. }
  501. static void
  502. armcdt(Opcode *o, Instr *i)
  503. {
  504. format(o->o, i, o->a);
  505. }
  506. static void
  507. armunk(Opcode *o, Instr *i)
  508. {
  509. format(o->o, i, o->a);
  510. }
  511. static void
  512. armb(Opcode *o, Instr *i)
  513. {
  514. uint32_t v;
  515. v = i->w & 0xffffff;
  516. if(v & 0x800000)
  517. v |= ~0xffffff;
  518. i->imm = (v<<2) + i->addr + 8;
  519. format(o->o, i, o->a);
  520. }
  521. static void
  522. armbpt(Opcode *o, Instr *i)
  523. {
  524. i->imm = ((i->w >> 4) & 0xfff0) | (i->w &0xf);
  525. format(o->o, i, o->a);
  526. }
  527. static void
  528. armco(Opcode *o, Instr *i) /* coprocessor instructions */
  529. {
  530. int op, p, cp;
  531. char buf[1024];
  532. i->rn = (i->w >> 16) & 0xf;
  533. i->rd = (i->w >> 12) & 0xf;
  534. i->rs = i->w&0xf;
  535. cp = (i->w >> 8) & 0xf;
  536. p = (i->w >> 5) & 0x7;
  537. if(i->w&(1<<4)) {
  538. op = (i->w >> 21) & 0x07;
  539. snprint(buf, sizeof(buf), "#%x, #%x, R%d, C(%d), C(%d), #%x", cp, op, i->rd, i->rn, i->rs, p);
  540. } else {
  541. op = (i->w >> 20) & 0x0f;
  542. snprint(buf, sizeof(buf), "#%x, #%x, C(%d), C(%d), C(%d), #%x", cp, op, i->rd, i->rn, i->rs, p);
  543. }
  544. format(o->o, i, buf);
  545. }
  546. static int
  547. armcondpass(Map *map, Rgetter rget, uint8_t cond)
  548. {
  549. uint64_t psr;
  550. uint8_t n;
  551. uint8_t z;
  552. uint8_t c;
  553. uint8_t v;
  554. psr = rget(map, "PSR");
  555. n = (psr >> 31) & 1;
  556. z = (psr >> 30) & 1;
  557. c = (psr >> 29) & 1;
  558. v = (psr >> 28) & 1;
  559. switch(cond) {
  560. default:
  561. case 0: return z;
  562. case 1: return !z;
  563. case 2: return c;
  564. case 3: return !c;
  565. case 4: return n;
  566. case 5: return !n;
  567. case 6: return v;
  568. case 7: return !v;
  569. case 8: return c && !z;
  570. case 9: return !c || z;
  571. case 10: return n == v;
  572. case 11: return n != v;
  573. case 12: return !z && (n == v);
  574. case 13: return z || (n != v);
  575. case 14: return 1;
  576. case 15: return 0;
  577. }
  578. }
  579. static uint32_t
  580. armshiftval(Map *map, Rgetter rget, Instr *i)
  581. {
  582. if(i->w & (1 << 25)) { /* immediate */
  583. uint32_t imm = i->w & BITS(0, 7);
  584. uint32_t s = (i->w & BITS(8, 11)) >> 7; /* this contains the *2 */
  585. return ROR(imm, s);
  586. } else {
  587. char buf[8];
  588. uint32_t v;
  589. uint32_t s = (i->w & BITS(7,11)) >> 7;
  590. sprint(buf, "R%ld", i->w & 0xf);
  591. v = rget(map, buf);
  592. switch((i->w & BITS(4, 6)) >> 4) {
  593. default:
  594. case 0: /* LSLIMM */
  595. return v << s;
  596. case 1: /* LSLREG */
  597. sprint(buf, "R%lud", s >> 1);
  598. s = rget(map, buf) & 0xFF;
  599. if(s >= 32) return 0;
  600. return v << s;
  601. case 2: /* LSRIMM */
  602. return LSR(v, s);
  603. case 3: /* LSRREG */
  604. sprint(buf, "R%ld", s >> 1);
  605. s = rget(map, buf) & 0xFF;
  606. if(s >= 32) return 0;
  607. return LSR(v, s);
  608. case 4: /* ASRIMM */
  609. if(s == 0) {
  610. if((v & (1U<<31)) == 0)
  611. return 0;
  612. return 0xFFFFFFFF;
  613. }
  614. return ASR(v, s);
  615. case 5: /* ASRREG */
  616. sprint(buf, "R%ld", s >> 1);
  617. s = rget(map, buf) & 0xFF;
  618. if(s >= 32) {
  619. if((v & (1U<<31)) == 0)
  620. return 0;
  621. return 0xFFFFFFFF;
  622. }
  623. return ASR(v, s);
  624. case 6: /* RORIMM */
  625. if(s == 0) {
  626. uint32_t c = (rget(map, "PSR") >> 29) & 1;
  627. return (c << 31) | LSR(v, 1);
  628. }
  629. return ROR(v, s);
  630. case 7: /* RORREG */
  631. sprint(buf, "R%ld", (s>>1)&0xF);
  632. s = rget(map, buf);
  633. if(s == 0 || (s & 0xF) == 0)
  634. return v;
  635. return ROR(v, s & 0xF);
  636. }
  637. }
  638. }
  639. static int
  640. nbits(uint32_t v)
  641. {
  642. int n = 0;
  643. int i;
  644. for(i=0; i < 32 ; i++) {
  645. if(v & 1) ++n;
  646. v >>= 1;
  647. }
  648. return n;
  649. }
  650. static uint32_t
  651. armmaddr(Map *map, Rgetter rget, Instr *i)
  652. {
  653. uint32_t v;
  654. uint32_t nb;
  655. char buf[8];
  656. uint32_t rn;
  657. rn = (i->w >> 16) & 0xf;
  658. sprint(buf,"R%ld", rn);
  659. v = rget(map, buf);
  660. nb = nbits(i->w & ((1 << 15) - 1));
  661. switch((i->w >> 23) & 3) {
  662. default:
  663. case 0: return (v - (nb*4)) + 4;
  664. case 1: return v;
  665. case 2: return v - (nb*4);
  666. case 3: return v + 4;
  667. }
  668. }
  669. static uint64_t
  670. armaddr(Map *map, Rgetter rget, Instr *i)
  671. {
  672. char buf[8];
  673. uint32_t rn;
  674. snprint(buf, sizeof(buf), "R%ld", (i->w >> 16) & 0xf);
  675. rn = rget(map, buf);
  676. if((i->w & (1<<24)) == 0) /* POSTIDX */
  677. return rn;
  678. if((i->w & (1<<25)) == 0) { /* OFFSET */
  679. if(i->w & (1U<<23))
  680. return rn + (i->w & BITS(0,11));
  681. return rn - (i->w & BITS(0,11));
  682. } else { /* REGOFF */
  683. uint32_t index = 0;
  684. uint8_t c;
  685. uint8_t rm;
  686. sprint(buf, "R%ld", i->w & 0xf);
  687. rm = rget(map, buf);
  688. switch((i->w & BITS(5,6)) >> 5) {
  689. case 0: index = rm << ((i->w & BITS(7,11)) >> 7); break;
  690. case 1: index = LSR(rm, ((i->w & BITS(7,11)) >> 7)); break;
  691. case 2: index = ASR(rm, ((i->w & BITS(7,11)) >> 7)); break;
  692. case 3:
  693. if((i->w & BITS(7,11)) == 0) {
  694. c = (rget(map, "PSR") >> 29) & 1;
  695. index = c << 31 | LSR(rm, 1);
  696. } else {
  697. index = ROR(rm, ((i->w & BITS(7,11)) >> 7));
  698. }
  699. break;
  700. }
  701. if(i->w & (1<<23))
  702. return rn + index;
  703. return rn - index;
  704. }
  705. }
  706. static uint64_t
  707. armfadd(Map *map, Rgetter rget, Instr *i, uint64_t pc)
  708. {
  709. char buf[8];
  710. int r;
  711. r = (i->w >> 12) & 0xf;
  712. if(r != 15 || !armcondpass(map, rget, (i->w >> 28) & 0xf))
  713. return pc+4;
  714. r = (i->w >> 16) & 0xf;
  715. sprint(buf, "R%d", r);
  716. return rget(map, buf) + armshiftval(map, rget, i);
  717. }
  718. static uint64_t
  719. armfbx(Map *map, Rgetter rget, Instr *i, uint64_t pc)
  720. {
  721. char buf[8];
  722. int r;
  723. if(!armcondpass(map, rget, (i->w>>28)&0xf))
  724. return pc+4;
  725. r = (i->w >> 0) & 0xf;
  726. sprint(buf, "R%d", r);
  727. return rget(map, buf);
  728. }
  729. static uint64_t
  730. armfmovm(Map *map, Rgetter rget, Instr *i, uint64_t pc)
  731. {
  732. uint32_t v;
  733. uint32_t addr;
  734. v = i->w & 1<<15;
  735. if(!v || !armcondpass(map, rget, (i->w>>28)&0xf))
  736. return pc+4;
  737. addr = armmaddr(map, rget, i) + nbits(i->w & BITS(0,15));
  738. if(get4(map, addr, &v) < 0) {
  739. werrstr("can't read addr: %r");
  740. return -1;
  741. }
  742. return v;
  743. }
  744. static uint64_t
  745. armfbranch(Map *map, Rgetter rget, Instr *i, uint64_t pc)
  746. {
  747. if(!armcondpass(map, rget, (i->w >> 28) & 0xf))
  748. return pc+4;
  749. return pc + (((signed long)i->w << 8) >> 6) + 8;
  750. }
  751. static uint64_t
  752. armfmov(Map *map, Rgetter rget, Instr *i, uint64_t pc)
  753. {
  754. uint32_t rd, v;
  755. rd = (i->w >> 12) & 0xf;
  756. if(rd != 15 || !armcondpass(map, rget, (i->w>>28)&0xf))
  757. return pc+4;
  758. /* LDR */
  759. /* BUG: Needs LDH/B, too */
  760. if(((i->w>>26)&0x3) == 1) {
  761. if(get4(map, armaddr(map, rget, i), &v) < 0) {
  762. werrstr("can't read instruction: %r");
  763. return pc+4;
  764. }
  765. return v;
  766. }
  767. /* MOV */
  768. v = armshiftval(map, rget, i);
  769. return v;
  770. }
  771. static Opcode opcodes[] =
  772. {
  773. "AND%C%S", armdps, 0, "R%s,R%n,R%d",
  774. "EOR%C%S", armdps, 0, "R%s,R%n,R%d",
  775. "SUB%C%S", armdps, 0, "R%s,R%n,R%d",
  776. "RSB%C%S", armdps, 0, "R%s,R%n,R%d",
  777. "ADD%C%S", armdps, armfadd, "R%s,R%n,R%d",
  778. "ADC%C%S", armdps, 0, "R%s,R%n,R%d",
  779. "SBC%C%S", armdps, 0, "R%s,R%n,R%d",
  780. "RSC%C%S", armdps, 0, "R%s,R%n,R%d",
  781. "TST%C%S", armdps, 0, "R%s,R%n",
  782. "TEQ%C%S", armdps, 0, "R%s,R%n",
  783. "CMP%C%S", armdps, 0, "R%s,R%n",
  784. "CMN%C%S", armdps, 0, "R%s,R%n",
  785. "ORR%C%S", armdps, 0, "R%s,R%n,R%d",
  786. "MOVW%C%S", armdps, armfmov, "R%s,R%d",
  787. "BIC%C%S", armdps, 0, "R%s,R%n,R%d",
  788. "MVN%C%S", armdps, 0, "R%s,R%d",
  789. /* 16 */
  790. "AND%C%S", armdps, 0, "(R%s%h%m),R%n,R%d",
  791. "EOR%C%S", armdps, 0, "(R%s%h%m),R%n,R%d",
  792. "SUB%C%S", armdps, 0, "(R%s%h%m),R%n,R%d",
  793. "RSB%C%S", armdps, 0, "(R%s%h%m),R%n,R%d",
  794. "ADD%C%S", armdps, armfadd, "(R%s%h%m),R%n,R%d",
  795. "ADC%C%S", armdps, 0, "(R%s%h%m),R%n,R%d",
  796. "SBC%C%S", armdps, 0, "(R%s%h%m),R%n,R%d",
  797. "RSC%C%S", armdps, 0, "(R%s%h%m),R%n,R%d",
  798. "TST%C%S", armdps, 0, "(R%s%h%m),R%n",
  799. "TEQ%C%S", armdps, 0, "(R%s%h%m),R%n",
  800. "CMP%C%S", armdps, 0, "(R%s%h%m),R%n",
  801. "CMN%C%S", armdps, 0, "(R%s%h%m),R%n",
  802. "ORR%C%S", armdps, 0, "(R%s%h%m),R%n,R%d",
  803. "MOVW%C%S", armdps, armfmov, "(R%s%h%m),R%d",
  804. "BIC%C%S", armdps, 0, "(R%s%h%m),R%n,R%d",
  805. "MVN%C%S", armdps, 0, "(R%s%h%m),R%d",
  806. /* 32 */
  807. "AND%C%S", armdps, 0, "(R%s%hR%M),R%n,R%d",
  808. "EOR%C%S", armdps, 0, "(R%s%hR%M),R%n,R%d",
  809. "SUB%C%S", armdps, 0, "(R%s%hR%M),R%n,R%d",
  810. "RSB%C%S", armdps, 0, "(R%s%hR%M),R%n,R%d",
  811. "ADD%C%S", armdps, armfadd, "(R%s%hR%M),R%n,R%d",
  812. "ADC%C%S", armdps, 0, "(R%s%hR%M),R%n,R%d",
  813. "SBC%C%S", armdps, 0, "(R%s%hR%M),R%n,R%d",
  814. "RSC%C%S", armdps, 0, "(R%s%hR%M),R%n,R%d",
  815. "TST%C%S", armdps, 0, "(R%s%hR%M),R%n",
  816. "TEQ%C%S", armdps, 0, "(R%s%hR%M),R%n",
  817. "CMP%C%S", armdps, 0, "(R%s%hR%M),R%n",
  818. "CMN%C%S", armdps, 0, "(R%s%hR%M),R%n",
  819. "ORR%C%S", armdps, 0, "(R%s%hR%M),R%n,R%d",
  820. "MOVW%C%S", armdps, armfmov, "(R%s%hR%M),R%d",
  821. "BIC%C%S", armdps, 0, "(R%s%hR%M),R%n,R%d",
  822. "MVN%C%S", armdps, 0, "(R%s%hR%M),R%d",
  823. /* 48 */
  824. "AND%C%S", armdpi, 0, "$#%i,R%n,R%d",
  825. "EOR%C%S", armdpi, 0, "$#%i,R%n,R%d",
  826. "SUB%C%S", armdpi, 0, "$#%i,R%n,R%d",
  827. "RSB%C%S", armdpi, 0, "$#%i,R%n,R%d",
  828. "ADD%C%S", armdpi, armfadd, "$#%i,R%n,R%d",
  829. "ADC%C%S", armdpi, 0, "$#%i,R%n,R%d",
  830. "SBC%C%S", armdpi, 0, "$#%i,R%n,R%d",
  831. "RSC%C%S", armdpi, 0, "$#%i,R%n,R%d",
  832. "TST%C%S", armdpi, 0, "$#%i,R%n",
  833. "TEQ%C%S", armdpi, 0, "$#%i,R%n",
  834. "CMP%C%S", armdpi, 0, "$#%i,R%n",
  835. "CMN%C%S", armdpi, 0, "$#%i,R%n",
  836. "ORR%C%S", armdpi, 0, "$#%i,R%n,R%d",
  837. "MOVW%C%S", armdpi, armfmov, "$#%i,R%d",
  838. "BIC%C%S", armdpi, 0, "$#%i,R%n,R%d",
  839. "MVN%C%S", armdpi, 0, "$#%i,R%d",
  840. /* 48+16 */
  841. "MUL%C%S", armdpi, 0, "R%M,R%s,R%n",
  842. "MULA%C%S", armdpi, 0, "R%M,R%s,R%n,R%d",
  843. "SWPW", armdpi, 0, "R%s,(R%n),R%d",
  844. "SWPB", armdpi, 0, "R%s,(R%n),R%d",
  845. /* 48+16+4 */
  846. "MOV%u%C%p", armhwby, 0, "R%d,(R%n%UR%M)",
  847. "MOV%u%C%p", armhwby, 0, "R%d,%I",
  848. "MOV%u%C%p", armhwby, armfmov, "(R%n%UR%M),R%d",
  849. "MOV%u%C%p", armhwby, armfmov, "%I,R%d",
  850. /* 48+24 */
  851. "MOVW%C%p", armsdti, 0, "R%d,%I",
  852. "MOVB%C%p", armsdti, 0, "R%d,%I",
  853. "MOVW%C%p", armsdti, armfmov, "%I,R%d",
  854. "MOVBU%C%p", armsdti, armfmov, "%I,R%d",
  855. "MOVW%C%p", armsdts, 0, "R%d,(R%s%h%m)(R%n)",
  856. "MOVB%C%p", armsdts, 0, "R%d,(R%s%h%m)(R%n)",
  857. "MOVW%C%p", armsdts, armfmov, "(R%s%h%m)(R%n),R%d",
  858. "MOVBU%C%p", armsdts, armfmov, "(R%s%h%m)(R%n),R%d",
  859. "MOVM%C%P%a", armbdt, armfmovm, "[%r],(R%n)",
  860. "MOVM%C%P%a", armbdt, armfmovm, "(R%n),[%r]",
  861. "B%C", armb, armfbranch, "%b",
  862. "BL%C", armb, armfbranch, "%b",
  863. "CDP%C", armco, 0, "",
  864. "CDP%C", armco, 0, "",
  865. "MCR%C", armco, 0, "",
  866. "MRC%C", armco, 0, "",
  867. /* 48+24+4+4+2+2+4 */
  868. "MULLU%C%S", armdpi, 0, "R%M,R%s,(R%n,R%d)",
  869. "MULALU%C%S", armdpi, 0, "R%M,R%s,(R%n,R%d)",
  870. "MULL%C%S", armdpi, 0, "R%M,R%s,(R%n,R%d)",
  871. "MULAL%C%S", armdpi, 0, "R%M,R%s,(R%n,R%d)",
  872. /* 48+24+4+4+2+2+4+4 = 92 */
  873. "UNK", armunk, 0, "",
  874. /* new v7 arch instructions */
  875. /* 93 */
  876. "LDREX", armdpi, 0, "(R%n),R%d",
  877. "STREX", armdpi, 0, "R%s,(R%n),R%d",
  878. "CLREX", armunk, 0, "",
  879. /* 96 */
  880. "DSB", armunk, 0, "",
  881. "DMB", armunk, 0, "",
  882. "ISB", armunk, 0, "",
  883. /* 99 */
  884. "RFEV7%P%a", armbdt, 0, "(R%n)",
  885. /* 100 */
  886. "MLA%f%C", armdps, 0, "F%s,F%n,F%d",
  887. "MLS%f%C", armdps, 0, "F%s,F%n,F%d",
  888. "NMLS%f%C", armdps, 0, "F%s,F%n,F%d",
  889. "NMLA%f%C", armdps, 0, "F%s,F%n,F%d",
  890. "MUL%f%C", armdps, 0, "F%s,F%n,F%d",
  891. "NMUL%f%C", armdps, 0, "F%s,F%n,F%d",
  892. "ADD%f%C", armdps, 0, "F%s,F%n,F%d",
  893. "SUB%f%C", armdps, 0, "F%s,F%n,F%d",
  894. "DIV%f%C", armdps, 0, "F%s,F%n,F%d",
  895. /* 109 */
  896. "MOV%f%C", armdps, 0, "F%s,F%d",
  897. "ABS%f%C", armdps, 0, "F%s,F%d",
  898. "NEG%f%C", armdps, 0, "F%s,F%d",
  899. "SQRT%f%C", armdps, 0, "F%s,F%d",
  900. "CMP%f%C", armdps, 0, "F%s,F%d",
  901. "CMPE%f%C", armdps, 0, "F%s,F%d",
  902. "CMP%f%C", armdps, 0, "$0.0,F%d",
  903. "CMPE%f%C", armdps, 0, "$0.0,F%d",
  904. /* 117 */
  905. "MOV%F%R%C", armdps, 0, "F%s,F%d",
  906. /* 118 */
  907. "MOVW%C", armdps, 0, "R%d,F%n",
  908. "MOVW%C", armdps, 0, "F%n,R%d",
  909. "MOVW%C", armdps, 0, "R%d,%x",
  910. "MOVW%C", armdps, 0, "%x,R%d",
  911. /* 122 */
  912. "MOV%f%C", armvstdi, 0, "F%d,%I",
  913. "MOV%f%C", armvstdi, 0, "%I,F%d",
  914. /* 124 */
  915. "BKPT%C", armbpt, 0, "$#%i",
  916. "BX%C", armdps, armfbx, "(R%s)",
  917. "BXJ%C", armdps, armfbx, "(R%s)",
  918. "BLX%C", armdps, armfbx, "(R%s)",
  919. };
  920. static void
  921. gaddr(Instr *i)
  922. {
  923. *i->curr++ = '$';
  924. i->curr += gsymoff(i->curr, i->end-i->curr, i->imm, CANY);
  925. }
  926. static char *mode[] = { 0, "IA", "DB", "IB" };
  927. static char *pw[] = { "P", "PW", 0, "W" };
  928. static char *sw[] = { 0, "W", "S", "SW" };
  929. static void
  930. format(char *mnemonic, Instr *i, char *f)
  931. {
  932. int j, k, m, n;
  933. int g;
  934. char *fmt;
  935. if(mnemonic)
  936. format(0, i, mnemonic);
  937. if(f == 0)
  938. return;
  939. if(mnemonic)
  940. if(i->curr < i->end)
  941. *i->curr++ = '\t';
  942. for ( ; *f && i->curr < i->end; f++) {
  943. if(*f != '%') {
  944. *i->curr++ = *f;
  945. continue;
  946. }
  947. switch (*++f) {
  948. case 'C': /* .CONDITION */
  949. if(cond[i->cond])
  950. bprint(i, ".%s", cond[i->cond]);
  951. break;
  952. case 'S': /* .STORE */
  953. if(i->store)
  954. bprint(i, ".S");
  955. break;
  956. case 'P': /* P & U bits for block move */
  957. n = (i->w >>23) & 0x3;
  958. if (mode[n])
  959. bprint(i, ".%s", mode[n]);
  960. break;
  961. case 'p': /* P & W bits for single data xfer*/
  962. if (pw[i->store])
  963. bprint(i, ".%s", pw[i->store]);
  964. break;
  965. case 'a': /* S & W bits for single data xfer*/
  966. if (sw[i->store])
  967. bprint(i, ".%s", sw[i->store]);
  968. break;
  969. case 's':
  970. bprint(i, "%d", i->rs & 0xf);
  971. break;
  972. case 'M':
  973. bprint(i, "%lud", (i->w>>8) & 0xf);
  974. break;
  975. case 'm':
  976. bprint(i, "%lud", (i->w>>7) & 0x1f);
  977. break;
  978. case 'h':
  979. bprint(i, shtype[(i->w>>5) & 0x3]);
  980. break;
  981. case 'u': /* Signed/unsigned Byte/Halfword */
  982. bprint(i, hb[(i->w>>5) & 0x3]);
  983. break;
  984. case 'I':
  985. if (i->rn == 13) {
  986. if (plocal(i))
  987. break;
  988. }
  989. g = 0;
  990. fmt = "#%lx(R%d)";
  991. if (i->rn == 15) {
  992. /* convert load of offset(PC) to a load immediate */
  993. if (get4(i->map, i->addr+i->imm+8, (uint32_t*)&i->imm) > 0)
  994. {
  995. g = 1;
  996. fmt = "";
  997. }
  998. }
  999. if (mach->sb)
  1000. {
  1001. if (i->rd == 11) {
  1002. uint32_t nxti;
  1003. if (get4(i->map, i->addr+4, &nxti) > 0) {
  1004. if ((nxti & 0x0e0f0fff) == 0x060c000b) {
  1005. i->imm += mach->sb;
  1006. g = 1;
  1007. fmt = "-SB";
  1008. }
  1009. }
  1010. }
  1011. if (i->rn == 12)
  1012. {
  1013. i->imm += mach->sb;
  1014. g = 1;
  1015. fmt = "-SB(SB)";
  1016. }
  1017. }
  1018. if (g)
  1019. {
  1020. gaddr(i);
  1021. bprint(i, fmt, i->rn);
  1022. }
  1023. else
  1024. bprint(i, fmt, i->imm, i->rn);
  1025. break;
  1026. case 'U': /* Add/subtract from base */
  1027. bprint(i, addsub[(i->w >> 23) & 1]);
  1028. break;
  1029. case 'n':
  1030. bprint(i, "%d", i->rn);
  1031. break;
  1032. case 'd':
  1033. bprint(i, "%d", i->rd);
  1034. break;
  1035. case 'i':
  1036. bprint(i, "%lux", i->imm);
  1037. break;
  1038. case 'b':
  1039. i->curr += symoff(i->curr, i->end-i->curr,
  1040. (uint32_t)i->imm, CTEXT);
  1041. break;
  1042. case 'g':
  1043. i->curr += gsymoff(i->curr, i->end-i->curr,
  1044. i->imm, CANY);
  1045. break;
  1046. case 'f':
  1047. switch((i->w >> 8) & 0xF){
  1048. case 10:
  1049. bprint(i, "F");
  1050. break;
  1051. case 11:
  1052. bprint(i, "D");
  1053. break;
  1054. }
  1055. break;
  1056. case 'F':
  1057. switch(((i->w >> 15) & 0xE) + ((i->w >> 8) & 0x1)){
  1058. case 0x0:
  1059. bprint(i, ((i->w >> 7) & 0x1)? "WF" : "WF.U");
  1060. break;
  1061. case 0x1:
  1062. bprint(i, ((i->w >> 7) & 0x1)? "WD" : "WD.U");
  1063. break;
  1064. case 0x8:
  1065. bprint(i, "FW.U");
  1066. break;
  1067. case 0x9:
  1068. bprint(i, "DW.U");
  1069. break;
  1070. case 0xA:
  1071. bprint(i, "FW");
  1072. break;
  1073. case 0xB:
  1074. bprint(i, "DW");
  1075. break;
  1076. case 0xE:
  1077. bprint(i, "FD");
  1078. break;
  1079. case 0xF:
  1080. bprint(i, "DF");
  1081. break;
  1082. }
  1083. break;
  1084. case 'R':
  1085. if(((i->w >> 7) & 0x1) == 0)
  1086. bprint(i, "R");
  1087. break;
  1088. case 'x':
  1089. switch(i->rn){
  1090. case 0:
  1091. bprint(i, "FPSID");
  1092. break;
  1093. case 1:
  1094. bprint(i, "FPSCR");
  1095. break;
  1096. case 2:
  1097. bprint(i, "FPEXC");
  1098. break;
  1099. default:
  1100. bprint(i, "FPS(%d)", i->rn);
  1101. break;
  1102. }
  1103. break;
  1104. case 'r':
  1105. n = i->imm&0xffff;
  1106. j = 0;
  1107. k = 0;
  1108. while(n) {
  1109. m = j;
  1110. while(n&0x1) {
  1111. j++;
  1112. n >>= 1;
  1113. }
  1114. if(j != m) {
  1115. if(k)
  1116. bprint(i, ",");
  1117. if(j == m+1)
  1118. bprint(i, "R%d", m);
  1119. else
  1120. bprint(i, "R%d-R%d", m, j-1);
  1121. k = 1;
  1122. }
  1123. j++;
  1124. n >>= 1;
  1125. }
  1126. break;
  1127. case '\0':
  1128. *i->curr++ = '%';
  1129. return;
  1130. default:
  1131. bprint(i, "%%%c", *f);
  1132. break;
  1133. }
  1134. }
  1135. *i->curr = 0;
  1136. }
  1137. static int
  1138. printins(Map *map, uint64_t pc, char *buf, int n)
  1139. {
  1140. Instr i;
  1141. i.curr = buf;
  1142. i.end = buf+n-1;
  1143. if(decode(map, pc, &i) < 0)
  1144. return -1;
  1145. (*opcodes[i.op].fmt)(&opcodes[i.op], &i);
  1146. return 4;
  1147. }
  1148. static int
  1149. arminst(Map *map, uint64_t pc, char modifier, char *buf, int n)
  1150. {
  1151. USED(modifier);
  1152. return printins(map, pc, buf, n);
  1153. }
  1154. static int
  1155. armdas(Map *map, uint64_t pc, char *buf, int n)
  1156. {
  1157. Instr i;
  1158. i.curr = buf;
  1159. i.end = buf+n;
  1160. if(decode(map, pc, &i) < 0)
  1161. return -1;
  1162. if(i.end-i.curr > 8)
  1163. i.curr = _hexify(buf, i.w, 7);
  1164. *i.curr = 0;
  1165. return 4;
  1166. }
  1167. static int
  1168. arminstlen(Map *map, uint64_t pc)
  1169. {
  1170. Instr i;
  1171. if(decode(map, pc, &i) < 0)
  1172. return -1;
  1173. return 4;
  1174. }
  1175. static int
  1176. armfoll(Map *map, uint64_t pc, Rgetter rget, uint64_t *foll)
  1177. {
  1178. uint64_t d;
  1179. Instr i;
  1180. if(decode(map, pc, &i) < 0)
  1181. return -1;
  1182. if(opcodes[i.op].foll) {
  1183. d = (*opcodes[i.op].foll)(map, rget, &i, pc);
  1184. if(d == -1)
  1185. return -1;
  1186. } else
  1187. d = pc+4;
  1188. foll[0] = d;
  1189. return 1;
  1190. }