unwind_decoder.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459
  1. /*
  2. * Copyright (C) 2000 Hewlett-Packard Co
  3. * Copyright (C) 2000 David Mosberger-Tang <davidm@hpl.hp.com>
  4. *
  5. * Generic IA-64 unwind info decoder.
  6. *
  7. * This file is used both by the Linux kernel and objdump. Please keep
  8. * the two copies of this file in sync.
  9. *
  10. * You need to customize the decoder by defining the following
  11. * macros/constants before including this file:
  12. *
  13. * Types:
  14. * unw_word Unsigned integer type with at least 64 bits
  15. *
  16. * Register names:
  17. * UNW_REG_BSP
  18. * UNW_REG_BSPSTORE
  19. * UNW_REG_FPSR
  20. * UNW_REG_LC
  21. * UNW_REG_PFS
  22. * UNW_REG_PR
  23. * UNW_REG_RNAT
  24. * UNW_REG_PSP
  25. * UNW_REG_RP
  26. * UNW_REG_UNAT
  27. *
  28. * Decoder action macros:
  29. * UNW_DEC_BAD_CODE(code)
  30. * UNW_DEC_ABI(fmt,abi,context,arg)
  31. * UNW_DEC_BR_GR(fmt,brmask,gr,arg)
  32. * UNW_DEC_BR_MEM(fmt,brmask,arg)
  33. * UNW_DEC_COPY_STATE(fmt,label,arg)
  34. * UNW_DEC_EPILOGUE(fmt,t,ecount,arg)
  35. * UNW_DEC_FRGR_MEM(fmt,grmask,frmask,arg)
  36. * UNW_DEC_FR_MEM(fmt,frmask,arg)
  37. * UNW_DEC_GR_GR(fmt,grmask,gr,arg)
  38. * UNW_DEC_GR_MEM(fmt,grmask,arg)
  39. * UNW_DEC_LABEL_STATE(fmt,label,arg)
  40. * UNW_DEC_MEM_STACK_F(fmt,t,size,arg)
  41. * UNW_DEC_MEM_STACK_V(fmt,t,arg)
  42. * UNW_DEC_PRIUNAT_GR(fmt,r,arg)
  43. * UNW_DEC_PRIUNAT_WHEN_GR(fmt,t,arg)
  44. * UNW_DEC_PRIUNAT_WHEN_MEM(fmt,t,arg)
  45. * UNW_DEC_PRIUNAT_WHEN_PSPREL(fmt,pspoff,arg)
  46. * UNW_DEC_PRIUNAT_WHEN_SPREL(fmt,spoff,arg)
  47. * UNW_DEC_PROLOGUE(fmt,body,rlen,arg)
  48. * UNW_DEC_PROLOGUE_GR(fmt,rlen,mask,grsave,arg)
  49. * UNW_DEC_REG_PSPREL(fmt,reg,pspoff,arg)
  50. * UNW_DEC_REG_REG(fmt,src,dst,arg)
  51. * UNW_DEC_REG_SPREL(fmt,reg,spoff,arg)
  52. * UNW_DEC_REG_WHEN(fmt,reg,t,arg)
  53. * UNW_DEC_RESTORE(fmt,t,abreg,arg)
  54. * UNW_DEC_RESTORE_P(fmt,qp,t,abreg,arg)
  55. * UNW_DEC_SPILL_BASE(fmt,pspoff,arg)
  56. * UNW_DEC_SPILL_MASK(fmt,imaskp,arg)
  57. * UNW_DEC_SPILL_PSPREL(fmt,t,abreg,pspoff,arg)
  58. * UNW_DEC_SPILL_PSPREL_P(fmt,qp,t,abreg,pspoff,arg)
  59. * UNW_DEC_SPILL_REG(fmt,t,abreg,x,ytreg,arg)
  60. * UNW_DEC_SPILL_REG_P(fmt,qp,t,abreg,x,ytreg,arg)
  61. * UNW_DEC_SPILL_SPREL(fmt,t,abreg,spoff,arg)
  62. * UNW_DEC_SPILL_SPREL_P(fmt,qp,t,abreg,pspoff,arg)
  63. */
  64. static unw_word
  65. unw_decode_uleb128 (unsigned char **dpp)
  66. {
  67. unsigned shift = 0;
  68. unw_word byte, result = 0;
  69. unsigned char *bp = *dpp;
  70. while (1)
  71. {
  72. byte = *bp++;
  73. result |= (byte & 0x7f) << shift;
  74. if ((byte & 0x80) == 0)
  75. break;
  76. shift += 7;
  77. }
  78. *dpp = bp;
  79. return result;
  80. }
  81. static unsigned char *
  82. unw_decode_x1 (unsigned char *dp, unsigned char code, void *arg)
  83. {
  84. unsigned char byte1, abreg;
  85. unw_word t, off;
  86. byte1 = *dp++;
  87. t = unw_decode_uleb128 (&dp);
  88. off = unw_decode_uleb128 (&dp);
  89. abreg = (byte1 & 0x7f);
  90. if (byte1 & 0x80)
  91. UNW_DEC_SPILL_SPREL(X1, t, abreg, off, arg);
  92. else
  93. UNW_DEC_SPILL_PSPREL(X1, t, abreg, off, arg);
  94. return dp;
  95. }
  96. static unsigned char *
  97. unw_decode_x2 (unsigned char *dp, unsigned char code, void *arg)
  98. {
  99. unsigned char byte1, byte2, abreg, x, ytreg;
  100. unw_word t;
  101. byte1 = *dp++; byte2 = *dp++;
  102. t = unw_decode_uleb128 (&dp);
  103. abreg = (byte1 & 0x7f);
  104. ytreg = byte2;
  105. x = (byte1 >> 7) & 1;
  106. if ((byte1 & 0x80) == 0 && ytreg == 0)
  107. UNW_DEC_RESTORE(X2, t, abreg, arg);
  108. else
  109. UNW_DEC_SPILL_REG(X2, t, abreg, x, ytreg, arg);
  110. return dp;
  111. }
  112. static unsigned char *
  113. unw_decode_x3 (unsigned char *dp, unsigned char code, void *arg)
  114. {
  115. unsigned char byte1, byte2, abreg, qp;
  116. unw_word t, off;
  117. byte1 = *dp++; byte2 = *dp++;
  118. t = unw_decode_uleb128 (&dp);
  119. off = unw_decode_uleb128 (&dp);
  120. qp = (byte1 & 0x3f);
  121. abreg = (byte2 & 0x7f);
  122. if (byte1 & 0x80)
  123. UNW_DEC_SPILL_SPREL_P(X3, qp, t, abreg, off, arg);
  124. else
  125. UNW_DEC_SPILL_PSPREL_P(X3, qp, t, abreg, off, arg);
  126. return dp;
  127. }
  128. static unsigned char *
  129. unw_decode_x4 (unsigned char *dp, unsigned char code, void *arg)
  130. {
  131. unsigned char byte1, byte2, byte3, qp, abreg, x, ytreg;
  132. unw_word t;
  133. byte1 = *dp++; byte2 = *dp++; byte3 = *dp++;
  134. t = unw_decode_uleb128 (&dp);
  135. qp = (byte1 & 0x3f);
  136. abreg = (byte2 & 0x7f);
  137. x = (byte2 >> 7) & 1;
  138. ytreg = byte3;
  139. if ((byte2 & 0x80) == 0 && byte3 == 0)
  140. UNW_DEC_RESTORE_P(X4, qp, t, abreg, arg);
  141. else
  142. UNW_DEC_SPILL_REG_P(X4, qp, t, abreg, x, ytreg, arg);
  143. return dp;
  144. }
  145. static unsigned char *
  146. unw_decode_r1 (unsigned char *dp, unsigned char code, void *arg)
  147. {
  148. int body = (code & 0x20) != 0;
  149. unw_word rlen;
  150. rlen = (code & 0x1f);
  151. UNW_DEC_PROLOGUE(R1, body, rlen, arg);
  152. return dp;
  153. }
  154. static unsigned char *
  155. unw_decode_r2 (unsigned char *dp, unsigned char code, void *arg)
  156. {
  157. unsigned char byte1, mask, grsave;
  158. unw_word rlen;
  159. byte1 = *dp++;
  160. mask = ((code & 0x7) << 1) | ((byte1 >> 7) & 1);
  161. grsave = (byte1 & 0x7f);
  162. rlen = unw_decode_uleb128 (&dp);
  163. UNW_DEC_PROLOGUE_GR(R2, rlen, mask, grsave, arg);
  164. return dp;
  165. }
  166. static unsigned char *
  167. unw_decode_r3 (unsigned char *dp, unsigned char code, void *arg)
  168. {
  169. unw_word rlen;
  170. rlen = unw_decode_uleb128 (&dp);
  171. UNW_DEC_PROLOGUE(R3, ((code & 0x3) == 1), rlen, arg);
  172. return dp;
  173. }
  174. static unsigned char *
  175. unw_decode_p1 (unsigned char *dp, unsigned char code, void *arg)
  176. {
  177. unsigned char brmask = (code & 0x1f);
  178. UNW_DEC_BR_MEM(P1, brmask, arg);
  179. return dp;
  180. }
  181. static unsigned char *
  182. unw_decode_p2_p5 (unsigned char *dp, unsigned char code, void *arg)
  183. {
  184. if ((code & 0x10) == 0)
  185. {
  186. unsigned char byte1 = *dp++;
  187. UNW_DEC_BR_GR(P2, ((code & 0xf) << 1) | ((byte1 >> 7) & 1),
  188. (byte1 & 0x7f), arg);
  189. }
  190. else if ((code & 0x08) == 0)
  191. {
  192. unsigned char byte1 = *dp++, r, dst;
  193. r = ((code & 0x7) << 1) | ((byte1 >> 7) & 1);
  194. dst = (byte1 & 0x7f);
  195. switch (r)
  196. {
  197. case 0: UNW_DEC_REG_GR(P3, UNW_REG_PSP, dst, arg); break;
  198. case 1: UNW_DEC_REG_GR(P3, UNW_REG_RP, dst, arg); break;
  199. case 2: UNW_DEC_REG_GR(P3, UNW_REG_PFS, dst, arg); break;
  200. case 3: UNW_DEC_REG_GR(P3, UNW_REG_PR, dst, arg); break;
  201. case 4: UNW_DEC_REG_GR(P3, UNW_REG_UNAT, dst, arg); break;
  202. case 5: UNW_DEC_REG_GR(P3, UNW_REG_LC, dst, arg); break;
  203. case 6: UNW_DEC_RP_BR(P3, dst, arg); break;
  204. case 7: UNW_DEC_REG_GR(P3, UNW_REG_RNAT, dst, arg); break;
  205. case 8: UNW_DEC_REG_GR(P3, UNW_REG_BSP, dst, arg); break;
  206. case 9: UNW_DEC_REG_GR(P3, UNW_REG_BSPSTORE, dst, arg); break;
  207. case 10: UNW_DEC_REG_GR(P3, UNW_REG_FPSR, dst, arg); break;
  208. case 11: UNW_DEC_PRIUNAT_GR(P3, dst, arg); break;
  209. default: UNW_DEC_BAD_CODE(r); break;
  210. }
  211. }
  212. else if ((code & 0x7) == 0)
  213. UNW_DEC_SPILL_MASK(P4, dp, arg);
  214. else if ((code & 0x7) == 1)
  215. {
  216. unw_word grmask, frmask, byte1, byte2, byte3;
  217. byte1 = *dp++; byte2 = *dp++; byte3 = *dp++;
  218. grmask = ((byte1 >> 4) & 0xf);
  219. frmask = ((byte1 & 0xf) << 16) | (byte2 << 8) | byte3;
  220. UNW_DEC_FRGR_MEM(P5, grmask, frmask, arg);
  221. }
  222. else
  223. UNW_DEC_BAD_CODE(code);
  224. return dp;
  225. }
  226. static unsigned char *
  227. unw_decode_p6 (unsigned char *dp, unsigned char code, void *arg)
  228. {
  229. int gregs = (code & 0x10) != 0;
  230. unsigned char mask = (code & 0x0f);
  231. if (gregs)
  232. UNW_DEC_GR_MEM(P6, mask, arg);
  233. else
  234. UNW_DEC_FR_MEM(P6, mask, arg);
  235. return dp;
  236. }
  237. static unsigned char *
  238. unw_decode_p7_p10 (unsigned char *dp, unsigned char code, void *arg)
  239. {
  240. unsigned char r, byte1, byte2;
  241. unw_word t, size;
  242. if ((code & 0x10) == 0)
  243. {
  244. r = (code & 0xf);
  245. t = unw_decode_uleb128 (&dp);
  246. switch (r)
  247. {
  248. case 0:
  249. size = unw_decode_uleb128 (&dp);
  250. UNW_DEC_MEM_STACK_F(P7, t, size, arg);
  251. break;
  252. case 1: UNW_DEC_MEM_STACK_V(P7, t, arg); break;
  253. case 2: UNW_DEC_SPILL_BASE(P7, t, arg); break;
  254. case 3: UNW_DEC_REG_SPREL(P7, UNW_REG_PSP, t, arg); break;
  255. case 4: UNW_DEC_REG_WHEN(P7, UNW_REG_RP, t, arg); break;
  256. case 5: UNW_DEC_REG_PSPREL(P7, UNW_REG_RP, t, arg); break;
  257. case 6: UNW_DEC_REG_WHEN(P7, UNW_REG_PFS, t, arg); break;
  258. case 7: UNW_DEC_REG_PSPREL(P7, UNW_REG_PFS, t, arg); break;
  259. case 8: UNW_DEC_REG_WHEN(P7, UNW_REG_PR, t, arg); break;
  260. case 9: UNW_DEC_REG_PSPREL(P7, UNW_REG_PR, t, arg); break;
  261. case 10: UNW_DEC_REG_WHEN(P7, UNW_REG_LC, t, arg); break;
  262. case 11: UNW_DEC_REG_PSPREL(P7, UNW_REG_LC, t, arg); break;
  263. case 12: UNW_DEC_REG_WHEN(P7, UNW_REG_UNAT, t, arg); break;
  264. case 13: UNW_DEC_REG_PSPREL(P7, UNW_REG_UNAT, t, arg); break;
  265. case 14: UNW_DEC_REG_WHEN(P7, UNW_REG_FPSR, t, arg); break;
  266. case 15: UNW_DEC_REG_PSPREL(P7, UNW_REG_FPSR, t, arg); break;
  267. default: UNW_DEC_BAD_CODE(r); break;
  268. }
  269. }
  270. else
  271. {
  272. switch (code & 0xf)
  273. {
  274. case 0x0: /* p8 */
  275. {
  276. r = *dp++;
  277. t = unw_decode_uleb128 (&dp);
  278. switch (r)
  279. {
  280. case 1: UNW_DEC_REG_SPREL(P8, UNW_REG_RP, t, arg); break;
  281. case 2: UNW_DEC_REG_SPREL(P8, UNW_REG_PFS, t, arg); break;
  282. case 3: UNW_DEC_REG_SPREL(P8, UNW_REG_PR, t, arg); break;
  283. case 4: UNW_DEC_REG_SPREL(P8, UNW_REG_LC, t, arg); break;
  284. case 5: UNW_DEC_REG_SPREL(P8, UNW_REG_UNAT, t, arg); break;
  285. case 6: UNW_DEC_REG_SPREL(P8, UNW_REG_FPSR, t, arg); break;
  286. case 7: UNW_DEC_REG_WHEN(P8, UNW_REG_BSP, t, arg); break;
  287. case 8: UNW_DEC_REG_PSPREL(P8, UNW_REG_BSP, t, arg); break;
  288. case 9: UNW_DEC_REG_SPREL(P8, UNW_REG_BSP, t, arg); break;
  289. case 10: UNW_DEC_REG_WHEN(P8, UNW_REG_BSPSTORE, t, arg); break;
  290. case 11: UNW_DEC_REG_PSPREL(P8, UNW_REG_BSPSTORE, t, arg); break;
  291. case 12: UNW_DEC_REG_SPREL(P8, UNW_REG_BSPSTORE, t, arg); break;
  292. case 13: UNW_DEC_REG_WHEN(P8, UNW_REG_RNAT, t, arg); break;
  293. case 14: UNW_DEC_REG_PSPREL(P8, UNW_REG_RNAT, t, arg); break;
  294. case 15: UNW_DEC_REG_SPREL(P8, UNW_REG_RNAT, t, arg); break;
  295. case 16: UNW_DEC_PRIUNAT_WHEN_GR(P8, t, arg); break;
  296. case 17: UNW_DEC_PRIUNAT_PSPREL(P8, t, arg); break;
  297. case 18: UNW_DEC_PRIUNAT_SPREL(P8, t, arg); break;
  298. case 19: UNW_DEC_PRIUNAT_WHEN_MEM(P8, t, arg); break;
  299. default: UNW_DEC_BAD_CODE(r); break;
  300. }
  301. }
  302. break;
  303. case 0x1:
  304. byte1 = *dp++; byte2 = *dp++;
  305. UNW_DEC_GR_GR(P9, (byte1 & 0xf), (byte2 & 0x7f), arg);
  306. break;
  307. case 0xf: /* p10 */
  308. byte1 = *dp++; byte2 = *dp++;
  309. UNW_DEC_ABI(P10, byte1, byte2, arg);
  310. break;
  311. case 0x9:
  312. return unw_decode_x1 (dp, code, arg);
  313. case 0xa:
  314. return unw_decode_x2 (dp, code, arg);
  315. case 0xb:
  316. return unw_decode_x3 (dp, code, arg);
  317. case 0xc:
  318. return unw_decode_x4 (dp, code, arg);
  319. default:
  320. UNW_DEC_BAD_CODE(code);
  321. break;
  322. }
  323. }
  324. return dp;
  325. }
  326. static unsigned char *
  327. unw_decode_b1 (unsigned char *dp, unsigned char code, void *arg)
  328. {
  329. unw_word label = (code & 0x1f);
  330. if ((code & 0x20) != 0)
  331. UNW_DEC_COPY_STATE(B1, label, arg);
  332. else
  333. UNW_DEC_LABEL_STATE(B1, label, arg);
  334. return dp;
  335. }
  336. static unsigned char *
  337. unw_decode_b2 (unsigned char *dp, unsigned char code, void *arg)
  338. {
  339. unw_word t;
  340. t = unw_decode_uleb128 (&dp);
  341. UNW_DEC_EPILOGUE(B2, t, (code & 0x1f), arg);
  342. return dp;
  343. }
  344. static unsigned char *
  345. unw_decode_b3_x4 (unsigned char *dp, unsigned char code, void *arg)
  346. {
  347. unw_word t, ecount, label;
  348. if ((code & 0x10) == 0)
  349. {
  350. t = unw_decode_uleb128 (&dp);
  351. ecount = unw_decode_uleb128 (&dp);
  352. UNW_DEC_EPILOGUE(B3, t, ecount, arg);
  353. }
  354. else if ((code & 0x07) == 0)
  355. {
  356. label = unw_decode_uleb128 (&dp);
  357. if ((code & 0x08) != 0)
  358. UNW_DEC_COPY_STATE(B4, label, arg);
  359. else
  360. UNW_DEC_LABEL_STATE(B4, label, arg);
  361. }
  362. else
  363. switch (code & 0x7)
  364. {
  365. case 1: return unw_decode_x1 (dp, code, arg);
  366. case 2: return unw_decode_x2 (dp, code, arg);
  367. case 3: return unw_decode_x3 (dp, code, arg);
  368. case 4: return unw_decode_x4 (dp, code, arg);
  369. default: UNW_DEC_BAD_CODE(code); break;
  370. }
  371. return dp;
  372. }
  373. typedef unsigned char *(*unw_decoder) (unsigned char *, unsigned char, void *);
  374. static unw_decoder unw_decode_table[2][8] =
  375. {
  376. /* prologue table: */
  377. {
  378. unw_decode_r1, /* 0 */
  379. unw_decode_r1,
  380. unw_decode_r2,
  381. unw_decode_r3,
  382. unw_decode_p1, /* 4 */
  383. unw_decode_p2_p5,
  384. unw_decode_p6,
  385. unw_decode_p7_p10
  386. },
  387. {
  388. unw_decode_r1, /* 0 */
  389. unw_decode_r1,
  390. unw_decode_r2,
  391. unw_decode_r3,
  392. unw_decode_b1, /* 4 */
  393. unw_decode_b1,
  394. unw_decode_b2,
  395. unw_decode_b3_x4
  396. }
  397. };
  398. /*
  399. * Decode one descriptor and return address of next descriptor.
  400. */
  401. static inline unsigned char *
  402. unw_decode (unsigned char *dp, int inside_body, void *arg)
  403. {
  404. unw_decoder decoder;
  405. unsigned char code;
  406. code = *dp++;
  407. decoder = unw_decode_table[inside_body][code >> 5];
  408. dp = (*decoder) (dp, code, arg);
  409. return dp;
  410. }