Gparser.c 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131
  1. /* libunwind - a platform-independent unwind library
  2. Copyright (C) 2001-2004 Hewlett-Packard Co
  3. Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
  4. This file is part of libunwind.
  5. Permission is hereby granted, free of charge, to any person obtaining
  6. a copy of this software and associated documentation files (the
  7. "Software"), to deal in the Software without restriction, including
  8. without limitation the rights to use, copy, modify, merge, publish,
  9. distribute, sublicense, and/or sell copies of the Software, and to
  10. permit persons to whom the Software is furnished to do so, subject to
  11. the following conditions:
  12. The above copyright notice and this permission notice shall be
  13. included in all copies or substantial portions of the Software.
  14. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  15. EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  16. MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  17. NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  18. LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  19. OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  20. WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
  21. #include "unwind_i.h"
  22. /* forward declaration: */
  23. static int create_state_record_for (struct cursor *c,
  24. struct ia64_state_record *sr,
  25. unw_word_t ip);
  26. typedef unsigned long unw_word;
  27. #define alloc_reg_state() (mempool_alloc (&unw.reg_state_pool))
  28. #define free_reg_state(rs) (mempool_free (&unw.reg_state_pool, rs))
  29. #define alloc_labeled_state() (mempool_alloc (&unw.labeled_state_pool))
  30. #define free_labeled_state(s) (mempool_free (&unw.labeled_state_pool, s))
  31. /* Routines to manipulate the state stack. */
  32. static inline void
  33. push (struct ia64_state_record *sr)
  34. {
  35. struct ia64_reg_state *rs;
  36. rs = alloc_reg_state ();
  37. if (!rs)
  38. {
  39. print_error ("libunwind: cannot stack reg state!\n");
  40. return;
  41. }
  42. memcpy (rs, &sr->curr, sizeof (*rs));
  43. sr->curr.next = rs;
  44. }
  45. static void
  46. pop (struct ia64_state_record *sr)
  47. {
  48. struct ia64_reg_state *rs = sr->curr.next;
  49. if (!rs)
  50. {
  51. print_error ("libunwind: stack underflow!\n");
  52. return;
  53. }
  54. memcpy (&sr->curr, rs, sizeof (*rs));
  55. free_reg_state (rs);
  56. }
  57. /* Make a copy of the state stack. Non-recursive to avoid stack overflows. */
  58. static struct ia64_reg_state *
  59. dup_state_stack (struct ia64_reg_state *rs)
  60. {
  61. struct ia64_reg_state *copy, *prev = NULL, *first = NULL;
  62. while (rs)
  63. {
  64. copy = alloc_reg_state ();
  65. if (!copy)
  66. {
  67. print_error ("unwind.dup_state_stack: out of memory\n");
  68. return NULL;
  69. }
  70. memcpy (copy, rs, sizeof (*copy));
  71. if (first)
  72. prev->next = copy;
  73. else
  74. first = copy;
  75. rs = rs->next;
  76. prev = copy;
  77. }
  78. return first;
  79. }
  80. /* Free all stacked register states (but not RS itself). */
  81. static void
  82. free_state_stack (struct ia64_reg_state *rs)
  83. {
  84. struct ia64_reg_state *p, *next;
  85. for (p = rs->next; p != NULL; p = next)
  86. {
  87. next = p->next;
  88. free_reg_state (p);
  89. }
  90. rs->next = NULL;
  91. }
  92. /* Unwind decoder routines */
  93. static enum ia64_pregnum __attribute__ ((const))
  94. decode_abreg (unsigned char abreg, int memory)
  95. {
  96. switch (abreg)
  97. {
  98. case 0x04 ... 0x07:
  99. return IA64_REG_R4 + (abreg - 0x04);
  100. case 0x22 ... 0x25:
  101. return IA64_REG_F2 + (abreg - 0x22);
  102. case 0x30 ... 0x3f:
  103. return IA64_REG_F16 + (abreg - 0x30);
  104. case 0x41 ... 0x45:
  105. return IA64_REG_B1 + (abreg - 0x41);
  106. case 0x60:
  107. return IA64_REG_PR;
  108. case 0x61:
  109. return IA64_REG_PSP;
  110. case 0x62:
  111. return memory ? IA64_REG_PRI_UNAT_MEM : IA64_REG_PRI_UNAT_GR;
  112. case 0x63:
  113. return IA64_REG_IP;
  114. case 0x64:
  115. return IA64_REG_BSP;
  116. case 0x65:
  117. return IA64_REG_BSPSTORE;
  118. case 0x66:
  119. return IA64_REG_RNAT;
  120. case 0x67:
  121. return IA64_REG_UNAT;
  122. case 0x68:
  123. return IA64_REG_FPSR;
  124. case 0x69:
  125. return IA64_REG_PFS;
  126. case 0x6a:
  127. return IA64_REG_LC;
  128. default:
  129. break;
  130. }
  131. Dprintf ("libunwind: bad abreg=0x%x\n", abreg);
  132. return IA64_REG_LC;
  133. }
  134. static void
  135. set_reg (struct ia64_reg_info *reg, enum ia64_where where, int when,
  136. unsigned long val)
  137. {
  138. reg->val = val;
  139. reg->where = where;
  140. if (reg->when == IA64_WHEN_NEVER)
  141. reg->when = when;
  142. }
  143. static void
  144. alloc_spill_area (unsigned long *offp, unsigned long regsize,
  145. struct ia64_reg_info *lo, struct ia64_reg_info *hi)
  146. {
  147. struct ia64_reg_info *reg;
  148. for (reg = hi; reg >= lo; --reg)
  149. {
  150. if (reg->where == IA64_WHERE_SPILL_HOME)
  151. {
  152. reg->where = IA64_WHERE_PSPREL;
  153. *offp -= regsize;
  154. reg->val = *offp;
  155. }
  156. }
  157. }
  158. static inline void
  159. spill_next_when (struct ia64_reg_info **regp, struct ia64_reg_info *lim,
  160. unw_word t)
  161. {
  162. struct ia64_reg_info *reg;
  163. for (reg = *regp; reg <= lim; ++reg)
  164. {
  165. if (reg->where == IA64_WHERE_SPILL_HOME)
  166. {
  167. reg->when = t;
  168. *regp = reg + 1;
  169. return;
  170. }
  171. }
  172. Dprintf ("libunwind: excess spill!\n");
  173. }
  174. static inline void
  175. finish_prologue (struct ia64_state_record *sr)
  176. {
  177. struct ia64_reg_info *reg;
  178. unsigned long off;
  179. int i;
  180. /* First, resolve implicit register save locations (see Section
  181. "11.4.2.3 Rules for Using Unwind Descriptors", rule 3). */
  182. for (i = 0; i < (int) ARRAY_SIZE (unw.save_order); ++i)
  183. {
  184. reg = sr->curr.reg + unw.save_order[i];
  185. if (reg->where == IA64_WHERE_GR_SAVE)
  186. {
  187. reg->where = IA64_WHERE_GR;
  188. reg->val = sr->gr_save_loc++;
  189. }
  190. }
  191. /* Next, compute when the fp, general, and branch registers get
  192. saved. This must come before alloc_spill_area() because we need
  193. to know which registers are spilled to their home locations. */
  194. if (sr->imask)
  195. {
  196. unsigned char kind, mask = 0, *cp = sr->imask;
  197. unsigned long t;
  198. static const unsigned char limit[3] =
  199. {
  200. IA64_REG_F31, IA64_REG_R7, IA64_REG_B5
  201. };
  202. struct ia64_reg_info *(regs[3]);
  203. regs[0] = sr->curr.reg + IA64_REG_F2;
  204. regs[1] = sr->curr.reg + IA64_REG_R4;
  205. regs[2] = sr->curr.reg + IA64_REG_B1;
  206. for (t = 0; (int) t < sr->region_len; ++t)
  207. {
  208. if ((t & 3) == 0)
  209. mask = *cp++;
  210. kind = (mask >> 2 * (3 - (t & 3))) & 3;
  211. if (kind > 0)
  212. spill_next_when (&regs[kind - 1], sr->curr.reg + limit[kind - 1],
  213. sr->region_start + t);
  214. }
  215. }
  216. /* Next, lay out the memory stack spill area. */
  217. if (sr->any_spills)
  218. {
  219. off = sr->spill_offset;
  220. alloc_spill_area (&off, 16, sr->curr.reg + IA64_REG_F2,
  221. sr->curr.reg + IA64_REG_F31);
  222. alloc_spill_area (&off, 8, sr->curr.reg + IA64_REG_B1,
  223. sr->curr.reg + IA64_REG_B5);
  224. alloc_spill_area (&off, 8, sr->curr.reg + IA64_REG_R4,
  225. sr->curr.reg + IA64_REG_R7);
  226. }
  227. }
  228. /* Region header descriptors. */
  229. static void
  230. desc_prologue (int body, unw_word rlen, unsigned char mask,
  231. unsigned char grsave, struct ia64_state_record *sr)
  232. {
  233. int i, region_start;
  234. if (!(sr->in_body || sr->first_region))
  235. finish_prologue (sr);
  236. sr->first_region = 0;
  237. /* check if we're done: */
  238. if (sr->when_target < sr->region_start + sr->region_len)
  239. {
  240. sr->done = 1;
  241. return;
  242. }
  243. region_start = sr->region_start + sr->region_len;
  244. for (i = 0; i < sr->epilogue_count; ++i)
  245. pop (sr);
  246. sr->epilogue_count = 0;
  247. sr->when_sp_restored = IA64_WHEN_NEVER;
  248. sr->region_start = region_start;
  249. sr->region_len = rlen;
  250. sr->in_body = body;
  251. if (!body)
  252. {
  253. push (sr);
  254. if (mask)
  255. for (i = 0; i < 4; ++i)
  256. {
  257. if (mask & 0x8)
  258. set_reg (sr->curr.reg + unw.save_order[i], IA64_WHERE_GR,
  259. sr->region_start + sr->region_len - 1, grsave++);
  260. mask <<= 1;
  261. }
  262. sr->gr_save_loc = grsave;
  263. sr->any_spills = 0;
  264. sr->imask = 0;
  265. sr->spill_offset = 0x10; /* default to psp+16 */
  266. }
  267. }
  268. /* Prologue descriptors. */
  269. static inline void
  270. desc_abi (unsigned char abi, unsigned char context,
  271. struct ia64_state_record *sr)
  272. {
  273. sr->abi_marker = (abi << 8) | context;
  274. }
  275. static inline void
  276. desc_br_gr (unsigned char brmask, unsigned char gr,
  277. struct ia64_state_record *sr)
  278. {
  279. int i;
  280. for (i = 0; i < 5; ++i)
  281. {
  282. if (brmask & 1)
  283. set_reg (sr->curr.reg + IA64_REG_B1 + i, IA64_WHERE_GR,
  284. sr->region_start + sr->region_len - 1, gr++);
  285. brmask >>= 1;
  286. }
  287. }
  288. static inline void
  289. desc_br_mem (unsigned char brmask, struct ia64_state_record *sr)
  290. {
  291. int i;
  292. for (i = 0; i < 5; ++i)
  293. {
  294. if (brmask & 1)
  295. {
  296. set_reg (sr->curr.reg + IA64_REG_B1 + i, IA64_WHERE_SPILL_HOME,
  297. sr->region_start + sr->region_len - 1, 0);
  298. sr->any_spills = 1;
  299. }
  300. brmask >>= 1;
  301. }
  302. }
  303. static inline void
  304. desc_frgr_mem (unsigned char grmask, unw_word frmask,
  305. struct ia64_state_record *sr)
  306. {
  307. int i;
  308. for (i = 0; i < 4; ++i)
  309. {
  310. if ((grmask & 1) != 0)
  311. {
  312. set_reg (sr->curr.reg + IA64_REG_R4 + i, IA64_WHERE_SPILL_HOME,
  313. sr->region_start + sr->region_len - 1, 0);
  314. sr->any_spills = 1;
  315. }
  316. grmask >>= 1;
  317. }
  318. for (i = 0; i < 20; ++i)
  319. {
  320. if ((frmask & 1) != 0)
  321. {
  322. int base = (i < 4) ? IA64_REG_F2 : IA64_REG_F16 - 4;
  323. set_reg (sr->curr.reg + base + i, IA64_WHERE_SPILL_HOME,
  324. sr->region_start + sr->region_len - 1, 0);
  325. sr->any_spills = 1;
  326. }
  327. frmask >>= 1;
  328. }
  329. }
  330. static inline void
  331. desc_fr_mem (unsigned char frmask, struct ia64_state_record *sr)
  332. {
  333. int i;
  334. for (i = 0; i < 4; ++i)
  335. {
  336. if ((frmask & 1) != 0)
  337. {
  338. set_reg (sr->curr.reg + IA64_REG_F2 + i, IA64_WHERE_SPILL_HOME,
  339. sr->region_start + sr->region_len - 1, 0);
  340. sr->any_spills = 1;
  341. }
  342. frmask >>= 1;
  343. }
  344. }
  345. static inline void
  346. desc_gr_gr (unsigned char grmask, unsigned char gr,
  347. struct ia64_state_record *sr)
  348. {
  349. int i;
  350. for (i = 0; i < 4; ++i)
  351. {
  352. if ((grmask & 1) != 0)
  353. set_reg (sr->curr.reg + IA64_REG_R4 + i, IA64_WHERE_GR,
  354. sr->region_start + sr->region_len - 1, gr++);
  355. grmask >>= 1;
  356. }
  357. }
  358. static inline void
  359. desc_gr_mem (unsigned char grmask, struct ia64_state_record *sr)
  360. {
  361. int i;
  362. for (i = 0; i < 4; ++i)
  363. {
  364. if ((grmask & 1) != 0)
  365. {
  366. set_reg (sr->curr.reg + IA64_REG_R4 + i, IA64_WHERE_SPILL_HOME,
  367. sr->region_start + sr->region_len - 1, 0);
  368. sr->any_spills = 1;
  369. }
  370. grmask >>= 1;
  371. }
  372. }
  373. static inline void
  374. desc_mem_stack_f (unw_word t, unw_word size, struct ia64_state_record *sr)
  375. {
  376. set_reg (sr->curr.reg + IA64_REG_PSP, IA64_WHERE_NONE,
  377. sr->region_start + MIN ((int) t, sr->region_len - 1), 16 * size);
  378. }
  379. static inline void
  380. desc_mem_stack_v (unw_word t, struct ia64_state_record *sr)
  381. {
  382. sr->curr.reg[IA64_REG_PSP].when =
  383. sr->region_start + MIN ((int) t, sr->region_len - 1);
  384. }
  385. static inline void
  386. desc_reg_gr (unsigned char reg, unsigned char dst,
  387. struct ia64_state_record *sr)
  388. {
  389. set_reg (sr->curr.reg + reg, IA64_WHERE_GR,
  390. sr->region_start + sr->region_len - 1, dst);
  391. }
  392. static inline void
  393. desc_reg_psprel (unsigned char reg, unw_word pspoff,
  394. struct ia64_state_record *sr)
  395. {
  396. set_reg (sr->curr.reg + reg, IA64_WHERE_PSPREL,
  397. sr->region_start + sr->region_len - 1, 0x10 - 4 * pspoff);
  398. }
  399. static inline void
  400. desc_reg_sprel (unsigned char reg, unw_word spoff,
  401. struct ia64_state_record *sr)
  402. {
  403. set_reg (sr->curr.reg + reg, IA64_WHERE_SPREL,
  404. sr->region_start + sr->region_len - 1, 4 * spoff);
  405. }
  406. static inline void
  407. desc_rp_br (unsigned char dst, struct ia64_state_record *sr)
  408. {
  409. sr->return_link_reg = dst;
  410. }
  411. static inline void
  412. desc_reg_when (unsigned char regnum, unw_word t, struct ia64_state_record *sr)
  413. {
  414. struct ia64_reg_info *reg = sr->curr.reg + regnum;
  415. if (reg->where == IA64_WHERE_NONE)
  416. reg->where = IA64_WHERE_GR_SAVE;
  417. reg->when = sr->region_start + MIN ((int) t, sr->region_len - 1);
  418. }
  419. static inline void
  420. desc_spill_base (unw_word pspoff, struct ia64_state_record *sr)
  421. {
  422. sr->spill_offset = 0x10 - 4 * pspoff;
  423. }
  424. static inline unsigned char *
  425. desc_spill_mask (unsigned char *imaskp, struct ia64_state_record *sr)
  426. {
  427. sr->imask = imaskp;
  428. return imaskp + (2 * sr->region_len + 7) / 8;
  429. }
  430. /* Body descriptors. */
  431. static inline void
  432. desc_epilogue (unw_word t, unw_word ecount, struct ia64_state_record *sr)
  433. {
  434. sr->when_sp_restored = sr->region_start + sr->region_len - 1 - t;
  435. sr->epilogue_count = ecount + 1;
  436. }
  437. static inline void
  438. desc_copy_state (unw_word label, struct ia64_state_record *sr)
  439. {
  440. struct ia64_labeled_state *ls;
  441. for (ls = sr->labeled_states; ls; ls = ls->next)
  442. {
  443. if (ls->label == label)
  444. {
  445. free_state_stack (&sr->curr);
  446. memcpy (&sr->curr, &ls->saved_state, sizeof (sr->curr));
  447. sr->curr.next = dup_state_stack (ls->saved_state.next);
  448. return;
  449. }
  450. }
  451. print_error ("libunwind: failed to find labeled state\n");
  452. }
  453. static inline void
  454. desc_label_state (unw_word label, struct ia64_state_record *sr)
  455. {
  456. struct ia64_labeled_state *ls;
  457. ls = alloc_labeled_state ();
  458. if (!ls)
  459. {
  460. print_error ("unwind.desc_label_state(): out of memory\n");
  461. return;
  462. }
  463. ls->label = label;
  464. memcpy (&ls->saved_state, &sr->curr, sizeof (ls->saved_state));
  465. ls->saved_state.next = dup_state_stack (sr->curr.next);
  466. /* insert into list of labeled states: */
  467. ls->next = sr->labeled_states;
  468. sr->labeled_states = ls;
  469. }
  470. /* General descriptors. */
  471. static inline int
  472. desc_is_active (unsigned char qp, unw_word t, struct ia64_state_record *sr)
  473. {
  474. if (sr->when_target <= sr->region_start + MIN ((int) t, sr->region_len - 1))
  475. return 0;
  476. if (qp > 0)
  477. {
  478. if ((sr->pr_val & ((unw_word_t) 1 << qp)) == 0)
  479. return 0;
  480. sr->pr_mask |= ((unw_word_t) 1 << qp);
  481. }
  482. return 1;
  483. }
  484. static inline void
  485. desc_restore_p (unsigned char qp, unw_word t, unsigned char abreg,
  486. struct ia64_state_record *sr)
  487. {
  488. struct ia64_reg_info *r;
  489. if (!desc_is_active (qp, t, sr))
  490. return;
  491. r = sr->curr.reg + decode_abreg (abreg, 0);
  492. r->where = IA64_WHERE_NONE;
  493. r->when = IA64_WHEN_NEVER;
  494. r->val = 0;
  495. }
  496. static inline void
  497. desc_spill_reg_p (unsigned char qp, unw_word t, unsigned char abreg,
  498. unsigned char x, unsigned char ytreg,
  499. struct ia64_state_record *sr)
  500. {
  501. enum ia64_where where = IA64_WHERE_GR;
  502. struct ia64_reg_info *r;
  503. if (!desc_is_active (qp, t, sr))
  504. return;
  505. if (x)
  506. where = IA64_WHERE_BR;
  507. else if (ytreg & 0x80)
  508. where = IA64_WHERE_FR;
  509. r = sr->curr.reg + decode_abreg (abreg, 0);
  510. r->where = where;
  511. r->when = sr->region_start + MIN ((int) t, sr->region_len - 1);
  512. r->val = (ytreg & 0x7f);
  513. }
  514. static inline void
  515. desc_spill_psprel_p (unsigned char qp, unw_word t, unsigned char abreg,
  516. unw_word pspoff, struct ia64_state_record *sr)
  517. {
  518. struct ia64_reg_info *r;
  519. if (!desc_is_active (qp, t, sr))
  520. return;
  521. r = sr->curr.reg + decode_abreg (abreg, 1);
  522. r->where = IA64_WHERE_PSPREL;
  523. r->when = sr->region_start + MIN ((int) t, sr->region_len - 1);
  524. r->val = 0x10 - 4 * pspoff;
  525. }
  526. static inline void
  527. desc_spill_sprel_p (unsigned char qp, unw_word t, unsigned char abreg,
  528. unw_word spoff, struct ia64_state_record *sr)
  529. {
  530. struct ia64_reg_info *r;
  531. if (!desc_is_active (qp, t, sr))
  532. return;
  533. r = sr->curr.reg + decode_abreg (abreg, 1);
  534. r->where = IA64_WHERE_SPREL;
  535. r->when = sr->region_start + MIN ((int) t, sr->region_len - 1);
  536. r->val = 4 * spoff;
  537. }
  538. #define UNW_DEC_BAD_CODE(code) \
  539. print_error ("libunwind: unknown code encountered\n")
  540. /* Register names. */
  541. #define UNW_REG_BSP IA64_REG_BSP
  542. #define UNW_REG_BSPSTORE IA64_REG_BSPSTORE
  543. #define UNW_REG_FPSR IA64_REG_FPSR
  544. #define UNW_REG_LC IA64_REG_LC
  545. #define UNW_REG_PFS IA64_REG_PFS
  546. #define UNW_REG_PR IA64_REG_PR
  547. #define UNW_REG_RNAT IA64_REG_RNAT
  548. #define UNW_REG_PSP IA64_REG_PSP
  549. #define UNW_REG_RP IA64_REG_IP
  550. #define UNW_REG_UNAT IA64_REG_UNAT
  551. /* Region headers. */
  552. #define UNW_DEC_PROLOGUE_GR(fmt,r,m,gr,arg) desc_prologue(0,r,m,gr,arg)
  553. #define UNW_DEC_PROLOGUE(fmt,b,r,arg) desc_prologue(b,r,0,32,arg)
  554. /* Prologue descriptors. */
  555. #define UNW_DEC_ABI(fmt,a,c,arg) desc_abi(a,c,arg)
  556. #define UNW_DEC_BR_GR(fmt,b,g,arg) desc_br_gr(b,g,arg)
  557. #define UNW_DEC_BR_MEM(fmt,b,arg) desc_br_mem(b,arg)
  558. #define UNW_DEC_FRGR_MEM(fmt,g,f,arg) desc_frgr_mem(g,f,arg)
  559. #define UNW_DEC_FR_MEM(fmt,f,arg) desc_fr_mem(f,arg)
  560. #define UNW_DEC_GR_GR(fmt,m,g,arg) desc_gr_gr(m,g,arg)
  561. #define UNW_DEC_GR_MEM(fmt,m,arg) desc_gr_mem(m,arg)
  562. #define UNW_DEC_MEM_STACK_F(fmt,t,s,arg) desc_mem_stack_f(t,s,arg)
  563. #define UNW_DEC_MEM_STACK_V(fmt,t,arg) desc_mem_stack_v(t,arg)
  564. #define UNW_DEC_REG_GR(fmt,r,d,arg) desc_reg_gr(r,d,arg)
  565. #define UNW_DEC_REG_PSPREL(fmt,r,o,arg) desc_reg_psprel(r,o,arg)
  566. #define UNW_DEC_REG_SPREL(fmt,r,o,arg) desc_reg_sprel(r,o,arg)
  567. #define UNW_DEC_REG_WHEN(fmt,r,t,arg) desc_reg_when(r,t,arg)
  568. #define UNW_DEC_PRIUNAT_WHEN_GR(fmt,t,arg) \
  569. desc_reg_when(IA64_REG_PRI_UNAT_GR,t,arg)
  570. #define UNW_DEC_PRIUNAT_WHEN_MEM(fmt,t,arg) \
  571. desc_reg_when(IA64_REG_PRI_UNAT_MEM,t,arg)
  572. #define UNW_DEC_PRIUNAT_GR(fmt,r,arg) \
  573. desc_reg_gr(IA64_REG_PRI_UNAT_GR,r,arg)
  574. #define UNW_DEC_PRIUNAT_PSPREL(fmt,o,arg) \
  575. desc_reg_psprel(IA64_REG_PRI_UNAT_MEM,o,arg)
  576. #define UNW_DEC_PRIUNAT_SPREL(fmt,o,arg) \
  577. desc_reg_sprel(IA64_REG_PRI_UNAT_MEM,o,arg)
  578. #define UNW_DEC_RP_BR(fmt,d,arg) desc_rp_br(d,arg)
  579. #define UNW_DEC_SPILL_BASE(fmt,o,arg) desc_spill_base(o,arg)
  580. #define UNW_DEC_SPILL_MASK(fmt,m,arg) (m = desc_spill_mask(m,arg))
  581. /* Body descriptors. */
  582. #define UNW_DEC_EPILOGUE(fmt,t,c,arg) desc_epilogue(t,c,arg)
  583. #define UNW_DEC_COPY_STATE(fmt,l,arg) desc_copy_state(l,arg)
  584. #define UNW_DEC_LABEL_STATE(fmt,l,arg) desc_label_state(l,arg)
  585. /* General unwind descriptors. */
  586. #define UNW_DEC_SPILL_REG_P(f,p,t,a,x,y,arg) desc_spill_reg_p(p,t,a,x,y,arg)
  587. #define UNW_DEC_SPILL_REG(f,t,a,x,y,arg) desc_spill_reg_p(0,t,a,x,y,arg)
  588. #define UNW_DEC_SPILL_PSPREL_P(f,p,t,a,o,arg) \
  589. desc_spill_psprel_p(p,t,a,o,arg)
  590. #define UNW_DEC_SPILL_PSPREL(f,t,a,o,arg) \
  591. desc_spill_psprel_p(0,t,a,o,arg)
  592. #define UNW_DEC_SPILL_SPREL_P(f,p,t,a,o,arg) desc_spill_sprel_p(p,t,a,o,arg)
  593. #define UNW_DEC_SPILL_SPREL(f,t,a,o,arg) desc_spill_sprel_p(0,t,a,o,arg)
  594. #define UNW_DEC_RESTORE_P(f,p,t,a,arg) desc_restore_p(p,t,a,arg)
  595. #define UNW_DEC_RESTORE(f,t,a,arg) desc_restore_p(0,t,a,arg)
  596. #include "unwind_decoder.h"
  597. #ifdef _U_dyn_op
  598. /* parse dynamic unwind info */
  599. static struct ia64_reg_info *
  600. lookup_preg (int regnum, int memory, struct ia64_state_record *sr)
  601. {
  602. int preg;
  603. switch (regnum)
  604. {
  605. case UNW_IA64_AR_BSP: preg = IA64_REG_BSP; break;
  606. case UNW_IA64_AR_BSPSTORE: preg = IA64_REG_BSPSTORE; break;
  607. case UNW_IA64_AR_FPSR: preg = IA64_REG_FPSR; break;
  608. case UNW_IA64_AR_LC: preg = IA64_REG_LC; break;
  609. case UNW_IA64_AR_PFS: preg = IA64_REG_PFS; break;
  610. case UNW_IA64_AR_RNAT: preg = IA64_REG_RNAT; break;
  611. case UNW_IA64_AR_UNAT: preg = IA64_REG_UNAT; break;
  612. case UNW_IA64_BR + 0: preg = IA64_REG_IP; break;
  613. case UNW_IA64_PR: preg = IA64_REG_PR; break;
  614. case UNW_IA64_SP: preg = IA64_REG_PSP; break;
  615. case UNW_IA64_NAT:
  616. if (memory)
  617. preg = IA64_REG_PRI_UNAT_MEM;
  618. else
  619. preg = IA64_REG_PRI_UNAT_GR;
  620. break;
  621. case UNW_IA64_GR + 4 ... UNW_IA64_GR + 7:
  622. preg = IA64_REG_R4 + (regnum - (UNW_IA64_GR + 4));
  623. break;
  624. case UNW_IA64_BR + 1 ... UNW_IA64_BR + 5:
  625. preg = IA64_REG_B1 + (regnum - UNW_IA64_BR);
  626. break;
  627. case UNW_IA64_FR + 2 ... UNW_IA64_FR + 5:
  628. preg = IA64_REG_F2 + (regnum - (UNW_IA64_FR + 2));
  629. break;
  630. case UNW_IA64_FR + 16 ... UNW_IA64_FR + 31:
  631. preg = IA64_REG_F16 + (regnum - (UNW_IA64_FR + 16));
  632. break;
  633. default:
  634. Dprintf ("%s: invalid register number %d\n", __FUNCTION__, regnum);
  635. return NULL;
  636. }
  637. return sr->curr.reg + preg;
  638. }
  639. /* An alias directive inside a region of length RLEN is interpreted to
  640. mean that the region behaves exactly like the first RLEN
  641. instructions at the aliased IP. RLEN=0 implies that the current
  642. state matches exactly that of before the instruction at the aliased
  643. IP is executed. */
  644. static int
  645. desc_alias (unw_dyn_op_t *op, struct cursor *c, struct ia64_state_record *sr)
  646. {
  647. struct ia64_state_record orig_sr = *sr;
  648. int i, ret, when, rlen = sr->region_len;
  649. unw_word_t new_ip;
  650. when = MIN (sr->when_target, rlen);
  651. new_ip = op->val + ((when / 3) * 16 + (when % 3));
  652. if ((ret = ia64_fetch_proc_info (c, new_ip, 1)) < 0)
  653. return ret;
  654. if ((ret = create_state_record_for (c, sr, new_ip)) < 0)
  655. return ret;
  656. sr->first_region = orig_sr.first_region;
  657. sr->done = 0;
  658. sr->any_spills |= orig_sr.any_spills;
  659. sr->in_body = orig_sr.in_body;
  660. sr->region_start = orig_sr.region_start;
  661. sr->region_len = orig_sr.region_len;
  662. if (sr->when_sp_restored != IA64_WHEN_NEVER)
  663. sr->when_sp_restored = op->when + MIN (orig_sr.when_sp_restored, rlen);
  664. sr->epilogue_count = orig_sr.epilogue_count;
  665. sr->when_target = orig_sr.when_target;
  666. for (i = 0; i < IA64_NUM_PREGS; ++i)
  667. if (sr->curr.reg[i].when != IA64_WHEN_NEVER)
  668. sr->curr.reg[i].when = op->when + MIN (sr->curr.reg[i].when, rlen);
  669. ia64_free_state_record (sr);
  670. sr->labeled_states = orig_sr.labeled_states;
  671. sr->curr.next = orig_sr.curr.next;
  672. return 0;
  673. }
  674. static inline int
  675. parse_dynamic (struct cursor *c, struct ia64_state_record *sr)
  676. {
  677. unw_dyn_info_t *di = c->pi.unwind_info;
  678. unw_dyn_proc_info_t *proc = &di->u.pi;
  679. unw_dyn_region_info_t *r;
  680. struct ia64_reg_info *ri;
  681. enum ia64_where where;
  682. int32_t when, len;
  683. unw_dyn_op_t *op;
  684. unw_word_t val;
  685. int memory, ret;
  686. int8_t qp;
  687. for (r = proc->regions; r; r = r->next)
  688. {
  689. len = r->insn_count;
  690. if (len < 0)
  691. {
  692. if (r->next)
  693. {
  694. Debug (1, "negative region length allowed in last region only!");
  695. return -UNW_EINVAL;
  696. }
  697. len = -len;
  698. /* hack old region info to set the start where we need it: */
  699. sr->region_start = (di->end_ip - di->start_ip) / 0x10 * 3 - len;
  700. sr->region_len = 0;
  701. }
  702. /* all regions are treated as prologue regions: */
  703. desc_prologue (0, len, 0, 0, sr);
  704. if (sr->done)
  705. return 0;
  706. for (op = r->op; op < r->op + r->op_count; ++op)
  707. {
  708. when = op->when;
  709. val = op->val;
  710. qp = op->qp;
  711. if (!desc_is_active (qp, when, sr))
  712. continue;
  713. when = sr->region_start + MIN ((int) when, sr->region_len - 1);
  714. switch (op->tag)
  715. {
  716. case UNW_DYN_SAVE_REG:
  717. memory = 0;
  718. if ((unsigned) (val - UNW_IA64_GR) < 128)
  719. where = IA64_WHERE_GR;
  720. else if ((unsigned) (val - UNW_IA64_FR) < 128)
  721. where = IA64_WHERE_FR;
  722. else if ((unsigned) (val - UNW_IA64_BR) < 8)
  723. where = IA64_WHERE_BR;
  724. else
  725. {
  726. Dprintf ("%s: can't save to register number %d\n",
  727. __FUNCTION__, (int) op->reg);
  728. return -UNW_EBADREG;
  729. }
  730. /* fall through */
  731. update_reg_info:
  732. ri = lookup_preg (op->reg, memory, sr);
  733. if (!ri)
  734. return -UNW_EBADREG;
  735. ri->where = where;
  736. ri->when = when;
  737. ri->val = val;
  738. break;
  739. case UNW_DYN_SPILL_FP_REL:
  740. memory = 1;
  741. where = IA64_WHERE_PSPREL;
  742. val = 0x10 - val;
  743. goto update_reg_info;
  744. case UNW_DYN_SPILL_SP_REL:
  745. memory = 1;
  746. where = IA64_WHERE_SPREL;
  747. goto update_reg_info;
  748. case UNW_DYN_ADD:
  749. if (op->reg == UNW_IA64_SP)
  750. {
  751. if (val & 0xf)
  752. {
  753. Dprintf ("%s: frame-size %ld not an integer "
  754. "multiple of 16\n",
  755. __FUNCTION__, (long) op->val);
  756. return -UNW_EINVAL;
  757. }
  758. desc_mem_stack_f (when, -((int64_t) val / 16), sr);
  759. }
  760. else
  761. {
  762. Dprintf ("%s: can only ADD to stack-pointer\n",
  763. __FUNCTION__);
  764. return -UNW_EBADREG;
  765. }
  766. break;
  767. case UNW_DYN_POP_FRAMES:
  768. sr->when_sp_restored = when;
  769. sr->epilogue_count = op->val;
  770. break;
  771. case UNW_DYN_LABEL_STATE:
  772. desc_label_state (op->val, sr);
  773. break;
  774. case UNW_DYN_COPY_STATE:
  775. desc_copy_state (op->val, sr);
  776. break;
  777. case UNW_DYN_ALIAS:
  778. if ((ret = desc_alias (op, c, sr)) < 0)
  779. return ret;
  780. case UNW_DYN_STOP:
  781. goto end_of_ops;
  782. }
  783. }
  784. end_of_ops:
  785. ;
  786. }
  787. return 0;
  788. }
  789. #else
  790. # define parse_dynamic(c,sr) (-UNW_EINVAL)
  791. #endif /* _U_dyn_op */
  792. HIDDEN int
  793. ia64_fetch_proc_info (struct cursor *c, unw_word_t ip, int need_unwind_info)
  794. {
  795. int ret, dynamic = 1;
  796. if (c->pi_valid && !need_unwind_info)
  797. return 0;
  798. /* check dynamic info first --- it overrides everything else */
  799. ret = unwi_find_dynamic_proc_info (c->as, ip, &c->pi, need_unwind_info,
  800. c->as_arg);
  801. if (ret == -UNW_ENOINFO)
  802. {
  803. dynamic = 0;
  804. ret = ia64_find_proc_info (c, ip, need_unwind_info);
  805. }
  806. c->pi_valid = 1;
  807. c->pi_is_dynamic = dynamic;
  808. return ret;
  809. }
  810. static inline void
  811. put_unwind_info (struct cursor *c, unw_proc_info_t *pi)
  812. {
  813. if (!c->pi_valid)
  814. return;
  815. if (c->pi_is_dynamic)
  816. unwi_put_dynamic_unwind_info (c->as, pi, c->as_arg);
  817. else
  818. ia64_put_unwind_info (c, pi);
  819. }
  820. static int
  821. create_state_record_for (struct cursor *c, struct ia64_state_record *sr,
  822. unw_word_t ip)
  823. {
  824. unw_word_t predicates = c->pr;
  825. struct ia64_reg_info *r;
  826. uint8_t *dp, *desc_end;
  827. int ret;
  828. assert (c->pi_valid);
  829. /* build state record */
  830. memset (sr, 0, sizeof (*sr));
  831. for (r = sr->curr.reg; r < sr->curr.reg + IA64_NUM_PREGS; ++r)
  832. r->when = IA64_WHEN_NEVER;
  833. sr->pr_val = predicates;
  834. sr->first_region = 1;
  835. if (!c->pi.unwind_info)
  836. {
  837. /* No info, return default unwinder (leaf proc, no mem stack, no
  838. saved regs), rp in b0, pfs in ar.pfs. */
  839. Debug (1, "no unwind info for ip=0x%lx (gp=%lx)\n",
  840. (long) ip, (long) c->pi.gp);
  841. sr->curr.reg[IA64_REG_IP].where = IA64_WHERE_BR;
  842. sr->curr.reg[IA64_REG_IP].when = -1;
  843. sr->curr.reg[IA64_REG_IP].val = 0;
  844. goto out;
  845. }
  846. sr->when_target = (3 * ((ip & ~(unw_word_t) 0xf) - c->pi.start_ip) / 16
  847. + (ip & 0xf));
  848. switch (c->pi.format)
  849. {
  850. case UNW_INFO_FORMAT_TABLE:
  851. case UNW_INFO_FORMAT_REMOTE_TABLE:
  852. dp = c->pi.unwind_info;
  853. desc_end = dp + c->pi.unwind_info_size;
  854. while (!sr->done && dp < desc_end)
  855. dp = unw_decode (dp, sr->in_body, sr);
  856. ret = 0;
  857. break;
  858. case UNW_INFO_FORMAT_DYNAMIC:
  859. ret = parse_dynamic (c, sr);
  860. break;
  861. default:
  862. ret = -UNW_EINVAL;
  863. }
  864. put_unwind_info (c, &c->pi);
  865. if (ret < 0)
  866. return ret;
  867. if (sr->when_target > sr->when_sp_restored)
  868. {
  869. /* sp has been restored and all values on the memory stack below
  870. psp also have been restored. */
  871. sr->curr.reg[IA64_REG_PSP].val = 0;
  872. sr->curr.reg[IA64_REG_PSP].where = IA64_WHERE_NONE;
  873. sr->curr.reg[IA64_REG_PSP].when = IA64_WHEN_NEVER;
  874. for (r = sr->curr.reg; r < sr->curr.reg + IA64_NUM_PREGS; ++r)
  875. if ((r->where == IA64_WHERE_PSPREL && r->val <= 0x10)
  876. || r->where == IA64_WHERE_SPREL)
  877. {
  878. r->val = 0;
  879. r->where = IA64_WHERE_NONE;
  880. r->when = IA64_WHEN_NEVER;
  881. }
  882. }
  883. /* If RP did't get saved, generate entry for the return link
  884. register. */
  885. if (sr->curr.reg[IA64_REG_IP].when >= sr->when_target)
  886. {
  887. sr->curr.reg[IA64_REG_IP].where = IA64_WHERE_BR;
  888. sr->curr.reg[IA64_REG_IP].when = -1;
  889. sr->curr.reg[IA64_REG_IP].val = sr->return_link_reg;
  890. }
  891. if (sr->when_target > sr->curr.reg[IA64_REG_BSP].when
  892. && sr->when_target > sr->curr.reg[IA64_REG_BSPSTORE].when
  893. && sr->when_target > sr->curr.reg[IA64_REG_RNAT].when)
  894. {
  895. Debug (8, "func 0x%lx may switch the register-backing-store\n",
  896. c->pi.start_ip);
  897. c->pi.flags |= UNW_PI_FLAG_IA64_RBS_SWITCH;
  898. }
  899. out:
  900. #if UNW_DEBUG
  901. if (unwi_debug_level > 2)
  902. {
  903. Dprintf ("%s: state record for func 0x%lx, t=%u (flags=0x%lx):\n",
  904. __FUNCTION__,
  905. (long) c->pi.start_ip, sr->when_target, (long) c->pi.flags);
  906. for (r = sr->curr.reg; r < sr->curr.reg + IA64_NUM_PREGS; ++r)
  907. {
  908. if (r->where != IA64_WHERE_NONE || r->when != IA64_WHEN_NEVER)
  909. {
  910. Dprintf (" %s <- ", unw.preg_name[r - sr->curr.reg]);
  911. switch (r->where)
  912. {
  913. case IA64_WHERE_GR:
  914. Dprintf ("r%lu", (long) r->val);
  915. break;
  916. case IA64_WHERE_FR:
  917. Dprintf ("f%lu", (long) r->val);
  918. break;
  919. case IA64_WHERE_BR:
  920. Dprintf ("b%lu", (long) r->val);
  921. break;
  922. case IA64_WHERE_SPREL:
  923. Dprintf ("[sp+0x%lx]", (long) r->val);
  924. break;
  925. case IA64_WHERE_PSPREL:
  926. Dprintf ("[psp+0x%lx]", (long) r->val);
  927. break;
  928. case IA64_WHERE_NONE:
  929. Dprintf ("%s+0x%lx",
  930. unw.preg_name[r - sr->curr.reg], (long) r->val);
  931. break;
  932. default:
  933. Dprintf ("BADWHERE(%d)", r->where);
  934. break;
  935. }
  936. Dprintf ("\t\t%d\n", r->when);
  937. }
  938. }
  939. }
  940. #endif
  941. return 0;
  942. }
  943. /* The proc-info must be valid for IP before this routine can be
  944. called. */
  945. HIDDEN int
  946. ia64_create_state_record (struct cursor *c, struct ia64_state_record *sr)
  947. {
  948. return create_state_record_for (c, sr, c->ip);
  949. }
  950. HIDDEN int
  951. ia64_free_state_record (struct ia64_state_record *sr)
  952. {
  953. struct ia64_labeled_state *ls, *next;
  954. /* free labeled register states & stack: */
  955. for (ls = sr->labeled_states; ls; ls = next)
  956. {
  957. next = ls->next;
  958. free_state_stack (&ls->saved_state);
  959. free_labeled_state (ls);
  960. }
  961. free_state_stack (&sr->curr);
  962. return 0;
  963. }
  964. HIDDEN int
  965. ia64_make_proc_info (struct cursor *c)
  966. {
  967. int ret, caching = c->as->caching_policy != UNW_CACHE_NONE;
  968. if (!caching || ia64_get_cached_proc_info (c) < 0)
  969. {
  970. /* Lookup it up the slow way... */
  971. if ((ret = ia64_fetch_proc_info (c, c->ip, 0)) < 0)
  972. return ret;
  973. if (caching)
  974. ia64_cache_proc_info (c);
  975. }
  976. return 0;
  977. }