unwind-ia64.c 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164
  1. /* unwind-ia64.c -- utility routines to dump IA-64 unwind info for readelf.
  2. Copyright (C) 2000-2022 Free Software Foundation, Inc.
  3. Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
  4. This file is part of GNU Binutils.
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 3, or (at your option)
  8. any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, 51 Franklin Street - Fifth Floor, Boston,
  16. MA 02110-1301, USA. */
  17. #include "config.h"
  18. #include "sysdep.h"
  19. #include "unwind-ia64.h"
  20. #if __GNUC__ >= 2
  21. /* Define BFD64 here, even if our default architecture is 32 bit ELF
  22. as this will allow us to read in and parse 64bit and 32bit ELF files.
  23. Only do this if we believe that the compiler can support a 64 bit
  24. data type. For now we only rely on GCC being able to do this. */
  25. #define BFD64
  26. #endif
  27. #include "bfd.h"
  28. static bfd_vma unw_rlen = 0;
  29. static void unw_print_brmask (char *, unsigned int);
  30. static void unw_print_grmask (char *, unsigned int);
  31. static void unw_print_frmask (char *, unsigned int);
  32. static void unw_print_abreg (char *, unsigned int);
  33. static void unw_print_xyreg (char *, unsigned int, unsigned int);
  34. static void
  35. unw_print_brmask (char *cp, unsigned int mask)
  36. {
  37. int sep = 0;
  38. int i;
  39. for (i = 0; mask && (i < 5); ++i)
  40. {
  41. if (mask & 1)
  42. {
  43. if (sep)
  44. *cp++ = ',';
  45. *cp++ = 'b';
  46. *cp++ = i + 1 + '0';
  47. sep = 1;
  48. }
  49. mask >>= 1;
  50. }
  51. *cp = '\0';
  52. }
  53. static void
  54. unw_print_grmask (char *cp, unsigned int mask)
  55. {
  56. int sep = 0;
  57. int i;
  58. for (i = 0; i < 4; ++i)
  59. {
  60. if (mask & 1)
  61. {
  62. if (sep)
  63. *cp++ = ',';
  64. *cp++ = 'r';
  65. *cp++ = i + 4 + '0';
  66. sep = 1;
  67. }
  68. mask >>= 1;
  69. }
  70. *cp = '\0';
  71. }
  72. static void
  73. unw_print_frmask (char *cp, unsigned int mask)
  74. {
  75. int sep = 0;
  76. int i;
  77. for (i = 0; i < 20; ++i)
  78. {
  79. if (mask & 1)
  80. {
  81. if (sep)
  82. *cp++ = ',';
  83. *cp++ = 'f';
  84. if (i < 4)
  85. *cp++ = i + 2 + '0';
  86. else
  87. {
  88. *cp++ = (i + 2) / 10 + 1 + '0';
  89. *cp++ = (i + 2) % 10 + '0';
  90. }
  91. sep = 1;
  92. }
  93. mask >>= 1;
  94. }
  95. *cp = '\0';
  96. }
  97. static void
  98. unw_print_abreg (char *cp, unsigned int abreg)
  99. {
  100. static const char * const special_reg[16] =
  101. {
  102. "pr", "psp", "@priunat", "rp", "ar.bsp", "ar.bspstore", "ar.rnat",
  103. "ar.unat", "ar.fpsr", "ar.pfs", "ar.lc",
  104. "Unknown11", "Unknown12", "Unknown13", "Unknown14", "Unknown15"
  105. };
  106. switch ((abreg >> 5) & 0x3)
  107. {
  108. case 0: /* gr */
  109. sprintf (cp, "r%u", (abreg & 0x1f));
  110. break;
  111. case 1: /* fr */
  112. sprintf (cp, "f%u", (abreg & 0x1f));
  113. break;
  114. case 2: /* br */
  115. sprintf (cp, "b%u", (abreg & 0x1f));
  116. break;
  117. case 3: /* special */
  118. strcpy (cp, special_reg[abreg & 0xf]);
  119. break;
  120. }
  121. }
  122. static void
  123. unw_print_xyreg (char *cp, unsigned int x, unsigned int ytreg)
  124. {
  125. switch ((x << 1) | ((ytreg >> 7) & 1))
  126. {
  127. case 0: /* gr */
  128. sprintf (cp, "r%u", (ytreg & 0x1f));
  129. break;
  130. case 1: /* fr */
  131. sprintf (cp, "f%u", (ytreg & 0x1f));
  132. break;
  133. case 2: /* br */
  134. sprintf (cp, "b%u", (ytreg & 0x1f));
  135. break;
  136. default:
  137. strcpy (cp, "invalid");
  138. break;
  139. }
  140. }
  141. #define UNW_REG_BSP "bsp"
  142. #define UNW_REG_BSPSTORE "bspstore"
  143. #define UNW_REG_FPSR "fpsr"
  144. #define UNW_REG_LC "lc"
  145. #define UNW_REG_PFS "pfs"
  146. #define UNW_REG_PR "pr"
  147. #define UNW_REG_PSP "psp"
  148. #define UNW_REG_RNAT "rnat"
  149. #define UNW_REG_RP "rp"
  150. #define UNW_REG_UNAT "unat"
  151. typedef bfd_vma unw_word;
  152. #define UNW_DEC_BAD_CODE(code) \
  153. printf (_("Unknown code 0x%02x\n"), code)
  154. #define UNW_DEC_PROLOGUE(fmt, body, rlen, arg) \
  155. do \
  156. { \
  157. unw_rlen = rlen; \
  158. *(int *)arg = body; \
  159. printf (" %s:%s(rlen=%lu)\n", \
  160. fmt, body ? "body" : "prologue", (unsigned long) rlen); \
  161. } \
  162. while (0)
  163. #define UNW_DEC_PROLOGUE_GR(fmt, rlen, mask, grsave, arg) \
  164. do \
  165. { \
  166. char regname[16], maskstr[64], *sep; \
  167. \
  168. unw_rlen = rlen; \
  169. *(int *)arg = 0; \
  170. \
  171. maskstr[0] = '\0'; \
  172. sep = ""; \
  173. if (mask & 0x8) \
  174. { \
  175. strcat (maskstr, "rp"); \
  176. sep = ","; \
  177. } \
  178. if (mask & 0x4) \
  179. { \
  180. strcat (maskstr, sep); \
  181. strcat (maskstr, "ar.pfs"); \
  182. sep = ","; \
  183. } \
  184. if (mask & 0x2) \
  185. { \
  186. strcat (maskstr, sep); \
  187. strcat (maskstr, "psp"); \
  188. sep = ","; \
  189. } \
  190. if (mask & 0x1) \
  191. { \
  192. strcat (maskstr, sep); \
  193. strcat (maskstr, "pr"); \
  194. } \
  195. sprintf (regname, "r%u", grsave); \
  196. printf (" %s:prologue_gr(mask=[%s],grsave=%s,rlen=%lu)\n", \
  197. fmt, maskstr, regname, (unsigned long) rlen); \
  198. } \
  199. while (0)
  200. #define UNW_DEC_FR_MEM(fmt, frmask, arg) \
  201. do \
  202. { \
  203. char frstr[200]; \
  204. \
  205. unw_print_frmask (frstr, frmask); \
  206. printf ("\t%s:fr_mem(frmask=[%s])\n", fmt, frstr); \
  207. } \
  208. while (0)
  209. #define UNW_DEC_GR_MEM(fmt, grmask, arg) \
  210. do \
  211. { \
  212. char grstr[200]; \
  213. \
  214. unw_print_grmask (grstr, grmask); \
  215. printf ("\t%s:gr_mem(grmask=[%s])\n", fmt, grstr); \
  216. } \
  217. while (0)
  218. #define UNW_DEC_FRGR_MEM(fmt, grmask, frmask, arg) \
  219. do \
  220. { \
  221. char frstr[200], grstr[20]; \
  222. \
  223. unw_print_grmask (grstr, grmask); \
  224. unw_print_frmask (frstr, frmask); \
  225. printf ("\t%s:frgr_mem(grmask=[%s],frmask=[%s])\n", fmt, grstr, frstr); \
  226. } \
  227. while (0)
  228. #define UNW_DEC_BR_MEM(fmt, brmask, arg) \
  229. do \
  230. { \
  231. char brstr[20]; \
  232. \
  233. unw_print_brmask (brstr, brmask); \
  234. printf ("\t%s:br_mem(brmask=[%s])\n", fmt, brstr); \
  235. } \
  236. while (0)
  237. #define UNW_DEC_BR_GR(fmt, brmask, gr, arg) \
  238. do \
  239. { \
  240. char brstr[20]; \
  241. \
  242. unw_print_brmask (brstr, brmask); \
  243. printf ("\t%s:br_gr(brmask=[%s],gr=r%u)\n", fmt, brstr, gr); \
  244. } \
  245. while (0)
  246. #define UNW_DEC_REG_GR(fmt, src, dst, arg) \
  247. printf ("\t%s:%s_gr(reg=r%u)\n", fmt, src, dst)
  248. #define UNW_DEC_RP_BR(fmt, dst, arg) \
  249. printf ("\t%s:rp_br(reg=b%u)\n", fmt, dst)
  250. #define UNW_DEC_REG_WHEN(fmt, reg, t, arg) \
  251. printf ("\t%s:%s_when(t=%lu)\n", fmt, reg, (unsigned long) t)
  252. #define UNW_DEC_REG_SPREL(fmt, reg, spoff, arg) \
  253. printf ("\t%s:%s_sprel(spoff=0x%lx)\n", \
  254. fmt, reg, 4*(unsigned long)spoff)
  255. #define UNW_DEC_REG_PSPREL(fmt, reg, pspoff, arg) \
  256. printf ("\t%s:%s_psprel(pspoff=0x10-0x%lx)\n", \
  257. fmt, reg, 4*(unsigned long)pspoff)
  258. #define UNW_DEC_GR_GR(fmt, grmask, gr, arg) \
  259. do \
  260. { \
  261. char grstr[20]; \
  262. \
  263. unw_print_grmask (grstr, grmask); \
  264. printf ("\t%s:gr_gr(grmask=[%s],r%u)\n", fmt, grstr, gr); \
  265. } \
  266. while (0)
  267. #define UNW_DEC_ABI(fmt, abi, context, arg) \
  268. do \
  269. { \
  270. static const char * const abiname[] = \
  271. { \
  272. "@svr4", "@hpux", "@nt" \
  273. }; \
  274. char buf[20]; \
  275. const char *abistr = buf; \
  276. \
  277. if (abi < 3) \
  278. abistr = abiname[abi]; \
  279. else \
  280. sprintf (buf, "0x%x", abi); \
  281. printf ("\t%s:unwabi(abi=%s,context=0x%02x)\n", \
  282. fmt, abistr, context); \
  283. } \
  284. while (0)
  285. #define UNW_DEC_PRIUNAT_GR(fmt, r, arg) \
  286. printf ("\t%s:priunat_gr(reg=r%u)\n", fmt, r)
  287. #define UNW_DEC_PRIUNAT_WHEN_GR(fmt, t, arg) \
  288. printf ("\t%s:priunat_when_gr(t=%lu)\n", fmt, (unsigned long) t)
  289. #define UNW_DEC_PRIUNAT_WHEN_MEM(fmt, t, arg) \
  290. printf ("\t%s:priunat_when_mem(t=%lu)\n", fmt, (unsigned long) t)
  291. #define UNW_DEC_PRIUNAT_PSPREL(fmt, pspoff, arg) \
  292. printf ("\t%s:priunat_psprel(pspoff=0x10-0x%lx)\n", \
  293. fmt, 4*(unsigned long)pspoff)
  294. #define UNW_DEC_PRIUNAT_SPREL(fmt, spoff, arg) \
  295. printf ("\t%s:priunat_sprel(spoff=0x%lx)\n", \
  296. fmt, 4*(unsigned long)spoff)
  297. #define UNW_DEC_MEM_STACK_F(fmt, t, size, arg) \
  298. printf ("\t%s:mem_stack_f(t=%lu,size=%lu)\n", \
  299. fmt, (unsigned long) t, 16*(unsigned long)size)
  300. #define UNW_DEC_MEM_STACK_V(fmt, t, arg) \
  301. printf ("\t%s:mem_stack_v(t=%lu)\n", fmt, (unsigned long) t)
  302. #define UNW_DEC_SPILL_BASE(fmt, pspoff, arg) \
  303. printf ("\t%s:spill_base(pspoff=0x10-0x%lx)\n", \
  304. fmt, 4*(unsigned long)pspoff)
  305. #define UNW_DEC_SPILL_MASK(fmt, dp, arg, end) \
  306. do \
  307. { \
  308. static const char *spill_type = "-frb"; \
  309. unsigned const char *imaskp = dp; \
  310. unsigned char mask = 0; \
  311. bfd_vma insn = 0; \
  312. \
  313. /* PR 18420. */ \
  314. if ((dp + (unw_rlen / 4)) > end) \
  315. { \
  316. printf (_("\nERROR: unwind length too long (0x%lx > 0x%lx)\n\n"), \
  317. (long) (unw_rlen / 4), (long)(end - dp)); \
  318. /* FIXME: Should we reset unw_rlen ? */ \
  319. break; \
  320. } \
  321. printf ("\t%s:spill_mask(imask=[", fmt); \
  322. for (insn = 0; insn < unw_rlen; ++insn) \
  323. { \
  324. if ((insn % 4) == 0) \
  325. mask = *imaskp++; \
  326. if (insn > 0 && (insn % 3) == 0) \
  327. putchar (','); \
  328. putchar (spill_type[(mask >> (2 * (3 - (insn & 0x3)))) & 0x3]); \
  329. } \
  330. printf ("])\n"); \
  331. dp = imaskp; \
  332. } \
  333. while (0)
  334. #define UNW_DEC_SPILL_SPREL(fmt, t, abreg, spoff, arg) \
  335. do \
  336. { \
  337. char regname[20]; \
  338. \
  339. unw_print_abreg (regname, abreg); \
  340. printf ("\t%s:spill_sprel(reg=%s,t=%lu,spoff=0x%lx)\n", \
  341. fmt, regname, (unsigned long) t, 4*(unsigned long)off); \
  342. } \
  343. while (0)
  344. #define UNW_DEC_SPILL_PSPREL(fmt, t, abreg, pspoff, arg) \
  345. do \
  346. { \
  347. char regname[20]; \
  348. \
  349. unw_print_abreg (regname, abreg); \
  350. printf ("\t%s:spill_psprel(reg=%s,t=%lu,pspoff=0x10-0x%lx)\n", \
  351. fmt, regname, (unsigned long) t, 4*(unsigned long)pspoff); \
  352. } \
  353. while (0)
  354. #define UNW_DEC_RESTORE(fmt, t, abreg, arg) \
  355. do \
  356. { \
  357. char regname[20]; \
  358. \
  359. unw_print_abreg (regname, abreg); \
  360. printf ("\t%s:restore(t=%lu,reg=%s)\n", \
  361. fmt, (unsigned long) t, regname); \
  362. } \
  363. while (0)
  364. #define UNW_DEC_SPILL_REG(fmt, t, abreg, x, ytreg, arg) \
  365. do \
  366. { \
  367. char abregname[20], tregname[20]; \
  368. \
  369. unw_print_abreg (abregname, abreg); \
  370. unw_print_xyreg (tregname, x, ytreg); \
  371. printf ("\t%s:spill_reg(t=%lu,reg=%s,treg=%s)\n", \
  372. fmt, (unsigned long) t, abregname, tregname); \
  373. } \
  374. while (0)
  375. #define UNW_DEC_SPILL_SPREL_P(fmt, qp, t, abreg, spoff, arg) \
  376. do \
  377. { \
  378. char regname[20]; \
  379. \
  380. unw_print_abreg (regname, abreg); \
  381. printf ("\t%s:spill_sprel_p(qp=p%u,t=%lu,reg=%s,spoff=0x%lx)\n", \
  382. fmt, qp, (unsigned long) t, regname, 4 * (unsigned long)spoff); \
  383. } \
  384. while (0)
  385. #define UNW_DEC_SPILL_PSPREL_P(fmt, qp, t, abreg, pspoff, arg) \
  386. do \
  387. { \
  388. char regname[20]; \
  389. \
  390. unw_print_abreg (regname, abreg); \
  391. printf ("\t%s:spill_psprel_p(qp=p%u,t=%lu,reg=%s,pspoff=0x10-0x%lx)\n",\
  392. fmt, qp, (unsigned long) t, regname, 4*(unsigned long)pspoff);\
  393. } \
  394. while (0)
  395. #define UNW_DEC_RESTORE_P(fmt, qp, t, abreg, arg) \
  396. do \
  397. { \
  398. char regname[20]; \
  399. \
  400. unw_print_abreg (regname, abreg); \
  401. printf ("\t%s:restore_p(qp=p%u,t=%lu,reg=%s)\n", \
  402. fmt, qp, (unsigned long) t, regname); \
  403. } \
  404. while (0)
  405. #define UNW_DEC_SPILL_REG_P(fmt, qp, t, abreg, x, ytreg, arg) \
  406. do \
  407. { \
  408. char regname[20], tregname[20]; \
  409. \
  410. unw_print_abreg (regname, abreg); \
  411. unw_print_xyreg (tregname, x, ytreg); \
  412. printf ("\t%s:spill_reg_p(qp=p%u,t=%lu,reg=%s,treg=%s)\n", \
  413. fmt, qp, (unsigned long) t, regname, tregname); \
  414. } \
  415. while (0)
  416. #define UNW_DEC_LABEL_STATE(fmt, label, arg) \
  417. printf ("\t%s:label_state(label=%lu)\n", fmt, (unsigned long) label)
  418. #define UNW_DEC_COPY_STATE(fmt, label, arg) \
  419. printf ("\t%s:copy_state(label=%lu)\n", fmt, (unsigned long) label)
  420. #define UNW_DEC_EPILOGUE(fmt, t, ecount, arg) \
  421. printf ("\t%s:epilogue(t=%lu,ecount=%lu)\n", \
  422. fmt, (unsigned long) t, (unsigned long) ecount)
  423. /*
  424. * Generic IA-64 unwind info decoder.
  425. *
  426. * This file is used both by the Linux kernel and objdump. Please
  427. * keep the two copies of this file in sync (modulo differences in the
  428. * prototypes...).
  429. *
  430. * You need to customize the decoder by defining the following
  431. * macros/constants before including this file:
  432. *
  433. * Types:
  434. * unw_word Unsigned integer type with at least 64 bits
  435. *
  436. * Register names:
  437. * UNW_REG_BSP
  438. * UNW_REG_BSPSTORE
  439. * UNW_REG_FPSR
  440. * UNW_REG_LC
  441. * UNW_REG_PFS
  442. * UNW_REG_PR
  443. * UNW_REG_RNAT
  444. * UNW_REG_PSP
  445. * UNW_REG_RP
  446. * UNW_REG_UNAT
  447. *
  448. * Decoder action macros:
  449. * UNW_DEC_BAD_CODE(code)
  450. * UNW_DEC_ABI(fmt,abi,context,arg)
  451. * UNW_DEC_BR_GR(fmt,brmask,gr,arg)
  452. * UNW_DEC_BR_MEM(fmt,brmask,arg)
  453. * UNW_DEC_COPY_STATE(fmt,label,arg)
  454. * UNW_DEC_EPILOGUE(fmt,t,ecount,arg)
  455. * UNW_DEC_FRGR_MEM(fmt,grmask,frmask,arg)
  456. * UNW_DEC_FR_MEM(fmt,frmask,arg)
  457. * UNW_DEC_GR_GR(fmt,grmask,gr,arg)
  458. * UNW_DEC_GR_MEM(fmt,grmask,arg)
  459. * UNW_DEC_LABEL_STATE(fmt,label,arg)
  460. * UNW_DEC_MEM_STACK_F(fmt,t,size,arg)
  461. * UNW_DEC_MEM_STACK_V(fmt,t,arg)
  462. * UNW_DEC_PRIUNAT_GR(fmt,r,arg)
  463. * UNW_DEC_PRIUNAT_WHEN_GR(fmt,t,arg)
  464. * UNW_DEC_PRIUNAT_WHEN_MEM(fmt,t,arg)
  465. * UNW_DEC_PRIUNAT_WHEN_PSPREL(fmt,pspoff,arg)
  466. * UNW_DEC_PRIUNAT_WHEN_SPREL(fmt,spoff,arg)
  467. * UNW_DEC_PROLOGUE(fmt,body,rlen,arg)
  468. * UNW_DEC_PROLOGUE_GR(fmt,rlen,mask,grsave,arg)
  469. * UNW_DEC_REG_PSPREL(fmt,reg,pspoff,arg)
  470. * UNW_DEC_REG_REG(fmt,src,dst,arg)
  471. * UNW_DEC_REG_SPREL(fmt,reg,spoff,arg)
  472. * UNW_DEC_REG_WHEN(fmt,reg,t,arg)
  473. * UNW_DEC_RESTORE(fmt,t,abreg,arg)
  474. * UNW_DEC_RESTORE_P(fmt,qp,t,abreg,arg)
  475. * UNW_DEC_SPILL_BASE(fmt,pspoff,arg)
  476. * UNW_DEC_SPILL_MASK(fmt,imaskp,arg)
  477. * UNW_DEC_SPILL_PSPREL(fmt,t,abreg,pspoff,arg)
  478. * UNW_DEC_SPILL_PSPREL_P(fmt,qp,t,abreg,pspoff,arg)
  479. * UNW_DEC_SPILL_REG(fmt,t,abreg,x,ytreg,arg)
  480. * UNW_DEC_SPILL_REG_P(fmt,qp,t,abreg,x,ytreg,arg)
  481. * UNW_DEC_SPILL_SPREL(fmt,t,abreg,spoff,arg)
  482. * UNW_DEC_SPILL_SPREL_P(fmt,qp,t,abreg,pspoff,arg)
  483. */
  484. static unw_word
  485. unw_decode_uleb128 (const unsigned char **dpp, const unsigned char * end)
  486. {
  487. unsigned shift = 0;
  488. int status = 1;
  489. unw_word byte, result = 0;
  490. const unsigned char *bp = *dpp;
  491. while (bp < end)
  492. {
  493. byte = *bp++;
  494. if (shift < sizeof (result) * 8)
  495. {
  496. result |= (byte & 0x7f) << shift;
  497. if ((result >> shift) != (byte & 0x7f))
  498. /* Overflow. */
  499. status |= 2;
  500. shift += 7;
  501. }
  502. else if ((byte & 0x7f) != 0)
  503. status |= 2;
  504. if ((byte & 0x80) == 0)
  505. {
  506. status &= ~1;
  507. break;
  508. }
  509. }
  510. *dpp = bp;
  511. if (status != 0)
  512. printf (_("Bad uleb128\n"));
  513. return result;
  514. }
  515. static const unsigned char *
  516. unw_decode_x1 (const unsigned char *dp, unsigned int code ATTRIBUTE_UNUSED,
  517. void *arg ATTRIBUTE_UNUSED, const unsigned char * end)
  518. {
  519. unsigned char byte1, abreg;
  520. unw_word t, off;
  521. if ((end - dp) < 3)
  522. {
  523. printf (_("\t<corrupt X1>\n"));
  524. return end;
  525. }
  526. byte1 = *dp++;
  527. t = unw_decode_uleb128 (&dp, end);
  528. off = unw_decode_uleb128 (&dp, end);
  529. abreg = (byte1 & 0x7f);
  530. if (byte1 & 0x80)
  531. UNW_DEC_SPILL_SPREL ("X1", t, abreg, off, arg);
  532. else
  533. UNW_DEC_SPILL_PSPREL ("X1", t, abreg, off, arg);
  534. return dp;
  535. }
  536. static const unsigned char *
  537. unw_decode_x2 (const unsigned char *dp, unsigned int code ATTRIBUTE_UNUSED,
  538. void *arg ATTRIBUTE_UNUSED, const unsigned char * end)
  539. {
  540. unsigned char byte1, byte2, abreg, x, ytreg;
  541. unw_word t;
  542. if ((end - dp) < 3)
  543. {
  544. printf (_("\t<corrupt X2>\n"));
  545. return end;
  546. }
  547. byte1 = *dp++;
  548. byte2 = *dp++;
  549. t = unw_decode_uleb128 (&dp, end);
  550. abreg = (byte1 & 0x7f);
  551. ytreg = byte2;
  552. x = (byte1 >> 7) & 1;
  553. if ((byte1 & 0x80) == 0 && ytreg == 0)
  554. UNW_DEC_RESTORE ("X2", t, abreg, arg);
  555. else
  556. UNW_DEC_SPILL_REG ("X2", t, abreg, x, ytreg, arg);
  557. return dp;
  558. }
  559. static const unsigned char *
  560. unw_decode_x3 (const unsigned char *dp, unsigned int code ATTRIBUTE_UNUSED,
  561. void *arg ATTRIBUTE_UNUSED, const unsigned char * end)
  562. {
  563. unsigned char byte1, byte2, abreg, qp;
  564. unw_word t, off;
  565. if ((end - dp) < 4)
  566. {
  567. printf (_("\t<corrupt X3>\n"));
  568. return end;
  569. }
  570. byte1 = *dp++;
  571. byte2 = *dp++;
  572. t = unw_decode_uleb128 (&dp, end);
  573. off = unw_decode_uleb128 (&dp, end);
  574. qp = (byte1 & 0x3f);
  575. abreg = (byte2 & 0x7f);
  576. if (byte1 & 0x80)
  577. UNW_DEC_SPILL_SPREL_P ("X3", qp, t, abreg, off, arg);
  578. else
  579. UNW_DEC_SPILL_PSPREL_P ("X3", qp, t, abreg, off, arg);
  580. return dp;
  581. }
  582. static const unsigned char *
  583. unw_decode_x4 (const unsigned char *dp, unsigned int code ATTRIBUTE_UNUSED,
  584. void *arg ATTRIBUTE_UNUSED, const unsigned char * end)
  585. {
  586. unsigned char byte1, byte2, byte3, qp, abreg, x, ytreg;
  587. unw_word t;
  588. if ((end - dp) < 4)
  589. {
  590. printf (_("\t<corrupt X4>\n"));
  591. return end;
  592. }
  593. byte1 = *dp++;
  594. byte2 = *dp++;
  595. byte3 = *dp++;
  596. t = unw_decode_uleb128 (&dp, end);
  597. qp = (byte1 & 0x3f);
  598. abreg = (byte2 & 0x7f);
  599. x = (byte2 >> 7) & 1;
  600. ytreg = byte3;
  601. if ((byte2 & 0x80) == 0 && byte3 == 0)
  602. UNW_DEC_RESTORE_P ("X4", qp, t, abreg, arg);
  603. else
  604. UNW_DEC_SPILL_REG_P ("X4", qp, t, abreg, x, ytreg, arg);
  605. return dp;
  606. }
  607. static const unsigned char *
  608. unw_decode_r1 (const unsigned char *dp, unsigned int code, void *arg,
  609. const unsigned char * end ATTRIBUTE_UNUSED)
  610. {
  611. int body = (code & 0x20) != 0;
  612. unw_word rlen;
  613. rlen = (code & 0x1f);
  614. UNW_DEC_PROLOGUE ("R1", body, rlen, arg);
  615. return dp;
  616. }
  617. static const unsigned char *
  618. unw_decode_r2 (const unsigned char *dp, unsigned int code, void *arg,
  619. const unsigned char * end)
  620. {
  621. unsigned char byte1, mask, grsave;
  622. unw_word rlen;
  623. if ((end - dp) < 2)
  624. {
  625. printf (_("\t<corrupt R2>\n"));
  626. return end;
  627. }
  628. byte1 = *dp++;
  629. mask = ((code & 0x7) << 1) | ((byte1 >> 7) & 1);
  630. grsave = (byte1 & 0x7f);
  631. rlen = unw_decode_uleb128 (& dp, end);
  632. UNW_DEC_PROLOGUE_GR ("R2", rlen, mask, grsave, arg);
  633. return dp;
  634. }
  635. static const unsigned char *
  636. unw_decode_r3 (const unsigned char *dp, unsigned int code, void *arg,
  637. const unsigned char * end)
  638. {
  639. unw_word rlen;
  640. rlen = unw_decode_uleb128 (& dp, end);
  641. UNW_DEC_PROLOGUE ("R3", ((code & 0x3) == 1), rlen, arg);
  642. return dp;
  643. }
  644. static const unsigned char *
  645. unw_decode_p1 (const unsigned char *dp, unsigned int code,
  646. void *arg ATTRIBUTE_UNUSED,
  647. const unsigned char * end ATTRIBUTE_UNUSED)
  648. {
  649. unsigned char brmask = (code & 0x1f);
  650. UNW_DEC_BR_MEM ("P1", brmask, arg);
  651. return dp;
  652. }
  653. static const unsigned char *
  654. unw_decode_p2_p5 (const unsigned char *dp, unsigned int code,
  655. void *arg ATTRIBUTE_UNUSED,
  656. const unsigned char * end)
  657. {
  658. if ((code & 0x10) == 0)
  659. {
  660. unsigned char byte1;
  661. if ((end - dp) < 1)
  662. {
  663. printf (_("\t<corrupt P2>\n"));
  664. return end;
  665. }
  666. byte1 = *dp++;
  667. UNW_DEC_BR_GR ("P2", ((code & 0xf) << 1) | ((byte1 >> 7) & 1),
  668. (byte1 & 0x7f), arg);
  669. }
  670. else if ((code & 0x08) == 0)
  671. {
  672. unsigned char byte1, r, dst;
  673. if ((end - dp) < 1)
  674. {
  675. printf (_("\t<corrupt P3>\n"));
  676. return end;
  677. }
  678. byte1 = *dp++;
  679. r = ((code & 0x7) << 1) | ((byte1 >> 7) & 1);
  680. dst = (byte1 & 0x7f);
  681. switch (r)
  682. {
  683. case 0:
  684. UNW_DEC_REG_GR ("P3", UNW_REG_PSP, dst, arg);
  685. break;
  686. case 1:
  687. UNW_DEC_REG_GR ("P3", UNW_REG_RP, dst, arg);
  688. break;
  689. case 2:
  690. UNW_DEC_REG_GR ("P3", UNW_REG_PFS, dst, arg);
  691. break;
  692. case 3:
  693. UNW_DEC_REG_GR ("P3", UNW_REG_PR, dst, arg);
  694. break;
  695. case 4:
  696. UNW_DEC_REG_GR ("P3", UNW_REG_UNAT, dst, arg);
  697. break;
  698. case 5:
  699. UNW_DEC_REG_GR ("P3", UNW_REG_LC, dst, arg);
  700. break;
  701. case 6:
  702. UNW_DEC_RP_BR ("P3", dst, arg);
  703. break;
  704. case 7:
  705. UNW_DEC_REG_GR ("P3", UNW_REG_RNAT, dst, arg);
  706. break;
  707. case 8:
  708. UNW_DEC_REG_GR ("P3", UNW_REG_BSP, dst, arg);
  709. break;
  710. case 9:
  711. UNW_DEC_REG_GR ("P3", UNW_REG_BSPSTORE, dst, arg);
  712. break;
  713. case 10:
  714. UNW_DEC_REG_GR ("P3", UNW_REG_FPSR, dst, arg);
  715. break;
  716. case 11:
  717. UNW_DEC_PRIUNAT_GR ("P3", dst, arg);
  718. break;
  719. default:
  720. UNW_DEC_BAD_CODE (r);
  721. break;
  722. }
  723. }
  724. else if ((code & 0x7) == 0)
  725. UNW_DEC_SPILL_MASK ("P4", dp, arg, end);
  726. else if ((code & 0x7) == 1)
  727. {
  728. unw_word grmask, frmask, byte1, byte2, byte3;
  729. if ((end - dp) < 3)
  730. {
  731. printf (_("\t<corrupt P5>\n"));
  732. return end;
  733. }
  734. byte1 = *dp++;
  735. byte2 = *dp++;
  736. byte3 = *dp++;
  737. grmask = ((byte1 >> 4) & 0xf);
  738. frmask = ((byte1 & 0xf) << 16) | (byte2 << 8) | byte3;
  739. UNW_DEC_FRGR_MEM ("P5", grmask, frmask, arg);
  740. }
  741. else
  742. UNW_DEC_BAD_CODE (code);
  743. return dp;
  744. }
  745. static const unsigned char *
  746. unw_decode_p6 (const unsigned char *dp, unsigned int code,
  747. void *arg ATTRIBUTE_UNUSED,
  748. const unsigned char * end ATTRIBUTE_UNUSED)
  749. {
  750. int gregs = (code & 0x10) != 0;
  751. unsigned char mask = (code & 0x0f);
  752. if (gregs)
  753. UNW_DEC_GR_MEM ("P6", mask, arg);
  754. else
  755. UNW_DEC_FR_MEM ("P6", mask, arg);
  756. return dp;
  757. }
  758. static const unsigned char *
  759. unw_decode_p7_p10 (const unsigned char *dp, unsigned int code, void *arg,
  760. const unsigned char * end)
  761. {
  762. unsigned char r, byte1, byte2;
  763. unw_word t, size;
  764. if ((code & 0x10) == 0)
  765. {
  766. r = (code & 0xf);
  767. t = unw_decode_uleb128 (&dp, end);
  768. switch (r)
  769. {
  770. case 0:
  771. size = unw_decode_uleb128 (&dp, end);
  772. UNW_DEC_MEM_STACK_F ("P7", t, size, arg);
  773. break;
  774. case 1:
  775. UNW_DEC_MEM_STACK_V ("P7", t, arg);
  776. break;
  777. case 2:
  778. UNW_DEC_SPILL_BASE ("P7", t, arg);
  779. break;
  780. case 3:
  781. UNW_DEC_REG_SPREL ("P7", UNW_REG_PSP, t, arg);
  782. break;
  783. case 4:
  784. UNW_DEC_REG_WHEN ("P7", UNW_REG_RP, t, arg);
  785. break;
  786. case 5:
  787. UNW_DEC_REG_PSPREL ("P7", UNW_REG_RP, t, arg);
  788. break;
  789. case 6:
  790. UNW_DEC_REG_WHEN ("P7", UNW_REG_PFS, t, arg);
  791. break;
  792. case 7:
  793. UNW_DEC_REG_PSPREL ("P7", UNW_REG_PFS, t, arg);
  794. break;
  795. case 8:
  796. UNW_DEC_REG_WHEN ("P7", UNW_REG_PR, t, arg);
  797. break;
  798. case 9:
  799. UNW_DEC_REG_PSPREL ("P7", UNW_REG_PR, t, arg);
  800. break;
  801. case 10:
  802. UNW_DEC_REG_WHEN ("P7", UNW_REG_LC, t, arg);
  803. break;
  804. case 11:
  805. UNW_DEC_REG_PSPREL ("P7", UNW_REG_LC, t, arg);
  806. break;
  807. case 12:
  808. UNW_DEC_REG_WHEN ("P7", UNW_REG_UNAT, t, arg);
  809. break;
  810. case 13:
  811. UNW_DEC_REG_PSPREL ("P7", UNW_REG_UNAT, t, arg);
  812. break;
  813. case 14:
  814. UNW_DEC_REG_WHEN ("P7", UNW_REG_FPSR, t, arg);
  815. break;
  816. case 15:
  817. UNW_DEC_REG_PSPREL ("P7", UNW_REG_FPSR, t, arg);
  818. break;
  819. default:
  820. UNW_DEC_BAD_CODE (r);
  821. break;
  822. }
  823. }
  824. else
  825. {
  826. switch (code & 0xf)
  827. {
  828. case 0x0: /* p8 */
  829. {
  830. if ((end - dp) < 2)
  831. {
  832. printf (_("\t<corrupt P8>\n"));
  833. return end;
  834. }
  835. r = *dp++;
  836. t = unw_decode_uleb128 (&dp, end);
  837. switch (r)
  838. {
  839. case 1:
  840. UNW_DEC_REG_SPREL ("P8", UNW_REG_RP, t, arg);
  841. break;
  842. case 2:
  843. UNW_DEC_REG_SPREL ("P8", UNW_REG_PFS, t, arg);
  844. break;
  845. case 3:
  846. UNW_DEC_REG_SPREL ("P8", UNW_REG_PR, t, arg);
  847. break;
  848. case 4:
  849. UNW_DEC_REG_SPREL ("P8", UNW_REG_LC, t, arg);
  850. break;
  851. case 5:
  852. UNW_DEC_REG_SPREL ("P8", UNW_REG_UNAT, t, arg);
  853. break;
  854. case 6:
  855. UNW_DEC_REG_SPREL ("P8", UNW_REG_FPSR, t, arg);
  856. break;
  857. case 7:
  858. UNW_DEC_REG_WHEN ("P8", UNW_REG_BSP, t, arg);
  859. break;
  860. case 8:
  861. UNW_DEC_REG_PSPREL ("P8", UNW_REG_BSP, t, arg);
  862. break;
  863. case 9:
  864. UNW_DEC_REG_SPREL ("P8", UNW_REG_BSP, t, arg);
  865. break;
  866. case 10:
  867. UNW_DEC_REG_WHEN ("P8", UNW_REG_BSPSTORE, t, arg);
  868. break;
  869. case 11:
  870. UNW_DEC_REG_PSPREL ("P8", UNW_REG_BSPSTORE, t, arg);
  871. break;
  872. case 12:
  873. UNW_DEC_REG_SPREL ("P8", UNW_REG_BSPSTORE, t, arg);
  874. break;
  875. case 13:
  876. UNW_DEC_REG_WHEN ("P8", UNW_REG_RNAT, t, arg);
  877. break;
  878. case 14:
  879. UNW_DEC_REG_PSPREL ("P8", UNW_REG_RNAT, t, arg);
  880. break;
  881. case 15:
  882. UNW_DEC_REG_SPREL ("P8", UNW_REG_RNAT, t, arg);
  883. break;
  884. case 16:
  885. UNW_DEC_PRIUNAT_WHEN_GR ("P8", t, arg);
  886. break;
  887. case 17:
  888. UNW_DEC_PRIUNAT_PSPREL ("P8", t, arg);
  889. break;
  890. case 18:
  891. UNW_DEC_PRIUNAT_SPREL ("P8", t, arg);
  892. break;
  893. case 19:
  894. UNW_DEC_PRIUNAT_WHEN_MEM ("P8", t, arg);
  895. break;
  896. default:
  897. UNW_DEC_BAD_CODE (r);
  898. break;
  899. }
  900. }
  901. break;
  902. case 0x1:
  903. if ((end - dp) < 2)
  904. {
  905. printf (_("\t<corrupt P9>\n"));
  906. return end;
  907. }
  908. byte1 = *dp++;
  909. byte2 = *dp++;
  910. UNW_DEC_GR_GR ("P9", (byte1 & 0xf), (byte2 & 0x7f), arg);
  911. break;
  912. case 0xf: /* p10 */
  913. if ((end - dp) < 2)
  914. {
  915. printf (_("\t<corrupt P10>\n"));
  916. return end;
  917. }
  918. byte1 = *dp++;
  919. byte2 = *dp++;
  920. UNW_DEC_ABI ("P10", byte1, byte2, arg);
  921. break;
  922. case 0x9:
  923. return unw_decode_x1 (dp, code, arg, end);
  924. case 0xa:
  925. return unw_decode_x2 (dp, code, arg, end);
  926. case 0xb:
  927. return unw_decode_x3 (dp, code, arg, end);
  928. case 0xc:
  929. return unw_decode_x4 (dp, code, arg, end);
  930. default:
  931. UNW_DEC_BAD_CODE (code);
  932. break;
  933. }
  934. }
  935. return dp;
  936. }
  937. static const unsigned char *
  938. unw_decode_b1 (const unsigned char *dp, unsigned int code,
  939. void *arg ATTRIBUTE_UNUSED,
  940. const unsigned char * end ATTRIBUTE_UNUSED)
  941. {
  942. unw_word label = (code & 0x1f);
  943. if ((code & 0x20) != 0)
  944. UNW_DEC_COPY_STATE ("B1", label, arg);
  945. else
  946. UNW_DEC_LABEL_STATE ("B1", label, arg);
  947. return dp;
  948. }
  949. static const unsigned char *
  950. unw_decode_b2 (const unsigned char *dp, unsigned int code,
  951. void *arg ATTRIBUTE_UNUSED,
  952. const unsigned char * end)
  953. {
  954. unw_word t;
  955. t = unw_decode_uleb128 (& dp, end);
  956. UNW_DEC_EPILOGUE ("B2", t, (code & 0x1f), arg);
  957. return dp;
  958. }
  959. static const unsigned char *
  960. unw_decode_b3_x4 (const unsigned char *dp, unsigned int code, void *arg,
  961. const unsigned char * end)
  962. {
  963. unw_word t, ecount, label;
  964. if ((code & 0x10) == 0)
  965. {
  966. t = unw_decode_uleb128 (&dp, end);
  967. ecount = unw_decode_uleb128 (&dp, end);
  968. UNW_DEC_EPILOGUE ("B3", t, ecount, arg);
  969. }
  970. else if ((code & 0x07) == 0)
  971. {
  972. label = unw_decode_uleb128 (&dp, end);
  973. if ((code & 0x08) != 0)
  974. UNW_DEC_COPY_STATE ("B4", label, arg);
  975. else
  976. UNW_DEC_LABEL_STATE ("B4", label, arg);
  977. }
  978. else
  979. switch (code & 0x7)
  980. {
  981. case 1:
  982. return unw_decode_x1 (dp, code, arg, end);
  983. case 2:
  984. return unw_decode_x2 (dp, code, arg, end);
  985. case 3:
  986. return unw_decode_x3 (dp, code, arg, end);
  987. case 4:
  988. return unw_decode_x4 (dp, code, arg, end);
  989. default:
  990. UNW_DEC_BAD_CODE (code);
  991. break;
  992. }
  993. return dp;
  994. }
  995. typedef const unsigned char *(*unw_decoder)
  996. (const unsigned char *, unsigned int, void *, const unsigned char *);
  997. static const unw_decoder unw_decode_table[2][8] =
  998. {
  999. /* prologue table: */
  1000. {
  1001. unw_decode_r1, /* 0 */
  1002. unw_decode_r1,
  1003. unw_decode_r2,
  1004. unw_decode_r3,
  1005. unw_decode_p1, /* 4 */
  1006. unw_decode_p2_p5,
  1007. unw_decode_p6,
  1008. unw_decode_p7_p10
  1009. },
  1010. {
  1011. unw_decode_r1, /* 0 */
  1012. unw_decode_r1,
  1013. unw_decode_r2,
  1014. unw_decode_r3,
  1015. unw_decode_b1, /* 4 */
  1016. unw_decode_b1,
  1017. unw_decode_b2,
  1018. unw_decode_b3_x4
  1019. }
  1020. };
  1021. /* Decode one descriptor and return address of next descriptor. */
  1022. const unsigned char *
  1023. unw_decode (const unsigned char *dp, int inside_body,
  1024. void *ptr_inside_body, const unsigned char * end)
  1025. {
  1026. unw_decoder decoder;
  1027. unsigned char code;
  1028. if ((end - dp) < 1)
  1029. {
  1030. printf (_("\t<corrupt IA64 descriptor>\n"));
  1031. return end;
  1032. }
  1033. code = *dp++;
  1034. decoder = unw_decode_table[inside_body][code >> 5];
  1035. return (*decoder) (dp, code, ptr_inside_body, end);
  1036. }