unwind_decoder.c 12 KB

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