]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/ia64/unwind-ia64.c
[multiple changes]
[thirdparty/gcc.git] / gcc / config / ia64 / unwind-ia64.c
1 /* Subroutines needed for unwinding IA-64 standard format stack frame
2 info for exception handling.
3 Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2006,
4 2009, 2011 Free Software Foundation, Inc.
5 Contributed by Andrew MacLeod <amacleod@cygnus.com>
6 Andrew Haley <aph@cygnus.com>
7 David Mosberger-Tang <davidm@hpl.hp.com>
8
9 This file is part of GCC.
10
11 GCC is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 3, or (at your option)
14 any later version.
15
16 GCC is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
20
21 Under Section 7 of GPL version 3, you are granted additional
22 permissions described in the GCC Runtime Library Exception, version
23 3.1, as published by the Free Software Foundation.
24
25 You should have received a copy of the GNU General Public License and
26 a copy of the GCC Runtime Library Exception along with this program;
27 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
28 <http://www.gnu.org/licenses/>. */
29
30 #include "tconfig.h"
31 #include "tsystem.h"
32 #include "coretypes.h"
33 #include "tm.h"
34 #include "unwind.h"
35 #include "unwind-ia64.h"
36 #include "unwind-compat.h"
37 #include "ia64intrin.h"
38
39 /* This isn't thread safe, but nice for occasional tests. */
40 #undef ENABLE_MALLOC_CHECKING
41
42 #ifndef __USING_SJLJ_EXCEPTIONS__
43
44
45 /* By default, assume personality routine interface compatibility with
46 our expectations. */
47 #ifndef MD_UNW_COMPATIBLE_PERSONALITY_P
48 #define MD_UNW_COMPATIBLE_PERSONALITY_P(HEADER) 1
49 #endif
50
51 enum unw_application_register
52 {
53 UNW_AR_BSP,
54 UNW_AR_BSPSTORE,
55 UNW_AR_PFS,
56 UNW_AR_RNAT,
57 UNW_AR_UNAT,
58 UNW_AR_LC,
59 UNW_AR_EC,
60 UNW_AR_FPSR,
61 UNW_AR_RSC,
62 UNW_AR_CCV
63 };
64
65 enum unw_register_index
66 {
67 /* Primary UNAT. */
68 UNW_REG_PRI_UNAT_GR,
69 UNW_REG_PRI_UNAT_MEM,
70
71 /* Memory Stack. */
72 UNW_REG_PSP, /* previous memory stack pointer */
73
74 /* Register Stack. */
75 UNW_REG_BSP, /* register stack pointer */
76 UNW_REG_BSPSTORE,
77 UNW_REG_PFS, /* previous function state */
78 UNW_REG_RNAT,
79 /* Return Pointer. */
80 UNW_REG_RP,
81
82 /* Special preserved registers. */
83 UNW_REG_UNAT, UNW_REG_PR, UNW_REG_LC, UNW_REG_FPSR,
84
85 /* Non-stacked general registers. */
86 UNW_REG_R2,
87 UNW_REG_R4 = UNW_REG_R2 + 2,
88 UNW_REG_R7 = UNW_REG_R2 + 5,
89 UNW_REG_R31 = UNW_REG_R2 + 29,
90
91 /* Non-stacked floating point registers. */
92 UNW_REG_F2,
93 UNW_REG_F5 = UNW_REG_F2 + 3,
94 UNW_REG_F16 = UNW_REG_F2 + 14,
95 UNW_REG_F31 = UNW_REG_F2 + 29,
96
97 /* Branch registers. */
98 UNW_REG_B0, UNW_REG_B1,
99 UNW_REG_B5 = UNW_REG_B1 + 4,
100
101 UNW_NUM_REGS
102 };
103
104 enum unw_where
105 {
106 UNW_WHERE_NONE, /* register isn't saved at all */
107 UNW_WHERE_GR, /* register is saved in a general register */
108 UNW_WHERE_FR, /* register is saved in a floating-point register */
109 UNW_WHERE_BR, /* register is saved in a branch register */
110 UNW_WHERE_SPREL, /* register is saved on memstack (sp-relative) */
111 UNW_WHERE_PSPREL, /* register is saved on memstack (psp-relative) */
112
113 /* At the end of each prologue these locations get resolved to
114 UNW_WHERE_PSPREL and UNW_WHERE_GR, respectively. */
115 UNW_WHERE_SPILL_HOME, /* register is saved in its spill home */
116 UNW_WHERE_GR_SAVE /* register is saved in next general register */
117 };
118
119 #define UNW_WHEN_NEVER 0x7fffffff
120
121 struct unw_reg_info
122 {
123 unsigned long val; /* save location: register number or offset */
124 enum unw_where where; /* where the register gets saved */
125 int when; /* when the register gets saved */
126 };
127
128 struct unw_reg_state {
129 struct unw_reg_state *next; /* next (outer) element on state stack */
130 struct unw_reg_info reg[UNW_NUM_REGS]; /* register save locations */
131 };
132
133 struct unw_labeled_state {
134 struct unw_labeled_state *next; /* next labeled state (or NULL) */
135 unsigned long label; /* label for this state */
136 struct unw_reg_state saved_state;
137 };
138
139 typedef struct unw_state_record
140 {
141 unsigned int first_region : 1; /* is this the first region? */
142 unsigned int done : 1; /* are we done scanning descriptors? */
143 unsigned int any_spills : 1; /* got any register spills? */
144 unsigned int in_body : 1; /* are we inside a body? */
145 unsigned int no_reg_stack_frame : 1; /* Don't adjust bsp for i&l regs */
146 unsigned char *imask; /* imask of spill_mask record or NULL */
147 unsigned long pr_val; /* predicate values */
148 unsigned long pr_mask; /* predicate mask */
149 long spill_offset; /* psp-relative offset for spill base */
150 int region_start;
151 int region_len;
152 int epilogue_start;
153 int epilogue_count;
154 int when_target;
155
156 unsigned char gr_save_loc; /* next general register to use for saving */
157 unsigned char return_link_reg; /* branch register for return link */
158 unsigned short unwabi;
159
160 struct unw_labeled_state *labeled_states; /* list of all labeled states */
161 struct unw_reg_state curr; /* current state */
162
163 _Unwind_Personality_Fn personality;
164
165 } _Unwind_FrameState;
166
167 enum unw_nat_type
168 {
169 UNW_NAT_NONE, /* NaT not represented */
170 UNW_NAT_VAL, /* NaT represented by NaT value (fp reg) */
171 UNW_NAT_MEMSTK, /* NaT value is in unat word at offset OFF */
172 UNW_NAT_REGSTK /* NaT is in rnat */
173 };
174
175 struct unw_stack
176 {
177 unsigned long limit;
178 unsigned long top;
179 };
180
181 struct _Unwind_Context
182 {
183 /* Initial frame info. */
184 unsigned long rnat; /* rse nat collection */
185 unsigned long regstk_top; /* lowest address of rbs stored register
186 which uses context->rnat collection */
187
188 /* Current frame info. */
189 unsigned long bsp; /* backing store pointer value
190 corresponding to psp. */
191 unsigned long sp; /* stack pointer value */
192 unsigned long psp; /* previous sp value */
193 unsigned long rp; /* return pointer */
194 unsigned long pr; /* predicate collection */
195
196 unsigned long region_start; /* start of unwind region */
197 unsigned long gp; /* global pointer value */
198 void *lsda; /* language specific data area */
199
200 /* Preserved state. */
201 unsigned long *bsp_loc; /* previous bsp save location
202 Appears to be write-only? */
203 unsigned long *bspstore_loc;
204 unsigned long *pfs_loc; /* Save location for pfs in current
205 (corr. to sp) frame. Target
206 contains cfm for caller. */
207 unsigned long *signal_pfs_loc;/* Save location for pfs in current
208 signal frame. Target contains
209 pfs for caller. */
210 unsigned long *pri_unat_loc;
211 unsigned long *unat_loc;
212 unsigned long *lc_loc;
213 unsigned long *fpsr_loc;
214
215 unsigned long eh_data[4];
216
217 struct unw_ireg
218 {
219 unsigned long *loc;
220 struct unw_ireg_nat
221 {
222 enum unw_nat_type type : 3;
223 signed long off : 61; /* NaT word is at loc+nat.off */
224 } nat;
225 } ireg[32 - 2]; /* Indexed by <register number> - 2 */
226
227 unsigned long *br_loc[8];
228 void *fr_loc[32 - 2];
229
230 /* ??? We initially point pri_unat_loc here. The entire NAT bit
231 logic needs work. */
232 unsigned long initial_unat;
233 };
234
235 typedef unsigned long unw_word;
236
237 /* Implicit register save order. See section 11.4.2.3 Rules for Using
238 Unwind Descriptors, rule 3. */
239
240 static unsigned char const save_order[] =
241 {
242 UNW_REG_RP, UNW_REG_PFS, UNW_REG_PSP, UNW_REG_PR,
243 UNW_REG_UNAT, UNW_REG_LC, UNW_REG_FPSR, UNW_REG_PRI_UNAT_GR
244 };
245
246 \f
247 #define MIN(X, Y) ((X) < (Y) ? (X) : (Y))
248
249 /* MASK is a bitmap describing the allocation state of emergency buffers,
250 with bit set indicating free. Return >= 0 if allocation is successful;
251 < 0 if failure. */
252
253 static inline int
254 atomic_alloc (unsigned int *mask)
255 {
256 unsigned int old = *mask, ret, new;
257
258 while (1)
259 {
260 if (old == 0)
261 return -1;
262 ret = old & -old;
263 new = old & ~ret;
264 new = __sync_val_compare_and_swap (mask, old, new);
265 if (old == new)
266 break;
267 old = new;
268 }
269
270 return __builtin_ffs (ret) - 1;
271 }
272
273 /* Similarly, free an emergency buffer. */
274
275 static inline void
276 atomic_free (unsigned int *mask, int bit)
277 {
278 __sync_xor_and_fetch (mask, 1 << bit);
279 }
280
281
282 #define SIZE(X) (sizeof(X) / sizeof(*(X)))
283 #define MASK_FOR(X) ((2U << (SIZE (X) - 1)) - 1)
284 #define PTR_IN(X, P) ((P) >= (X) && (P) < (X) + SIZE (X))
285
286 static struct unw_reg_state emergency_reg_state[32];
287 static unsigned int emergency_reg_state_free = MASK_FOR (emergency_reg_state);
288
289 static struct unw_labeled_state emergency_labeled_state[8];
290 static unsigned int emergency_labeled_state_free = MASK_FOR (emergency_labeled_state);
291
292 #ifdef ENABLE_MALLOC_CHECKING
293 static int reg_state_alloced;
294 static int labeled_state_alloced;
295 #endif
296
297 /* Allocation and deallocation of structures. */
298
299 static struct unw_reg_state *
300 alloc_reg_state (void)
301 {
302 struct unw_reg_state *rs;
303
304 #ifdef ENABLE_MALLOC_CHECKING
305 reg_state_alloced++;
306 #endif
307
308 rs = malloc (sizeof (struct unw_reg_state));
309 if (!rs)
310 {
311 int n = atomic_alloc (&emergency_reg_state_free);
312 if (n >= 0)
313 rs = &emergency_reg_state[n];
314 }
315
316 return rs;
317 }
318
319 static void
320 free_reg_state (struct unw_reg_state *rs)
321 {
322 #ifdef ENABLE_MALLOC_CHECKING
323 reg_state_alloced--;
324 #endif
325
326 if (PTR_IN (emergency_reg_state, rs))
327 atomic_free (&emergency_reg_state_free, rs - emergency_reg_state);
328 else
329 free (rs);
330 }
331
332 static struct unw_labeled_state *
333 alloc_label_state (void)
334 {
335 struct unw_labeled_state *ls;
336
337 #ifdef ENABLE_MALLOC_CHECKING
338 labeled_state_alloced++;
339 #endif
340
341 ls = malloc(sizeof(struct unw_labeled_state));
342 if (!ls)
343 {
344 int n = atomic_alloc (&emergency_labeled_state_free);
345 if (n >= 0)
346 ls = &emergency_labeled_state[n];
347 }
348
349 return ls;
350 }
351
352 static void
353 free_label_state (struct unw_labeled_state *ls)
354 {
355 #ifdef ENABLE_MALLOC_CHECKING
356 labeled_state_alloced--;
357 #endif
358
359 if (PTR_IN (emergency_labeled_state, ls))
360 atomic_free (&emergency_labeled_state_free, emergency_labeled_state - ls);
361 else
362 free (ls);
363 }
364
365 /* Routines to manipulate the state stack. */
366
367 static void
368 push (struct unw_state_record *sr)
369 {
370 struct unw_reg_state *rs = alloc_reg_state ();
371 memcpy (rs, &sr->curr, sizeof (*rs));
372 sr->curr.next = rs;
373 }
374
375 static void
376 pop (struct unw_state_record *sr)
377 {
378 struct unw_reg_state *rs = sr->curr.next;
379
380 if (!rs)
381 abort ();
382 memcpy (&sr->curr, rs, sizeof(*rs));
383 free_reg_state (rs);
384 }
385
386 /* Make a copy of the state stack. Non-recursive to avoid stack overflows. */
387
388 static struct unw_reg_state *
389 dup_state_stack (struct unw_reg_state *rs)
390 {
391 struct unw_reg_state *copy, *prev = NULL, *first = NULL;
392
393 while (rs)
394 {
395 copy = alloc_reg_state ();
396 memcpy (copy, rs, sizeof(*copy));
397 if (first)
398 prev->next = copy;
399 else
400 first = copy;
401 rs = rs->next;
402 prev = copy;
403 }
404
405 return first;
406 }
407
408 /* Free all stacked register states (but not RS itself). */
409 static void
410 free_state_stack (struct unw_reg_state *rs)
411 {
412 struct unw_reg_state *p, *next;
413
414 for (p = rs->next; p != NULL; p = next)
415 {
416 next = p->next;
417 free_reg_state (p);
418 }
419 rs->next = NULL;
420 }
421
422 /* Free all labeled states. */
423
424 static void
425 free_label_states (struct unw_labeled_state *ls)
426 {
427 struct unw_labeled_state *next;
428
429 for (; ls ; ls = next)
430 {
431 next = ls->next;
432
433 free_state_stack (&ls->saved_state);
434 free_label_state (ls);
435 }
436 }
437 \f
438 /* Unwind decoder routines */
439
440 static enum unw_register_index __attribute__((const))
441 decode_abreg (unsigned char abreg, int memory)
442 {
443 switch (abreg)
444 {
445 #if TARGET_ABI_OPEN_VMS
446 /* OpenVMS Calling Standard specifies R3 - R31. */
447 case 0x03 ... 0x1f: return UNW_REG_R2 + (abreg - 0x02);
448 #else
449 /* Standard Intel ABI specifies GR 4 - 7. */
450 case 0x04 ... 0x07: return UNW_REG_R4 + (abreg - 0x04);
451 #endif
452 case 0x22 ... 0x25: return UNW_REG_F2 + (abreg - 0x22);
453 case 0x30 ... 0x3f: return UNW_REG_F16 + (abreg - 0x30);
454 case 0x41 ... 0x45: return UNW_REG_B1 + (abreg - 0x41);
455 case 0x60: return UNW_REG_PR;
456 case 0x61: return UNW_REG_PSP;
457 case 0x62: return memory ? UNW_REG_PRI_UNAT_MEM : UNW_REG_PRI_UNAT_GR;
458 case 0x63: return UNW_REG_RP;
459 case 0x64: return UNW_REG_BSP;
460 case 0x65: return UNW_REG_BSPSTORE;
461 case 0x66: return UNW_REG_RNAT;
462 case 0x67: return UNW_REG_UNAT;
463 case 0x68: return UNW_REG_FPSR;
464 case 0x69: return UNW_REG_PFS;
465 case 0x6a: return UNW_REG_LC;
466 default:
467 abort ();
468 }
469 }
470
471 static void
472 set_reg (struct unw_reg_info *reg, enum unw_where where,
473 int when, unsigned long val)
474 {
475 reg->val = val;
476 reg->where = where;
477 if (reg->when == UNW_WHEN_NEVER)
478 reg->when = when;
479 }
480
481 static void
482 alloc_spill_area (unsigned long *offp, unsigned long regsize,
483 struct unw_reg_info *lo, struct unw_reg_info *hi)
484 {
485 struct unw_reg_info *reg;
486
487 for (reg = hi; reg >= lo; --reg)
488 {
489 if (reg->where == UNW_WHERE_SPILL_HOME)
490 {
491 reg->where = UNW_WHERE_PSPREL;
492 *offp -= regsize;
493 reg->val = *offp;
494 }
495 }
496 }
497
498 static inline void
499 spill_next_when (struct unw_reg_info **regp, struct unw_reg_info *lim,
500 unw_word t)
501 {
502 struct unw_reg_info *reg;
503
504 for (reg = *regp; reg <= lim; ++reg)
505 {
506 if (reg->where == UNW_WHERE_SPILL_HOME)
507 {
508 reg->when = t;
509 *regp = reg + 1;
510 return;
511 }
512 }
513 /* Excess spill. */
514 abort ();
515 }
516
517 static void
518 finish_prologue (struct unw_state_record *sr)
519 {
520 struct unw_reg_info *reg;
521 unsigned long off;
522 int i;
523
524 /* First, resolve implicit register save locations
525 (see Section "11.4.2.3 Rules for Using Unwind Descriptors", rule 3). */
526
527 for (i = 0; i < (int) sizeof (save_order); ++i)
528 {
529 reg = sr->curr.reg + save_order[i];
530 if (reg->where == UNW_WHERE_GR_SAVE)
531 {
532 reg->where = UNW_WHERE_GR;
533 reg->val = sr->gr_save_loc++;
534 }
535 }
536
537 /* Next, compute when the fp, general, and branch registers get saved.
538 This must come before alloc_spill_area() because we need to know
539 which registers are spilled to their home locations. */
540 if (sr->imask)
541 {
542 static unsigned char const limit[3] = {
543 UNW_REG_F31, UNW_REG_R7, UNW_REG_B5
544 };
545
546 unsigned char kind, mask = 0, *cp = sr->imask;
547 int t;
548 struct unw_reg_info *(regs[3]);
549
550 regs[0] = sr->curr.reg + UNW_REG_F2;
551 regs[1] = sr->curr.reg + UNW_REG_R4;
552 regs[2] = sr->curr.reg + UNW_REG_B1;
553
554 for (t = 0; t < sr->region_len; ++t)
555 {
556 if ((t & 3) == 0)
557 mask = *cp++;
558 kind = (mask >> 2*(3-(t & 3))) & 3;
559 if (kind > 0)
560 spill_next_when (&regs[kind - 1], sr->curr.reg + limit[kind - 1],
561 sr->region_start + t);
562 }
563 }
564
565 /* Next, lay out the memory stack spill area. */
566 if (sr->any_spills)
567 {
568 off = sr->spill_offset;
569 alloc_spill_area (&off, 16, sr->curr.reg + UNW_REG_F2,
570 sr->curr.reg + UNW_REG_F31);
571 alloc_spill_area (&off, 8, sr->curr.reg + UNW_REG_B1,
572 sr->curr.reg + UNW_REG_B5);
573 alloc_spill_area (&off, 8, sr->curr.reg + UNW_REG_R4,
574 sr->curr.reg + UNW_REG_R7);
575 }
576 }
577
578 /*
579 * Region header descriptors.
580 */
581
582 static void
583 desc_prologue (int body, unw_word rlen, unsigned char mask,
584 unsigned char grsave, struct unw_state_record *sr)
585 {
586 int i;
587
588 if (!(sr->in_body || sr->first_region))
589 finish_prologue (sr);
590 sr->first_region = 0;
591
592 /* Check if we're done. */
593 if (sr->when_target < sr->region_start + sr->region_len)
594 {
595 sr->done = 1;
596 return;
597 }
598
599 for (i = 0; i < sr->epilogue_count; ++i)
600 pop (sr);
601
602 sr->epilogue_count = 0;
603 sr->epilogue_start = UNW_WHEN_NEVER;
604
605 if (!body)
606 push (sr);
607
608 sr->region_start += sr->region_len;
609 sr->region_len = rlen;
610 sr->in_body = body;
611
612 if (!body)
613 {
614 for (i = 0; i < 4; ++i)
615 {
616 if (mask & 0x8)
617 set_reg (sr->curr.reg + save_order[i], UNW_WHERE_GR,
618 sr->region_start + sr->region_len - 1, grsave++);
619 mask <<= 1;
620 }
621 sr->gr_save_loc = grsave;
622 sr->any_spills = 0;
623 sr->imask = 0;
624 sr->spill_offset = 0x10; /* default to psp+16 */
625 }
626 }
627
628 /*
629 * Prologue descriptors.
630 */
631
632 static inline void
633 desc_abi (unsigned char abi,
634 unsigned char context,
635 struct unw_state_record *sr)
636 {
637 sr->unwabi = (abi << 8) | context;
638 }
639
640 static inline void
641 desc_br_gr (unsigned char brmask, unsigned char gr,
642 struct unw_state_record *sr)
643 {
644 int i;
645
646 for (i = 0; i < 5; ++i)
647 {
648 if (brmask & 1)
649 set_reg (sr->curr.reg + UNW_REG_B1 + i, UNW_WHERE_GR,
650 sr->region_start + sr->region_len - 1, gr++);
651 brmask >>= 1;
652 }
653 }
654
655 static inline void
656 desc_br_mem (unsigned char brmask, struct unw_state_record *sr)
657 {
658 int i;
659
660 for (i = 0; i < 5; ++i)
661 {
662 if (brmask & 1)
663 {
664 set_reg (sr->curr.reg + UNW_REG_B1 + i, UNW_WHERE_SPILL_HOME,
665 sr->region_start + sr->region_len - 1, 0);
666 sr->any_spills = 1;
667 }
668 brmask >>= 1;
669 }
670 }
671
672 static inline void
673 desc_frgr_mem (unsigned char grmask, unw_word frmask,
674 struct unw_state_record *sr)
675 {
676 int i;
677
678 for (i = 0; i < 4; ++i)
679 {
680 if ((grmask & 1) != 0)
681 {
682 set_reg (sr->curr.reg + UNW_REG_R4 + i, UNW_WHERE_SPILL_HOME,
683 sr->region_start + sr->region_len - 1, 0);
684 sr->any_spills = 1;
685 }
686 grmask >>= 1;
687 }
688 for (i = 0; i < 20; ++i)
689 {
690 if ((frmask & 1) != 0)
691 {
692 enum unw_register_index base = i < 4 ? UNW_REG_F2 : UNW_REG_F16 - 4;
693 set_reg (sr->curr.reg + base + i, UNW_WHERE_SPILL_HOME,
694 sr->region_start + sr->region_len - 1, 0);
695 sr->any_spills = 1;
696 }
697 frmask >>= 1;
698 }
699 }
700
701 static inline void
702 desc_fr_mem (unsigned char frmask, struct unw_state_record *sr)
703 {
704 int i;
705
706 for (i = 0; i < 4; ++i)
707 {
708 if ((frmask & 1) != 0)
709 {
710 set_reg (sr->curr.reg + UNW_REG_F2 + i, UNW_WHERE_SPILL_HOME,
711 sr->region_start + sr->region_len - 1, 0);
712 sr->any_spills = 1;
713 }
714 frmask >>= 1;
715 }
716 }
717
718 static inline void
719 desc_gr_gr (unsigned char grmask, unsigned char gr,
720 struct unw_state_record *sr)
721 {
722 int i;
723
724 for (i = 0; i < 4; ++i)
725 {
726 if ((grmask & 1) != 0)
727 set_reg (sr->curr.reg + UNW_REG_R4 + i, UNW_WHERE_GR,
728 sr->region_start + sr->region_len - 1, gr++);
729 grmask >>= 1;
730 }
731 }
732
733 static inline void
734 desc_gr_mem (unsigned char grmask, struct unw_state_record *sr)
735 {
736 int i;
737
738 for (i = 0; i < 4; ++i)
739 {
740 if ((grmask & 1) != 0)
741 {
742 set_reg (sr->curr.reg + UNW_REG_R4 + i, UNW_WHERE_SPILL_HOME,
743 sr->region_start + sr->region_len - 1, 0);
744 sr->any_spills = 1;
745 }
746 grmask >>= 1;
747 }
748 }
749
750 static inline void
751 desc_mem_stack_f (unw_word t, unw_word size, struct unw_state_record *sr)
752 {
753 set_reg (sr->curr.reg + UNW_REG_PSP, UNW_WHERE_NONE,
754 sr->region_start + MIN ((int)t, sr->region_len - 1), 16*size);
755 }
756
757 static inline void
758 desc_mem_stack_v (unw_word t, struct unw_state_record *sr)
759 {
760 sr->curr.reg[UNW_REG_PSP].when
761 = sr->region_start + MIN ((int)t, sr->region_len - 1);
762 }
763
764 static inline void
765 desc_reg_gr (unsigned char reg, unsigned char dst, struct unw_state_record *sr)
766 {
767 set_reg (sr->curr.reg + reg, UNW_WHERE_GR,
768 sr->region_start + sr->region_len - 1, dst);
769 }
770
771 static inline void
772 desc_reg_psprel (unsigned char reg, unw_word pspoff,
773 struct unw_state_record *sr)
774 {
775 set_reg (sr->curr.reg + reg, UNW_WHERE_PSPREL,
776 sr->region_start + sr->region_len - 1,
777 0x10 - 4*pspoff);
778 }
779
780 static inline void
781 desc_reg_sprel (unsigned char reg, unw_word spoff, struct unw_state_record *sr)
782 {
783 set_reg (sr->curr.reg + reg, UNW_WHERE_SPREL,
784 sr->region_start + sr->region_len - 1,
785 4*spoff);
786 }
787
788 static inline void
789 desc_rp_br (unsigned char dst, struct unw_state_record *sr)
790 {
791 sr->return_link_reg = dst;
792 }
793
794 static inline void
795 desc_reg_when (unsigned char regnum, unw_word t, struct unw_state_record *sr)
796 {
797 struct unw_reg_info *reg = sr->curr.reg + regnum;
798
799 if (reg->where == UNW_WHERE_NONE)
800 reg->where = UNW_WHERE_GR_SAVE;
801 reg->when = sr->region_start + MIN ((int)t, sr->region_len - 1);
802 }
803
804 static inline void
805 desc_spill_base (unw_word pspoff, struct unw_state_record *sr)
806 {
807 sr->spill_offset = 0x10 - 4*pspoff;
808 }
809
810 static inline unsigned char *
811 desc_spill_mask (unsigned char *imaskp, struct unw_state_record *sr)
812 {
813 sr->imask = imaskp;
814 return imaskp + (2*sr->region_len + 7)/8;
815 }
816
817 /*
818 * Body descriptors.
819 */
820 static inline void
821 desc_epilogue (unw_word t, unw_word ecount, struct unw_state_record *sr)
822 {
823 sr->epilogue_start = sr->region_start + sr->region_len - 1 - t;
824 sr->epilogue_count = ecount + 1;
825 }
826
827 static inline void
828 desc_copy_state (unw_word label, struct unw_state_record *sr)
829 {
830 struct unw_labeled_state *ls;
831
832 for (ls = sr->labeled_states; ls; ls = ls->next)
833 {
834 if (ls->label == label)
835 {
836 free_state_stack (&sr->curr);
837 memcpy (&sr->curr, &ls->saved_state, sizeof (sr->curr));
838 sr->curr.next = dup_state_stack (ls->saved_state.next);
839 return;
840 }
841 }
842 abort ();
843 }
844
845 static inline void
846 desc_label_state (unw_word label, struct unw_state_record *sr)
847 {
848 struct unw_labeled_state *ls = alloc_label_state ();
849
850 ls->label = label;
851 memcpy (&ls->saved_state, &sr->curr, sizeof (ls->saved_state));
852 ls->saved_state.next = dup_state_stack (sr->curr.next);
853
854 /* Insert into list of labeled states. */
855 ls->next = sr->labeled_states;
856 sr->labeled_states = ls;
857 }
858
859 /*
860 * General descriptors.
861 */
862
863 static inline int
864 desc_is_active (unsigned char qp, unw_word t, struct unw_state_record *sr)
865 {
866 if (sr->when_target <= sr->region_start + MIN ((int)t, sr->region_len - 1))
867 return 0;
868 if (qp > 0)
869 {
870 if ((sr->pr_val & (1UL << qp)) == 0)
871 return 0;
872 sr->pr_mask |= (1UL << qp);
873 }
874 return 1;
875 }
876
877 static inline void
878 desc_restore_p (unsigned char qp, unw_word t, unsigned char abreg,
879 struct unw_state_record *sr)
880 {
881 struct unw_reg_info *r;
882
883 if (! desc_is_active (qp, t, sr))
884 return;
885
886 r = sr->curr.reg + decode_abreg (abreg, 0);
887 r->where = UNW_WHERE_NONE;
888 r->when = sr->region_start + MIN ((int)t, sr->region_len - 1);
889 r->val = 0;
890 }
891
892 static inline void
893 desc_spill_reg_p (unsigned char qp, unw_word t, unsigned char abreg,
894 unsigned char x, unsigned char ytreg,
895 struct unw_state_record *sr)
896 {
897 enum unw_where where = UNW_WHERE_GR;
898 struct unw_reg_info *r;
899
900 if (! desc_is_active (qp, t, sr))
901 return;
902
903 if (x)
904 where = UNW_WHERE_BR;
905 else if (ytreg & 0x80)
906 where = UNW_WHERE_FR;
907
908 r = sr->curr.reg + decode_abreg (abreg, 0);
909 r->where = where;
910 r->when = sr->region_start + MIN ((int)t, sr->region_len - 1);
911 r->val = ytreg & 0x7f;
912 }
913
914 static inline void
915 desc_spill_psprel_p (unsigned char qp, unw_word t, unsigned char abreg,
916 unw_word pspoff, struct unw_state_record *sr)
917 {
918 struct unw_reg_info *r;
919
920 if (! desc_is_active (qp, t, sr))
921 return;
922
923 r = sr->curr.reg + decode_abreg (abreg, 1);
924 r->where = UNW_WHERE_PSPREL;
925 r->when = sr->region_start + MIN((int)t, sr->region_len - 1);
926 r->val = 0x10 - 4*pspoff;
927 }
928
929 static inline void
930 desc_spill_sprel_p (unsigned char qp, unw_word t, unsigned char abreg,
931 unw_word spoff, struct unw_state_record *sr)
932 {
933 struct unw_reg_info *r;
934
935 if (! desc_is_active (qp, t, sr))
936 return;
937
938 r = sr->curr.reg + decode_abreg (abreg, 1);
939 r->where = UNW_WHERE_SPREL;
940 r->when = sr->region_start + MIN ((int)t, sr->region_len - 1);
941 r->val = 4*spoff;
942 }
943
944 \f
945 #define UNW_DEC_BAD_CODE(code) abort ();
946
947 /* Region headers. */
948 #define UNW_DEC_PROLOGUE_GR(fmt,r,m,gr,arg) desc_prologue(0,r,m,gr,arg)
949 #define UNW_DEC_PROLOGUE(fmt,b,r,arg) desc_prologue(b,r,0,32,arg)
950
951 /* Prologue descriptors. */
952 #define UNW_DEC_ABI(fmt,a,c,arg) desc_abi(a,c,arg)
953 #define UNW_DEC_BR_GR(fmt,b,g,arg) desc_br_gr(b,g,arg)
954 #define UNW_DEC_BR_MEM(fmt,b,arg) desc_br_mem(b,arg)
955 #define UNW_DEC_FRGR_MEM(fmt,g,f,arg) desc_frgr_mem(g,f,arg)
956 #define UNW_DEC_FR_MEM(fmt,f,arg) desc_fr_mem(f,arg)
957 #define UNW_DEC_GR_GR(fmt,m,g,arg) desc_gr_gr(m,g,arg)
958 #define UNW_DEC_GR_MEM(fmt,m,arg) desc_gr_mem(m,arg)
959 #define UNW_DEC_MEM_STACK_F(fmt,t,s,arg) desc_mem_stack_f(t,s,arg)
960 #define UNW_DEC_MEM_STACK_V(fmt,t,arg) desc_mem_stack_v(t,arg)
961 #define UNW_DEC_REG_GR(fmt,r,d,arg) desc_reg_gr(r,d,arg)
962 #define UNW_DEC_REG_PSPREL(fmt,r,o,arg) desc_reg_psprel(r,o,arg)
963 #define UNW_DEC_REG_SPREL(fmt,r,o,arg) desc_reg_sprel(r,o,arg)
964 #define UNW_DEC_REG_WHEN(fmt,r,t,arg) desc_reg_when(r,t,arg)
965 #define UNW_DEC_PRIUNAT_WHEN_GR(fmt,t,arg) desc_reg_when(UNW_REG_PRI_UNAT_GR,t,arg)
966 #define UNW_DEC_PRIUNAT_WHEN_MEM(fmt,t,arg) desc_reg_when(UNW_REG_PRI_UNAT_MEM,t,arg)
967 #define UNW_DEC_PRIUNAT_GR(fmt,r,arg) desc_reg_gr(UNW_REG_PRI_UNAT_GR,r,arg)
968 #define UNW_DEC_PRIUNAT_PSPREL(fmt,o,arg) desc_reg_psprel(UNW_REG_PRI_UNAT_MEM,o,arg)
969 #define UNW_DEC_PRIUNAT_SPREL(fmt,o,arg) desc_reg_sprel(UNW_REG_PRI_UNAT_MEM,o,arg)
970 #define UNW_DEC_RP_BR(fmt,d,arg) desc_rp_br(d,arg)
971 #define UNW_DEC_SPILL_BASE(fmt,o,arg) desc_spill_base(o,arg)
972 #define UNW_DEC_SPILL_MASK(fmt,m,arg) (m = desc_spill_mask(m,arg))
973
974 /* Body descriptors. */
975 #define UNW_DEC_EPILOGUE(fmt,t,c,arg) desc_epilogue(t,c,arg)
976 #define UNW_DEC_COPY_STATE(fmt,l,arg) desc_copy_state(l,arg)
977 #define UNW_DEC_LABEL_STATE(fmt,l,arg) desc_label_state(l,arg)
978
979 /* General unwind descriptors. */
980 #define UNW_DEC_SPILL_REG_P(f,p,t,a,x,y,arg) desc_spill_reg_p(p,t,a,x,y,arg)
981 #define UNW_DEC_SPILL_REG(f,t,a,x,y,arg) desc_spill_reg_p(0,t,a,x,y,arg)
982 #define UNW_DEC_SPILL_PSPREL_P(f,p,t,a,o,arg) desc_spill_psprel_p(p,t,a,o,arg)
983 #define UNW_DEC_SPILL_PSPREL(f,t,a,o,arg) desc_spill_psprel_p(0,t,a,o,arg)
984 #define UNW_DEC_SPILL_SPREL_P(f,p,t,a,o,arg) desc_spill_sprel_p(p,t,a,o,arg)
985 #define UNW_DEC_SPILL_SPREL(f,t,a,o,arg) desc_spill_sprel_p(0,t,a,o,arg)
986 #define UNW_DEC_RESTORE_P(f,p,t,a,arg) desc_restore_p(p,t,a,arg)
987 #define UNW_DEC_RESTORE(f,t,a,arg) desc_restore_p(0,t,a,arg)
988
989 \f
990 /*
991 * Generic IA-64 unwind info decoder.
992 *
993 * This file is used both by the Linux kernel and objdump. Please keep
994 * the copies of this file in sync.
995 *
996 * You need to customize the decoder by defining the following
997 * macros/constants before including this file:
998 *
999 * Types:
1000 * unw_word Unsigned integer type with at least 64 bits
1001 *
1002 * Register names:
1003 * UNW_REG_BSP
1004 * UNW_REG_BSPSTORE
1005 * UNW_REG_FPSR
1006 * UNW_REG_LC
1007 * UNW_REG_PFS
1008 * UNW_REG_PR
1009 * UNW_REG_RNAT
1010 * UNW_REG_PSP
1011 * UNW_REG_RP
1012 * UNW_REG_UNAT
1013 *
1014 * Decoder action macros:
1015 * UNW_DEC_BAD_CODE(code)
1016 * UNW_DEC_ABI(fmt,abi,context,arg)
1017 * UNW_DEC_BR_GR(fmt,brmask,gr,arg)
1018 * UNW_DEC_BR_MEM(fmt,brmask,arg)
1019 * UNW_DEC_COPY_STATE(fmt,label,arg)
1020 * UNW_DEC_EPILOGUE(fmt,t,ecount,arg)
1021 * UNW_DEC_FRGR_MEM(fmt,grmask,frmask,arg)
1022 * UNW_DEC_FR_MEM(fmt,frmask,arg)
1023 * UNW_DEC_GR_GR(fmt,grmask,gr,arg)
1024 * UNW_DEC_GR_MEM(fmt,grmask,arg)
1025 * UNW_DEC_LABEL_STATE(fmt,label,arg)
1026 * UNW_DEC_MEM_STACK_F(fmt,t,size,arg)
1027 * UNW_DEC_MEM_STACK_V(fmt,t,arg)
1028 * UNW_DEC_PRIUNAT_GR(fmt,r,arg)
1029 * UNW_DEC_PRIUNAT_WHEN_GR(fmt,t,arg)
1030 * UNW_DEC_PRIUNAT_WHEN_MEM(fmt,t,arg)
1031 * UNW_DEC_PRIUNAT_WHEN_PSPREL(fmt,pspoff,arg)
1032 * UNW_DEC_PRIUNAT_WHEN_SPREL(fmt,spoff,arg)
1033 * UNW_DEC_PROLOGUE(fmt,body,rlen,arg)
1034 * UNW_DEC_PROLOGUE_GR(fmt,rlen,mask,grsave,arg)
1035 * UNW_DEC_REG_PSPREL(fmt,reg,pspoff,arg)
1036 * UNW_DEC_REG_REG(fmt,src,dst,arg)
1037 * UNW_DEC_REG_SPREL(fmt,reg,spoff,arg)
1038 * UNW_DEC_REG_WHEN(fmt,reg,t,arg)
1039 * UNW_DEC_RESTORE(fmt,t,abreg,arg)
1040 * UNW_DEC_RESTORE_P(fmt,qp,t,abreg,arg)
1041 * UNW_DEC_SPILL_BASE(fmt,pspoff,arg)
1042 * UNW_DEC_SPILL_MASK(fmt,imaskp,arg)
1043 * UNW_DEC_SPILL_PSPREL(fmt,t,abreg,pspoff,arg)
1044 * UNW_DEC_SPILL_PSPREL_P(fmt,qp,t,abreg,pspoff,arg)
1045 * UNW_DEC_SPILL_REG(fmt,t,abreg,x,ytreg,arg)
1046 * UNW_DEC_SPILL_REG_P(fmt,qp,t,abreg,x,ytreg,arg)
1047 * UNW_DEC_SPILL_SPREL(fmt,t,abreg,spoff,arg)
1048 * UNW_DEC_SPILL_SPREL_P(fmt,qp,t,abreg,pspoff,arg)
1049 */
1050
1051 static unw_word
1052 unw_decode_uleb128 (unsigned char **dpp)
1053 {
1054 unsigned shift = 0;
1055 unw_word byte, result = 0;
1056 unsigned char *bp = *dpp;
1057
1058 while (1)
1059 {
1060 byte = *bp++;
1061 result |= (byte & 0x7f) << shift;
1062 if ((byte & 0x80) == 0)
1063 break;
1064 shift += 7;
1065 }
1066 *dpp = bp;
1067 return result;
1068 }
1069
1070 static unsigned char *
1071 unw_decode_x1 (unsigned char *dp,
1072 unsigned char code __attribute__((unused)),
1073 void *arg)
1074 {
1075 unsigned char byte1, abreg;
1076 unw_word t, off;
1077
1078 byte1 = *dp++;
1079 t = unw_decode_uleb128 (&dp);
1080 off = unw_decode_uleb128 (&dp);
1081 abreg = (byte1 & 0x7f);
1082 if (byte1 & 0x80)
1083 UNW_DEC_SPILL_SPREL(X1, t, abreg, off, arg);
1084 else
1085 UNW_DEC_SPILL_PSPREL(X1, t, abreg, off, arg);
1086 return dp;
1087 }
1088
1089 static unsigned char *
1090 unw_decode_x2 (unsigned char *dp,
1091 unsigned char code __attribute__((unused)),
1092 void *arg)
1093 {
1094 unsigned char byte1, byte2, abreg, x, ytreg;
1095 unw_word t;
1096
1097 byte1 = *dp++; byte2 = *dp++;
1098 t = unw_decode_uleb128 (&dp);
1099 abreg = (byte1 & 0x7f);
1100 ytreg = byte2;
1101 x = (byte1 >> 7) & 1;
1102 if ((byte1 & 0x80) == 0 && ytreg == 0)
1103 UNW_DEC_RESTORE(X2, t, abreg, arg);
1104 else
1105 UNW_DEC_SPILL_REG(X2, t, abreg, x, ytreg, arg);
1106 return dp;
1107 }
1108
1109 static unsigned char *
1110 unw_decode_x3 (unsigned char *dp,
1111 unsigned char code __attribute__((unused)),
1112 void *arg)
1113 {
1114 unsigned char byte1, byte2, abreg, qp;
1115 unw_word t, off;
1116
1117 byte1 = *dp++; byte2 = *dp++;
1118 t = unw_decode_uleb128 (&dp);
1119 off = unw_decode_uleb128 (&dp);
1120
1121 qp = (byte1 & 0x3f);
1122 abreg = (byte2 & 0x7f);
1123
1124 if (byte1 & 0x80)
1125 UNW_DEC_SPILL_SPREL_P(X3, qp, t, abreg, off, arg);
1126 else
1127 UNW_DEC_SPILL_PSPREL_P(X3, qp, t, abreg, off, arg);
1128 return dp;
1129 }
1130
1131 static unsigned char *
1132 unw_decode_x4 (unsigned char *dp,
1133 unsigned char code __attribute__((unused)),
1134 void *arg)
1135 {
1136 unsigned char byte1, byte2, byte3, qp, abreg, x, ytreg;
1137 unw_word t;
1138
1139 byte1 = *dp++; byte2 = *dp++; byte3 = *dp++;
1140 t = unw_decode_uleb128 (&dp);
1141
1142 qp = (byte1 & 0x3f);
1143 abreg = (byte2 & 0x7f);
1144 x = (byte2 >> 7) & 1;
1145 ytreg = byte3;
1146
1147 if ((byte2 & 0x80) == 0 && byte3 == 0)
1148 UNW_DEC_RESTORE_P(X4, qp, t, abreg, arg);
1149 else
1150 UNW_DEC_SPILL_REG_P(X4, qp, t, abreg, x, ytreg, arg);
1151 return dp;
1152 }
1153
1154 static unsigned char *
1155 unw_decode_r1 (unsigned char *dp, unsigned char code, void *arg)
1156 {
1157 int body = (code & 0x20) != 0;
1158 unw_word rlen;
1159
1160 rlen = (code & 0x1f);
1161 UNW_DEC_PROLOGUE(R1, body, rlen, arg);
1162 return dp;
1163 }
1164
1165 static unsigned char *
1166 unw_decode_r2 (unsigned char *dp, unsigned char code, void *arg)
1167 {
1168 unsigned char byte1, mask, grsave;
1169 unw_word rlen;
1170
1171 byte1 = *dp++;
1172
1173 mask = ((code & 0x7) << 1) | ((byte1 >> 7) & 1);
1174 grsave = (byte1 & 0x7f);
1175 rlen = unw_decode_uleb128 (&dp);
1176 UNW_DEC_PROLOGUE_GR(R2, rlen, mask, grsave, arg);
1177 return dp;
1178 }
1179
1180 static unsigned char *
1181 unw_decode_r3 (unsigned char *dp, unsigned char code, void *arg)
1182 {
1183 unw_word rlen;
1184
1185 rlen = unw_decode_uleb128 (&dp);
1186 UNW_DEC_PROLOGUE(R3, ((code & 0x3) == 1), rlen, arg);
1187 return dp;
1188 }
1189
1190 static unsigned char *
1191 unw_decode_p1 (unsigned char *dp, unsigned char code, void *arg)
1192 {
1193 unsigned char brmask = (code & 0x1f);
1194
1195 UNW_DEC_BR_MEM(P1, brmask, arg);
1196 return dp;
1197 }
1198
1199 static unsigned char *
1200 unw_decode_p2_p5 (unsigned char *dp, unsigned char code, void *arg)
1201 {
1202 if ((code & 0x10) == 0)
1203 {
1204 unsigned char byte1 = *dp++;
1205
1206 UNW_DEC_BR_GR(P2, ((code & 0xf) << 1) | ((byte1 >> 7) & 1),
1207 (byte1 & 0x7f), arg);
1208 }
1209 else if ((code & 0x08) == 0)
1210 {
1211 unsigned char byte1 = *dp++, r, dst;
1212
1213 r = ((code & 0x7) << 1) | ((byte1 >> 7) & 1);
1214 dst = (byte1 & 0x7f);
1215 switch (r)
1216 {
1217 case 0: UNW_DEC_REG_GR(P3, UNW_REG_PSP, dst, arg); break;
1218 case 1: UNW_DEC_REG_GR(P3, UNW_REG_RP, dst, arg); break;
1219 case 2: UNW_DEC_REG_GR(P3, UNW_REG_PFS, dst, arg); break;
1220 case 3: UNW_DEC_REG_GR(P3, UNW_REG_PR, dst, arg); break;
1221 case 4: UNW_DEC_REG_GR(P3, UNW_REG_UNAT, dst, arg); break;
1222 case 5: UNW_DEC_REG_GR(P3, UNW_REG_LC, dst, arg); break;
1223 case 6: UNW_DEC_RP_BR(P3, dst, arg); break;
1224 case 7: UNW_DEC_REG_GR(P3, UNW_REG_RNAT, dst, arg); break;
1225 case 8: UNW_DEC_REG_GR(P3, UNW_REG_BSP, dst, arg); break;
1226 case 9: UNW_DEC_REG_GR(P3, UNW_REG_BSPSTORE, dst, arg); break;
1227 case 10: UNW_DEC_REG_GR(P3, UNW_REG_FPSR, dst, arg); break;
1228 case 11: UNW_DEC_PRIUNAT_GR(P3, dst, arg); break;
1229 default: UNW_DEC_BAD_CODE(r); break;
1230 }
1231 }
1232 else if ((code & 0x7) == 0)
1233 UNW_DEC_SPILL_MASK(P4, dp, arg);
1234 else if ((code & 0x7) == 1)
1235 {
1236 unw_word grmask, frmask, byte1, byte2, byte3;
1237
1238 byte1 = *dp++; byte2 = *dp++; byte3 = *dp++;
1239 grmask = ((byte1 >> 4) & 0xf);
1240 frmask = ((byte1 & 0xf) << 16) | (byte2 << 8) | byte3;
1241 UNW_DEC_FRGR_MEM(P5, grmask, frmask, arg);
1242 }
1243 else
1244 UNW_DEC_BAD_CODE(code);
1245 return dp;
1246 }
1247
1248 static unsigned char *
1249 unw_decode_p6 (unsigned char *dp, unsigned char code, void *arg)
1250 {
1251 int gregs = (code & 0x10) != 0;
1252 unsigned char mask = (code & 0x0f);
1253
1254 if (gregs)
1255 UNW_DEC_GR_MEM(P6, mask, arg);
1256 else
1257 UNW_DEC_FR_MEM(P6, mask, arg);
1258 return dp;
1259 }
1260
1261 static unsigned char *
1262 unw_decode_p7_p10 (unsigned char *dp, unsigned char code, void *arg)
1263 {
1264 unsigned char r, byte1, byte2;
1265 unw_word t, size;
1266
1267 if ((code & 0x10) == 0)
1268 {
1269 r = (code & 0xf);
1270 t = unw_decode_uleb128 (&dp);
1271 switch (r)
1272 {
1273 case 0:
1274 size = unw_decode_uleb128 (&dp);
1275 UNW_DEC_MEM_STACK_F(P7, t, size, arg);
1276 break;
1277
1278 case 1: UNW_DEC_MEM_STACK_V(P7, t, arg); break;
1279 case 2: UNW_DEC_SPILL_BASE(P7, t, arg); break;
1280 case 3: UNW_DEC_REG_SPREL(P7, UNW_REG_PSP, t, arg); break;
1281 case 4: UNW_DEC_REG_WHEN(P7, UNW_REG_RP, t, arg); break;
1282 case 5: UNW_DEC_REG_PSPREL(P7, UNW_REG_RP, t, arg); break;
1283 case 6: UNW_DEC_REG_WHEN(P7, UNW_REG_PFS, t, arg); break;
1284 case 7: UNW_DEC_REG_PSPREL(P7, UNW_REG_PFS, t, arg); break;
1285 case 8: UNW_DEC_REG_WHEN(P7, UNW_REG_PR, t, arg); break;
1286 case 9: UNW_DEC_REG_PSPREL(P7, UNW_REG_PR, t, arg); break;
1287 case 10: UNW_DEC_REG_WHEN(P7, UNW_REG_LC, t, arg); break;
1288 case 11: UNW_DEC_REG_PSPREL(P7, UNW_REG_LC, t, arg); break;
1289 case 12: UNW_DEC_REG_WHEN(P7, UNW_REG_UNAT, t, arg); break;
1290 case 13: UNW_DEC_REG_PSPREL(P7, UNW_REG_UNAT, t, arg); break;
1291 case 14: UNW_DEC_REG_WHEN(P7, UNW_REG_FPSR, t, arg); break;
1292 case 15: UNW_DEC_REG_PSPREL(P7, UNW_REG_FPSR, t, arg); break;
1293 default: UNW_DEC_BAD_CODE(r); break;
1294 }
1295 }
1296 else
1297 {
1298 switch (code & 0xf)
1299 {
1300 case 0x0: /* p8 */
1301 {
1302 r = *dp++;
1303 t = unw_decode_uleb128 (&dp);
1304 switch (r)
1305 {
1306 case 1: UNW_DEC_REG_SPREL(P8, UNW_REG_RP, t, arg); break;
1307 case 2: UNW_DEC_REG_SPREL(P8, UNW_REG_PFS, t, arg); break;
1308 case 3: UNW_DEC_REG_SPREL(P8, UNW_REG_PR, t, arg); break;
1309 case 4: UNW_DEC_REG_SPREL(P8, UNW_REG_LC, t, arg); break;
1310 case 5: UNW_DEC_REG_SPREL(P8, UNW_REG_UNAT, t, arg); break;
1311 case 6: UNW_DEC_REG_SPREL(P8, UNW_REG_FPSR, t, arg); break;
1312 case 7: UNW_DEC_REG_WHEN(P8, UNW_REG_BSP, t, arg); break;
1313 case 8: UNW_DEC_REG_PSPREL(P8, UNW_REG_BSP, t, arg); break;
1314 case 9: UNW_DEC_REG_SPREL(P8, UNW_REG_BSP, t, arg); break;
1315 case 10: UNW_DEC_REG_WHEN(P8, UNW_REG_BSPSTORE, t, arg); break;
1316 case 11: UNW_DEC_REG_PSPREL(P8, UNW_REG_BSPSTORE, t, arg); break;
1317 case 12: UNW_DEC_REG_SPREL(P8, UNW_REG_BSPSTORE, t, arg); break;
1318 case 13: UNW_DEC_REG_WHEN(P8, UNW_REG_RNAT, t, arg); break;
1319 case 14: UNW_DEC_REG_PSPREL(P8, UNW_REG_RNAT, t, arg); break;
1320 case 15: UNW_DEC_REG_SPREL(P8, UNW_REG_RNAT, t, arg); break;
1321 case 16: UNW_DEC_PRIUNAT_WHEN_GR(P8, t, arg); break;
1322 case 17: UNW_DEC_PRIUNAT_PSPREL(P8, t, arg); break;
1323 case 18: UNW_DEC_PRIUNAT_SPREL(P8, t, arg); break;
1324 case 19: UNW_DEC_PRIUNAT_WHEN_MEM(P8, t, arg); break;
1325 default: UNW_DEC_BAD_CODE(r); break;
1326 }
1327 }
1328 break;
1329
1330 case 0x1:
1331 byte1 = *dp++; byte2 = *dp++;
1332 UNW_DEC_GR_GR(P9, (byte1 & 0xf), (byte2 & 0x7f), arg);
1333 break;
1334
1335 case 0xf: /* p10 */
1336 byte1 = *dp++; byte2 = *dp++;
1337 UNW_DEC_ABI(P10, byte1, byte2, arg);
1338 break;
1339
1340 case 0x9:
1341 return unw_decode_x1 (dp, code, arg);
1342
1343 case 0xa:
1344 return unw_decode_x2 (dp, code, arg);
1345
1346 case 0xb:
1347 return unw_decode_x3 (dp, code, arg);
1348
1349 case 0xc:
1350 return unw_decode_x4 (dp, code, arg);
1351
1352 default:
1353 UNW_DEC_BAD_CODE(code);
1354 break;
1355 }
1356 }
1357 return dp;
1358 }
1359
1360 static unsigned char *
1361 unw_decode_b1 (unsigned char *dp, unsigned char code, void *arg)
1362 {
1363 unw_word label = (code & 0x1f);
1364
1365 if ((code & 0x20) != 0)
1366 UNW_DEC_COPY_STATE(B1, label, arg);
1367 else
1368 UNW_DEC_LABEL_STATE(B1, label, arg);
1369 return dp;
1370 }
1371
1372 static unsigned char *
1373 unw_decode_b2 (unsigned char *dp, unsigned char code, void *arg)
1374 {
1375 unw_word t;
1376
1377 t = unw_decode_uleb128 (&dp);
1378 UNW_DEC_EPILOGUE(B2, t, (code & 0x1f), arg);
1379 return dp;
1380 }
1381
1382 static unsigned char *
1383 unw_decode_b3_x4 (unsigned char *dp, unsigned char code, void *arg)
1384 {
1385 unw_word t, ecount, label;
1386
1387 if ((code & 0x10) == 0)
1388 {
1389 t = unw_decode_uleb128 (&dp);
1390 ecount = unw_decode_uleb128 (&dp);
1391 UNW_DEC_EPILOGUE(B3, t, ecount, arg);
1392 }
1393 else if ((code & 0x07) == 0)
1394 {
1395 label = unw_decode_uleb128 (&dp);
1396 if ((code & 0x08) != 0)
1397 UNW_DEC_COPY_STATE(B4, label, arg);
1398 else
1399 UNW_DEC_LABEL_STATE(B4, label, arg);
1400 }
1401 else
1402 switch (code & 0x7)
1403 {
1404 case 1: return unw_decode_x1 (dp, code, arg);
1405 case 2: return unw_decode_x2 (dp, code, arg);
1406 case 3: return unw_decode_x3 (dp, code, arg);
1407 case 4: return unw_decode_x4 (dp, code, arg);
1408 default: UNW_DEC_BAD_CODE(code); break;
1409 }
1410 return dp;
1411 }
1412
1413 typedef unsigned char *(*unw_decoder) (unsigned char *, unsigned char, void *);
1414
1415 static const unw_decoder unw_decode_table[2][8] =
1416 {
1417 /* prologue table: */
1418 {
1419 unw_decode_r1, /* 0 */
1420 unw_decode_r1,
1421 unw_decode_r2,
1422 unw_decode_r3,
1423 unw_decode_p1, /* 4 */
1424 unw_decode_p2_p5,
1425 unw_decode_p6,
1426 unw_decode_p7_p10
1427 },
1428 {
1429 unw_decode_r1, /* 0 */
1430 unw_decode_r1,
1431 unw_decode_r2,
1432 unw_decode_r3,
1433 unw_decode_b1, /* 4 */
1434 unw_decode_b1,
1435 unw_decode_b2,
1436 unw_decode_b3_x4
1437 }
1438 };
1439
1440 /*
1441 * Decode one descriptor and return address of next descriptor.
1442 */
1443 static inline unsigned char *
1444 unw_decode (unsigned char *dp, int inside_body, void *arg)
1445 {
1446 unw_decoder decoder;
1447 unsigned char code;
1448
1449 code = *dp++;
1450 decoder = unw_decode_table[inside_body][code >> 5];
1451 dp = (*decoder) (dp, code, arg);
1452 return dp;
1453 }
1454
1455 \f
1456 /* RSE helper functions. */
1457
1458 static inline unsigned long
1459 ia64_rse_slot_num (unsigned long *addr)
1460 {
1461 return (((unsigned long) addr) >> 3) & 0x3f;
1462 }
1463
1464 /* Return TRUE if ADDR is the address of an RNAT slot. */
1465 static inline unsigned long
1466 ia64_rse_is_rnat_slot (unsigned long *addr)
1467 {
1468 return ia64_rse_slot_num (addr) == 0x3f;
1469 }
1470
1471 /* Returns the address of the RNAT slot that covers the slot at
1472 address SLOT_ADDR. */
1473 static inline unsigned long *
1474 ia64_rse_rnat_addr (unsigned long *slot_addr)
1475 {
1476 return (unsigned long *) ((unsigned long) slot_addr | (0x3f << 3));
1477 }
1478
1479 /* Calculate the number of registers in the dirty partition starting at
1480 BSPSTORE with a size of DIRTY bytes. This isn't simply DIRTY
1481 divided by eight because the 64th slot is used to store ar.rnat. */
1482 static inline unsigned long
1483 ia64_rse_num_regs (unsigned long *bspstore, unsigned long *bsp)
1484 {
1485 unsigned long slots = (bsp - bspstore);
1486
1487 return slots - (ia64_rse_slot_num (bspstore) + slots)/0x40;
1488 }
1489
1490 /* The inverse of the above: given bspstore and the number of
1491 registers, calculate ar.bsp. */
1492 static inline unsigned long *
1493 ia64_rse_skip_regs (unsigned long *addr, long num_regs)
1494 {
1495 long delta = ia64_rse_slot_num (addr) + num_regs;
1496
1497 if (num_regs < 0)
1498 delta -= 0x3e;
1499 return addr + num_regs + delta/0x3f;
1500 }
1501
1502 \f
1503 /* Copy register backing store from SRC to DST, LEN words
1504 (which include both saved registers and nat collections).
1505 DST_RNAT is a partial nat collection for DST. SRC and DST
1506 don't have to be equal modulo 64 slots, so it cannot be
1507 done with a simple memcpy as the nat collections will be
1508 at different relative offsets and need to be combined together. */
1509 static void
1510 ia64_copy_rbs (struct _Unwind_Context *info, unsigned long dst,
1511 unsigned long src, long len, unsigned long dst_rnat)
1512 {
1513 long count;
1514 unsigned long src_rnat;
1515 unsigned long shift1, shift2;
1516
1517 len <<= 3;
1518 dst_rnat &= (1UL << ((dst >> 3) & 0x3f)) - 1;
1519 src_rnat = src >= info->regstk_top
1520 ? info->rnat : *(unsigned long *) (src | 0x1f8);
1521 src_rnat &= ~((1UL << ((src >> 3) & 0x3f)) - 1);
1522 /* Just to make sure. */
1523 src_rnat &= ~(1UL << 63);
1524 shift1 = ((dst - src) >> 3) & 0x3f;
1525 if ((dst & 0x1f8) < (src & 0x1f8))
1526 shift1--;
1527 shift2 = 0x3f - shift1;
1528 if ((dst & 0x1f8) >= (src & 0x1f8))
1529 {
1530 count = ~dst & 0x1f8;
1531 goto first;
1532 }
1533 count = ~src & 0x1f8;
1534 goto second;
1535 while (len > 0)
1536 {
1537 src_rnat = src >= info->regstk_top
1538 ? info->rnat : *(unsigned long *) (src | 0x1f8);
1539 /* Just to make sure. */
1540 src_rnat &= ~(1UL << 63);
1541 count = shift2 << 3;
1542 first:
1543 if (count > len)
1544 count = len;
1545 memcpy ((char *) dst, (char *) src, count);
1546 dst += count;
1547 src += count;
1548 len -= count;
1549 dst_rnat |= (src_rnat << shift1) & ~(1UL << 63);
1550 if (len <= 0)
1551 break;
1552 *(long *) dst = dst_rnat;
1553 dst += 8;
1554 dst_rnat = 0;
1555 count = shift1 << 3;
1556 second:
1557 if (count > len)
1558 count = len;
1559 memcpy ((char *) dst, (char *) src, count);
1560 dst += count;
1561 src += count + 8;
1562 len -= count + 8;
1563 dst_rnat |= (src_rnat >> shift2);
1564 }
1565 if ((dst & 0x1f8) == 0x1f8)
1566 {
1567 *(long *) dst = dst_rnat;
1568 dst += 8;
1569 dst_rnat = 0;
1570 }
1571 /* Set info->regstk_top to lowest rbs address which will use
1572 info->rnat collection. */
1573 info->regstk_top = dst & ~0x1ffUL;
1574 info->rnat = dst_rnat;
1575 }
1576
1577 /* Unwind accessors. */
1578
1579 static void
1580 unw_access_gr (struct _Unwind_Context *info, int regnum,
1581 unsigned long *val, char *nat, int write)
1582 {
1583 unsigned long *addr, *nat_addr = 0, nat_mask = 0, dummy_nat;
1584 struct unw_ireg *ireg;
1585
1586 if ((unsigned) regnum - 1 >= 127)
1587 abort ();
1588
1589 if (regnum < 1)
1590 {
1591 nat_addr = addr = &dummy_nat;
1592 dummy_nat = 0;
1593 }
1594 else if (regnum < 32)
1595 {
1596 /* Access a non-stacked register. */
1597 ireg = &info->ireg[regnum - 2];
1598 addr = ireg->loc;
1599 if (addr)
1600 {
1601 nat_addr = addr + ireg->nat.off;
1602 switch (ireg->nat.type)
1603 {
1604 case UNW_NAT_VAL:
1605 /* Simulate getf.sig/setf.sig. */
1606 if (write)
1607 {
1608 if (*nat)
1609 {
1610 /* Write NaTVal and be done with it. */
1611 addr[0] = 0;
1612 addr[1] = 0x1fffe;
1613 return;
1614 }
1615 addr[1] = 0x1003e;
1616 }
1617 else if (addr[0] == 0 && addr[1] == 0x1ffe)
1618 {
1619 /* Return NaT and be done with it. */
1620 *val = 0;
1621 *nat = 1;
1622 return;
1623 }
1624 /* FALLTHRU */
1625
1626 case UNW_NAT_NONE:
1627 dummy_nat = 0;
1628 nat_addr = &dummy_nat;
1629 break;
1630
1631 case UNW_NAT_MEMSTK:
1632 nat_mask = 1UL << ((long) addr & 0x1f8)/8;
1633 break;
1634
1635 case UNW_NAT_REGSTK:
1636 if ((unsigned long) addr >= info->regstk_top)
1637 nat_addr = &info->rnat;
1638 else
1639 nat_addr = ia64_rse_rnat_addr (addr);
1640 nat_mask = 1UL << ia64_rse_slot_num (addr);
1641 break;
1642 }
1643 }
1644 }
1645 else
1646 {
1647 /* Access a stacked register. */
1648 addr = ia64_rse_skip_regs ((unsigned long *) info->bsp, regnum - 32);
1649 if ((unsigned long) addr >= info->regstk_top)
1650 nat_addr = &info->rnat;
1651 else
1652 nat_addr = ia64_rse_rnat_addr (addr);
1653 nat_mask = 1UL << ia64_rse_slot_num (addr);
1654 }
1655
1656 if (write)
1657 {
1658 *addr = *val;
1659 if (*nat)
1660 *nat_addr |= nat_mask;
1661 else
1662 *nat_addr &= ~nat_mask;
1663 }
1664 else
1665 {
1666 *val = *addr;
1667 *nat = (*nat_addr & nat_mask) != 0;
1668 }
1669 }
1670 \f
1671 /* Get the value of register REG as saved in CONTEXT. */
1672
1673 _Unwind_Word
1674 _Unwind_GetGR (struct _Unwind_Context *context, int index)
1675 {
1676 _Unwind_Word ret;
1677 char nat;
1678
1679 if (index == 1)
1680 return context->gp;
1681 else if (index >= 15 && index <= 18)
1682 return context->eh_data[index - 15];
1683 else
1684 unw_access_gr (context, index, &ret, &nat, 0);
1685
1686 return ret;
1687 }
1688
1689 /* Overwrite the saved value for register REG in CONTEXT with VAL. */
1690
1691 void
1692 _Unwind_SetGR (struct _Unwind_Context *context, int index, _Unwind_Word val)
1693 {
1694 char nat = 0;
1695
1696 if (index == 1)
1697 context->gp = val;
1698 else if (index >= 15 && index <= 18)
1699 context->eh_data[index - 15] = val;
1700 else
1701 unw_access_gr (context, index, &val, &nat, 1);
1702 }
1703
1704 /* Retrieve the return address for CONTEXT. */
1705
1706 inline _Unwind_Ptr
1707 _Unwind_GetIP (struct _Unwind_Context *context)
1708 {
1709 return context->rp;
1710 }
1711
1712 inline _Unwind_Ptr
1713 _Unwind_GetIPInfo (struct _Unwind_Context *context, int *ip_before_insn)
1714 {
1715 *ip_before_insn = 0;
1716 return context->rp;
1717 }
1718
1719 /* Overwrite the return address for CONTEXT with VAL. */
1720
1721 inline void
1722 _Unwind_SetIP (struct _Unwind_Context *context, _Unwind_Ptr val)
1723 {
1724 context->rp = val;
1725 }
1726
1727 void *
1728 _Unwind_GetLanguageSpecificData (struct _Unwind_Context *context)
1729 {
1730 return context->lsda;
1731 }
1732
1733 _Unwind_Ptr
1734 _Unwind_GetRegionStart (struct _Unwind_Context *context)
1735 {
1736 return context->region_start;
1737 }
1738
1739 void *
1740 _Unwind_FindEnclosingFunction (void *pc)
1741 {
1742 struct unw_table_entry *entp, ent;
1743 unsigned long segment_base, gp;
1744
1745 entp = _Unwind_FindTableEntry (pc, &segment_base, &gp, &ent);
1746 if (entp == NULL)
1747 return NULL;
1748 else
1749 return (void *)(segment_base + entp->start_offset);
1750 }
1751
1752 /* Get the value of the CFA as saved in CONTEXT. In GCC/Dwarf2 parlance,
1753 the CFA is the value of the stack pointer on entry; In IA-64 unwind
1754 parlance, this is the PSP. */
1755
1756 _Unwind_Word
1757 _Unwind_GetCFA (struct _Unwind_Context *context)
1758 {
1759 return (_Unwind_Ptr) context->psp;
1760 }
1761
1762 /* Get the value of the Backing Store Pointer as saved in CONTEXT. */
1763
1764 _Unwind_Word
1765 _Unwind_GetBSP (struct _Unwind_Context *context)
1766 {
1767 return (_Unwind_Ptr) context->bsp;
1768 }
1769
1770 #include "md-unwind-support.h"
1771 \f
1772 static _Unwind_Reason_Code
1773 uw_frame_state_for (struct _Unwind_Context *context, _Unwind_FrameState *fs)
1774 {
1775 struct unw_table_entry *entp, ent;
1776 unsigned long *unw, header, length;
1777 unsigned char *insn, *insn_end;
1778 unsigned long segment_base;
1779 struct unw_reg_info *r;
1780
1781 memset (fs, 0, sizeof (*fs));
1782 for (r = fs->curr.reg; r < fs->curr.reg + UNW_NUM_REGS; ++r)
1783 r->when = UNW_WHEN_NEVER;
1784 context->lsda = 0;
1785
1786 entp = _Unwind_FindTableEntry ((void *) context->rp,
1787 &segment_base, &context->gp, &ent);
1788 if (entp == NULL)
1789 {
1790 /* Couldn't find unwind info for this function. Try an
1791 os-specific fallback mechanism. This will necessarily
1792 not provide a personality routine or LSDA. */
1793 #ifdef MD_FALLBACK_FRAME_STATE_FOR
1794 if (MD_FALLBACK_FRAME_STATE_FOR (context, fs) == _URC_NO_REASON)
1795 return _URC_NO_REASON;
1796 #endif
1797
1798 /* [SCRA 11.4.1] A leaf function with no memory stack, no exception
1799 handlers, and which keeps the return value in B0 does not need
1800 an unwind table entry.
1801
1802 This can only happen in the frame after unwinding through a signal
1803 handler. Avoid infinite looping by requiring that B0 != RP.
1804 RP == 0 terminates the chain. */
1805 if (context->br_loc[0]
1806 && *context->br_loc[0] != context->rp
1807 && context->rp != 0)
1808 goto skip_unwind_info;
1809
1810 return _URC_END_OF_STACK;
1811 }
1812
1813 context->region_start = entp->start_offset + segment_base;
1814 fs->when_target = ((context->rp & -16) - context->region_start) / 16 * 3
1815 + (context->rp & 15);
1816
1817 unw = (unsigned long *) (entp->info_offset + segment_base);
1818 header = *unw;
1819 length = UNW_LENGTH (header);
1820
1821 /* Some operating systems use the personality routine slot in way not
1822 compatible with what we expect. For instance, OpenVMS uses this slot to
1823 designate "condition handlers" with very different arguments than what we
1824 would be providing. Such cases are typically identified from OS specific
1825 bits in the unwind information block header, and checked by the target
1826 MD_UNW_COMPATIBLE_PERSONALITY_P macro.
1827
1828 We just pretend there is no personality from our standpoint in such
1829 situations, and expect GCC not to set the identifying bits itself so that
1830 compatible personalities for GCC compiled code are called.
1831
1832 Of course, this raises the question of what combinations of native/GCC
1833 calls can be expected to behave properly exception handling-wise. We are
1834 not to provide a magic answer here, merely to prevent crashes assuming
1835 users know what they are doing.
1836
1837 ??? Perhaps check UNW_VER / UNW_FLAG_OSMASK as well. */
1838
1839 if (MD_UNW_COMPATIBLE_PERSONALITY_P (header)
1840 && (UNW_FLAG_EHANDLER (header) | UNW_FLAG_UHANDLER (header)))
1841 {
1842 fs->personality =
1843 *(_Unwind_Personality_Fn *) (unw[length + 1] + context->gp);
1844 context->lsda = unw + length + 2;
1845 }
1846
1847 insn = (unsigned char *) (unw + 1);
1848 insn_end = (unsigned char *) (unw + 1 + length);
1849 while (!fs->done && insn < insn_end)
1850 insn = unw_decode (insn, fs->in_body, fs);
1851
1852 free_label_states (fs->labeled_states);
1853 free_state_stack (&fs->curr);
1854
1855 #ifdef ENABLE_MALLOC_CHECKING
1856 if (reg_state_alloced || labeled_state_alloced)
1857 abort ();
1858 #endif
1859
1860 /* If we're in the epilogue, sp has been restored and all values
1861 on the memory stack below psp also have been restored. */
1862 if (fs->when_target > fs->epilogue_start)
1863 {
1864 struct unw_reg_info *r;
1865
1866 fs->curr.reg[UNW_REG_PSP].where = UNW_WHERE_NONE;
1867 fs->curr.reg[UNW_REG_PSP].val = 0;
1868 for (r = fs->curr.reg; r < fs->curr.reg + UNW_NUM_REGS; ++r)
1869 if ((r->where == UNW_WHERE_PSPREL && r->val <= 0x10)
1870 || r->where == UNW_WHERE_SPREL)
1871 r->where = UNW_WHERE_NONE;
1872 }
1873
1874 skip_unwind_info:
1875 /* If RP didn't get saved, generate entry for the return link register. */
1876 if (fs->curr.reg[UNW_REG_RP].when >= fs->when_target)
1877 {
1878 fs->curr.reg[UNW_REG_RP].where = UNW_WHERE_BR;
1879 fs->curr.reg[UNW_REG_RP].when = -1;
1880 fs->curr.reg[UNW_REG_RP].val = fs->return_link_reg;
1881 }
1882
1883 /* There is a subtlety for the frame after unwinding through a signal
1884 handler: should we restore the cfm as usual or the pfs? We can't
1885 restore both because we use br.ret to resume execution of user code.
1886 For other frames the procedure is by definition non-leaf so the pfs
1887 is saved and restored and thus effectively dead in the body; only
1888 the cfm need therefore be restored.
1889
1890 Here we have 2 cases:
1891 - either the pfs is saved and restored and thus effectively dead
1892 like in regular frames; then we do nothing special and restore
1893 the cfm.
1894 - or the pfs is not saved and thus live; but in that case the
1895 procedure is necessarily leaf so the cfm is effectively dead
1896 and we restore the pfs. */
1897 if (context->signal_pfs_loc)
1898 {
1899 if (fs->curr.reg[UNW_REG_PFS].when >= fs->when_target)
1900 context->pfs_loc = context->signal_pfs_loc;
1901 context->signal_pfs_loc = NULL;
1902 }
1903
1904 return _URC_NO_REASON;
1905 }
1906
1907 static void
1908 uw_update_reg_address (struct _Unwind_Context *context,
1909 _Unwind_FrameState *fs,
1910 enum unw_register_index regno)
1911 {
1912 struct unw_reg_info *r = fs->curr.reg + regno;
1913 void *addr;
1914 unsigned long rval;
1915
1916 if (r->where == UNW_WHERE_NONE || r->when >= fs->when_target)
1917 return;
1918
1919 rval = r->val;
1920 switch (r->where)
1921 {
1922 case UNW_WHERE_GR:
1923 if (rval >= 32)
1924 addr = ia64_rse_skip_regs ((unsigned long *) context->bsp, rval - 32);
1925 else if (rval >= 2)
1926 addr = context->ireg[rval - 2].loc;
1927 else if (rval == 0)
1928 {
1929 static const unsigned long dummy;
1930 addr = (void *) &dummy;
1931 }
1932 else
1933 abort ();
1934 break;
1935
1936 case UNW_WHERE_FR:
1937 if (rval >= 2 && rval < 32)
1938 addr = context->fr_loc[rval - 2];
1939 else
1940 abort ();
1941 break;
1942
1943 case UNW_WHERE_BR:
1944 /* Note that while RVAL can only be 1-5 from normal descriptors,
1945 we can want to look at B0, B6 and B7 due to having manually unwound a
1946 signal frame. */
1947 if (rval < 8)
1948 addr = context->br_loc[rval];
1949 else
1950 abort ();
1951 break;
1952
1953 case UNW_WHERE_SPREL:
1954 addr = (void *)(context->sp + rval);
1955 break;
1956
1957 case UNW_WHERE_PSPREL:
1958 addr = (void *)(context->psp + rval);
1959 break;
1960
1961 default:
1962 abort ();
1963 }
1964
1965 switch (regno)
1966 {
1967 case UNW_REG_R2 ... UNW_REG_R31:
1968 context->ireg[regno - UNW_REG_R2].loc = addr;
1969 switch (r->where)
1970 {
1971 case UNW_WHERE_GR:
1972 if (rval >= 32)
1973 {
1974 context->ireg[regno - UNW_REG_R2].nat.type = UNW_NAT_MEMSTK;
1975 context->ireg[regno - UNW_REG_R2].nat.off
1976 = context->pri_unat_loc - (unsigned long *) addr;
1977 }
1978 else if (rval >= 2)
1979 {
1980 context->ireg[regno - UNW_REG_R2].nat
1981 = context->ireg[rval - 2].nat;
1982 }
1983 else if (rval == 0)
1984 {
1985 context->ireg[regno - UNW_REG_R2].nat.type = UNW_NAT_NONE;
1986 context->ireg[regno - UNW_REG_R2].nat.off = 0;
1987 }
1988 else
1989 abort ();
1990 break;
1991
1992 case UNW_WHERE_FR:
1993 context->ireg[regno - UNW_REG_R2].nat.type = UNW_NAT_VAL;
1994 context->ireg[regno - UNW_REG_R2].nat.off = 0;
1995 break;
1996
1997 case UNW_WHERE_BR:
1998 context->ireg[regno - UNW_REG_R2].nat.type = UNW_NAT_NONE;
1999 context->ireg[regno - UNW_REG_R2].nat.off = 0;
2000 break;
2001
2002 case UNW_WHERE_PSPREL:
2003 case UNW_WHERE_SPREL:
2004 context->ireg[regno - UNW_REG_R2].nat.type = UNW_NAT_MEMSTK;
2005 context->ireg[regno - UNW_REG_R2].nat.off
2006 = context->pri_unat_loc - (unsigned long *) addr;
2007 break;
2008
2009 default:
2010 abort ();
2011 }
2012 break;
2013
2014 case UNW_REG_F2 ... UNW_REG_F31:
2015 context->fr_loc[regno - UNW_REG_F2] = addr;
2016 break;
2017
2018 case UNW_REG_B1 ... UNW_REG_B5:
2019 context->br_loc[regno - UNW_REG_B0] = addr;
2020 break;
2021
2022 case UNW_REG_BSP:
2023 context->bsp_loc = addr;
2024 break;
2025 case UNW_REG_BSPSTORE:
2026 context->bspstore_loc = addr;
2027 break;
2028 case UNW_REG_PFS:
2029 context->pfs_loc = addr;
2030 break;
2031 case UNW_REG_RP:
2032 context->rp = *(unsigned long *)addr;
2033 break;
2034 case UNW_REG_UNAT:
2035 context->unat_loc = addr;
2036 break;
2037 case UNW_REG_PR:
2038 context->pr = *(unsigned long *) addr;
2039 break;
2040 case UNW_REG_LC:
2041 context->lc_loc = addr;
2042 break;
2043 case UNW_REG_FPSR:
2044 context->fpsr_loc = addr;
2045 break;
2046
2047 case UNW_REG_PSP:
2048 context->psp = *(unsigned long *)addr;
2049 break;
2050
2051 default:
2052 abort ();
2053 }
2054 }
2055
2056 static void
2057 uw_update_context (struct _Unwind_Context *context, _Unwind_FrameState *fs)
2058 {
2059 long i;
2060
2061 #ifdef MD_HANDLE_UNWABI
2062 MD_HANDLE_UNWABI (context, fs);
2063 #endif
2064
2065 context->sp = context->psp;
2066
2067 /* First, set PSP. Subsequent instructions may depend on this value. */
2068 if (fs->when_target > fs->curr.reg[UNW_REG_PSP].when)
2069 {
2070 if (fs->curr.reg[UNW_REG_PSP].where == UNW_WHERE_NONE)
2071 context->psp = context->psp + fs->curr.reg[UNW_REG_PSP].val;
2072 else
2073 uw_update_reg_address (context, fs, UNW_REG_PSP);
2074 }
2075
2076 /* Determine the location of the primary UNaT. */
2077 {
2078 int i;
2079 if (fs->when_target < fs->curr.reg[UNW_REG_PRI_UNAT_GR].when)
2080 i = UNW_REG_PRI_UNAT_MEM;
2081 else if (fs->when_target < fs->curr.reg[UNW_REG_PRI_UNAT_MEM].when)
2082 i = UNW_REG_PRI_UNAT_GR;
2083 else if (fs->curr.reg[UNW_REG_PRI_UNAT_MEM].when
2084 > fs->curr.reg[UNW_REG_PRI_UNAT_GR].when)
2085 i = UNW_REG_PRI_UNAT_MEM;
2086 else
2087 i = UNW_REG_PRI_UNAT_GR;
2088 uw_update_reg_address (context, fs, i);
2089 }
2090
2091 /* Compute the addresses of all registers saved in this frame. */
2092 for (i = UNW_REG_BSP; i < UNW_NUM_REGS; ++i)
2093 uw_update_reg_address (context, fs, i);
2094
2095 /* Unwind BSP for the local registers allocated this frame. */
2096 /* ??? What to do with stored BSP or BSPSTORE registers. */
2097 /* We assert that we are either at a call site, or we have
2098 just unwound through a signal frame. In either case
2099 pfs_loc is valid. */
2100 if (!(fs -> no_reg_stack_frame))
2101 {
2102 unsigned long pfs = *context->pfs_loc;
2103 unsigned long sol = (pfs >> 7) & 0x7f;
2104 context->bsp = (unsigned long)
2105 ia64_rse_skip_regs ((unsigned long *) context->bsp, -sol);
2106 }
2107 }
2108
2109 static void
2110 uw_advance_context (struct _Unwind_Context *context, _Unwind_FrameState *fs)
2111 {
2112 uw_update_context (context, fs);
2113 }
2114
2115 /* Fill in CONTEXT for top-of-stack. The only valid registers at this
2116 level will be the return address and the CFA. Note that CFA = SP+16. */
2117
2118 #define uw_init_context(CONTEXT) \
2119 do { \
2120 /* ??? There is a whole lot o code in uw_install_context that \
2121 tries to avoid spilling the entire machine state here. We \
2122 should try to make that work again. */ \
2123 __builtin_unwind_init(); \
2124 uw_init_context_1 (CONTEXT, __builtin_ia64_bsp ()); \
2125 } while (0)
2126
2127 static void __attribute__((noinline))
2128 uw_init_context_1 (struct _Unwind_Context *context, void *bsp)
2129 {
2130 void *rp = __builtin_extract_return_addr (__builtin_return_address (0));
2131 /* Set psp to the caller's stack pointer. */
2132 void *psp = __builtin_dwarf_cfa () - 16;
2133 _Unwind_FrameState fs;
2134 unsigned long rnat, tmp1, tmp2;
2135
2136 /* Flush the register stack to memory so that we can access it.
2137 Get rse nat collection for the last incomplete rbs chunk of
2138 registers at the same time. For this RSE needs to be turned
2139 into the mandatory only mode. */
2140 asm ("mov.m %1 = ar.rsc;;\n\t"
2141 "and %2 = 0x1c, %1;;\n\t"
2142 "mov.m ar.rsc = %2;;\n\t"
2143 "flushrs;;\n\t"
2144 "mov.m %0 = ar.rnat;;\n\t"
2145 "mov.m ar.rsc = %1\n\t"
2146 : "=r" (rnat), "=r" (tmp1), "=r" (tmp2));
2147
2148 memset (context, 0, sizeof (struct _Unwind_Context));
2149 context->bsp = (unsigned long) bsp;
2150 /* Set context->regstk_top to lowest rbs address which will use
2151 context->rnat collection. */
2152 context->regstk_top = context->bsp & ~0x1ffULL;
2153 context->rnat = rnat;
2154 context->psp = (unsigned long) psp;
2155 context->rp = (unsigned long) rp;
2156 asm ("mov %0 = sp" : "=r" (context->sp));
2157 asm ("mov %0 = pr" : "=r" (context->pr));
2158 context->pri_unat_loc = &context->initial_unat; /* ??? */
2159
2160 if (uw_frame_state_for (context, &fs) != _URC_NO_REASON)
2161 abort ();
2162
2163 uw_update_context (context, &fs);
2164 }
2165
2166 /* Install (i.e. longjmp to) the contents of TARGET. */
2167
2168 static void __attribute__((noreturn))
2169 uw_install_context (struct _Unwind_Context *current __attribute__((unused)),
2170 struct _Unwind_Context *target)
2171 {
2172 unsigned long ireg_buf[4], ireg_nat = 0, ireg_pr = 0;
2173 long i;
2174
2175 /* Copy integer register data from the target context to a
2176 temporary buffer. Do this so that we can frob AR.UNAT
2177 to get the NaT bits for these registers set properly. */
2178 for (i = 4; i <= 7; ++i)
2179 {
2180 char nat;
2181 void *t = target->ireg[i - 2].loc;
2182 if (t)
2183 {
2184 unw_access_gr (target, i, &ireg_buf[i - 4], &nat, 0);
2185 ireg_nat |= (long)nat << (((size_t)&ireg_buf[i - 4] >> 3) & 0x3f);
2186 /* Set p6 - p9. */
2187 ireg_pr |= 4L << i;
2188 }
2189 }
2190
2191 /* The value in uc_bsp that we've computed is that for the
2192 target function. The value that we install below will be
2193 adjusted by the BR.RET instruction based on the contents
2194 of AR.PFS. So we must unadjust that here. */
2195 target->bsp = (unsigned long)
2196 ia64_rse_skip_regs ((unsigned long *)target->bsp,
2197 (*target->pfs_loc >> 7) & 0x7f);
2198
2199 if (target->bsp < target->regstk_top)
2200 target->rnat = *ia64_rse_rnat_addr ((unsigned long *) target->bsp);
2201
2202 /* Provide assembly with the offsets into the _Unwind_Context. */
2203 asm volatile ("uc_rnat = %0"
2204 : : "i"(offsetof (struct _Unwind_Context, rnat)));
2205 asm volatile ("uc_bsp = %0"
2206 : : "i"(offsetof (struct _Unwind_Context, bsp)));
2207 asm volatile ("uc_psp = %0"
2208 : : "i"(offsetof (struct _Unwind_Context, psp)));
2209 asm volatile ("uc_rp = %0"
2210 : : "i"(offsetof (struct _Unwind_Context, rp)));
2211 asm volatile ("uc_pr = %0"
2212 : : "i"(offsetof (struct _Unwind_Context, pr)));
2213 asm volatile ("uc_gp = %0"
2214 : : "i"(offsetof (struct _Unwind_Context, gp)));
2215 asm volatile ("uc_pfs_loc = %0"
2216 : : "i"(offsetof (struct _Unwind_Context, pfs_loc)));
2217 asm volatile ("uc_unat_loc = %0"
2218 : : "i"(offsetof (struct _Unwind_Context, unat_loc)));
2219 asm volatile ("uc_lc_loc = %0"
2220 : : "i"(offsetof (struct _Unwind_Context, lc_loc)));
2221 asm volatile ("uc_fpsr_loc = %0"
2222 : : "i"(offsetof (struct _Unwind_Context, fpsr_loc)));
2223 asm volatile ("uc_eh_data = %0"
2224 : : "i"(offsetof (struct _Unwind_Context, eh_data)));
2225 asm volatile ("uc_br_loc = %0"
2226 : : "i"(offsetof (struct _Unwind_Context, br_loc)));
2227 asm volatile ("uc_fr_loc = %0"
2228 : : "i"(offsetof (struct _Unwind_Context, fr_loc)));
2229
2230 asm volatile (
2231 /* Load up call-saved non-window integer registers from ireg_buf. */
2232 "add r20 = 8, %1 \n\t"
2233 "mov ar.unat = %2 \n\t"
2234 "mov pr = %3, 0x3c0 \n\t"
2235 ";; \n\t"
2236 "(p6) ld8.fill r4 = [%1] \n\t"
2237 "(p7) ld8.fill r5 = [r20] \n\t"
2238 "add r21 = uc_br_loc + 16, %0 \n\t"
2239 "adds %1 = 16, %1 \n\t"
2240 "adds r20 = 16, r20 \n\t"
2241 ";; \n\t"
2242 "(p8) ld8.fill r6 = [%1] \n\t"
2243 "(p9) ld8.fill r7 = [r20] \n\t"
2244 "add r20 = uc_br_loc + 8, %0 \n\t"
2245 ";; \n\t"
2246 /* Load up call-saved branch registers. */
2247 "ld8 r22 = [r20], 16 \n\t"
2248 "ld8 r23 = [r21], 16 \n\t"
2249 ";; \n\t"
2250 "ld8 r24 = [r20], 16 \n\t"
2251 "ld8 r25 = [r21], uc_fr_loc - (uc_br_loc + 32)\n\t"
2252 ";; \n\t"
2253 "ld8 r26 = [r20], uc_fr_loc + 8 - (uc_br_loc + 40)\n\t"
2254 "ld8 r27 = [r21], 24 \n\t"
2255 "cmp.ne p6, p0 = r0, r22 \n\t"
2256 ";; \n\t"
2257 "ld8 r28 = [r20], 8 \n\t"
2258 "(p6) ld8 r22 = [r22] \n\t"
2259 "cmp.ne p7, p0 = r0, r23 \n\t"
2260 ";; \n\t"
2261 "(p7) ld8 r23 = [r23] \n\t"
2262 "cmp.ne p8, p0 = r0, r24 \n\t"
2263 ";; \n\t"
2264 "(p8) ld8 r24 = [r24] \n\t"
2265 "(p6) mov b1 = r22 \n\t"
2266 "cmp.ne p9, p0 = r0, r25 \n\t"
2267 ";; \n\t"
2268 "(p9) ld8 r25 = [r25] \n\t"
2269 "(p7) mov b2 = r23 \n\t"
2270 "cmp.ne p6, p0 = r0, r26 \n\t"
2271 ";; \n\t"
2272 "(p6) ld8 r26 = [r26] \n\t"
2273 "(p8) mov b3 = r24 \n\t"
2274 "cmp.ne p7, p0 = r0, r27 \n\t"
2275 ";; \n\t"
2276 /* Load up call-saved fp registers. */
2277 "(p7) ldf.fill f2 = [r27] \n\t"
2278 "(p9) mov b4 = r25 \n\t"
2279 "cmp.ne p8, p0 = r0, r28 \n\t"
2280 ";; \n\t"
2281 "(p8) ldf.fill f3 = [r28] \n\t"
2282 "(p6) mov b5 = r26 \n\t"
2283 ";; \n\t"
2284 "ld8 r29 = [r20], 16*8 - 4*8 \n\t"
2285 "ld8 r30 = [r21], 17*8 - 5*8 \n\t"
2286 ";; \n\t"
2287 "ld8 r22 = [r20], 16 \n\t"
2288 "ld8 r23 = [r21], 16 \n\t"
2289 ";; \n\t"
2290 "ld8 r24 = [r20], 16 \n\t"
2291 "ld8 r25 = [r21] \n\t"
2292 "cmp.ne p6, p0 = r0, r29 \n\t"
2293 ";; \n\t"
2294 "ld8 r26 = [r20], 8 \n\t"
2295 "(p6) ldf.fill f4 = [r29] \n\t"
2296 "cmp.ne p7, p0 = r0, r30 \n\t"
2297 ";; \n\t"
2298 "ld8 r27 = [r20], 8 \n\t"
2299 "(p7) ldf.fill f5 = [r30] \n\t"
2300 "cmp.ne p6, p0 = r0, r22 \n\t"
2301 ";; \n\t"
2302 "ld8 r28 = [r20], 8 \n\t"
2303 "(p6) ldf.fill f16 = [r22] \n\t"
2304 "cmp.ne p7, p0 = r0, r23 \n\t"
2305 ";; \n\t"
2306 "ld8 r29 = [r20], 8 \n\t"
2307 "(p7) ldf.fill f17 = [r23] \n\t"
2308 "cmp.ne p6, p0 = r0, r24 \n\t"
2309 ";; \n\t"
2310 "ld8 r22 = [r20], 8 \n\t"
2311 "(p6) ldf.fill f18 = [r24] \n\t"
2312 "cmp.ne p7, p0 = r0, r25 \n\t"
2313 ";; \n\t"
2314 "ld8 r23 = [r20], 8 \n\t"
2315 "(p7) ldf.fill f19 = [r25] \n\t"
2316 "cmp.ne p6, p0 = r0, r26 \n\t"
2317 ";; \n\t"
2318 "ld8 r24 = [r20], 8 \n\t"
2319 "(p6) ldf.fill f20 = [r26] \n\t"
2320 "cmp.ne p7, p0 = r0, r27 \n\t"
2321 ";; \n\t"
2322 "ld8 r25 = [r20], 8 \n\t"
2323 "(p7) ldf.fill f21 = [r27] \n\t"
2324 "cmp.ne p6, p0 = r0, r28 \n\t"
2325 ";; \n\t"
2326 "ld8 r26 = [r20], 8 \n\t"
2327 "(p6) ldf.fill f22 = [r28] \n\t"
2328 "cmp.ne p7, p0 = r0, r29 \n\t"
2329 ";; \n\t"
2330 "ld8 r27 = [r20], 8 \n\t"
2331 ";; \n\t"
2332 "ld8 r28 = [r20], 8 \n\t"
2333 "(p7) ldf.fill f23 = [r29] \n\t"
2334 "cmp.ne p6, p0 = r0, r22 \n\t"
2335 ";; \n\t"
2336 "ld8 r29 = [r20], 8 \n\t"
2337 "(p6) ldf.fill f24 = [r22] \n\t"
2338 "cmp.ne p7, p0 = r0, r23 \n\t"
2339 ";; \n\t"
2340 "(p7) ldf.fill f25 = [r23] \n\t"
2341 "cmp.ne p6, p0 = r0, r24 \n\t"
2342 "cmp.ne p7, p0 = r0, r25 \n\t"
2343 ";; \n\t"
2344 "(p6) ldf.fill f26 = [r24] \n\t"
2345 "(p7) ldf.fill f27 = [r25] \n\t"
2346 "cmp.ne p6, p0 = r0, r26 \n\t"
2347 ";; \n\t"
2348 "(p6) ldf.fill f28 = [r26] \n\t"
2349 "cmp.ne p7, p0 = r0, r27 \n\t"
2350 "cmp.ne p6, p0 = r0, r28 \n\t"
2351 ";; \n\t"
2352 "(p7) ldf.fill f29 = [r27] \n\t"
2353 "(p6) ldf.fill f30 = [r28] \n\t"
2354 "cmp.ne p7, p0 = r0, r29 \n\t"
2355 ";; \n\t"
2356 "(p7) ldf.fill f31 = [r29] \n\t"
2357 "add r20 = uc_rnat, %0 \n\t"
2358 "add r21 = uc_bsp, %0 \n\t"
2359 ";; \n\t"
2360 /* Load the balance of the thread state from the context. */
2361 "ld8 r22 = [r20], uc_psp - uc_rnat \n\t"
2362 "ld8 r23 = [r21], uc_gp - uc_bsp \n\t"
2363 ";; \n\t"
2364 "ld8 r24 = [r20], uc_pfs_loc - uc_psp \n\t"
2365 "ld8 r1 = [r21], uc_rp - uc_gp \n\t"
2366 ";; \n\t"
2367 "ld8 r25 = [r20], uc_unat_loc - uc_pfs_loc\n\t"
2368 "ld8 r26 = [r21], uc_pr - uc_rp \n\t"
2369 ";; \n\t"
2370 "ld8 r27 = [r20], uc_lc_loc - uc_unat_loc\n\t"
2371 "ld8 r28 = [r21], uc_fpsr_loc - uc_pr \n\t"
2372 ";; \n\t"
2373 "ld8 r29 = [r20], uc_eh_data - uc_lc_loc\n\t"
2374 "ld8 r30 = [r21], uc_eh_data + 8 - uc_fpsr_loc\n\t"
2375 ";; \n\t"
2376 /* Load data for the exception handler. */
2377 "ld8 r15 = [r20], 16 \n\t"
2378 "ld8 r16 = [r21], 16 \n\t"
2379 ";; \n\t"
2380 "ld8 r17 = [r20] \n\t"
2381 "ld8 r18 = [r21] \n\t"
2382 ";; \n\t"
2383 /* Install the balance of the thread state loaded above. */
2384 "cmp.ne p6, p0 = r0, r25 \n\t"
2385 "cmp.ne p7, p0 = r0, r27 \n\t"
2386 ";; \n\t"
2387 "(p6) ld8 r25 = [r25] \n\t"
2388 "(p7) ld8 r27 = [r27] \n\t"
2389 ";; \n\t"
2390 "(p7) mov.m ar.unat = r27 \n\t"
2391 "(p6) mov.i ar.pfs = r25 \n\t"
2392 "cmp.ne p9, p0 = r0, r29 \n\t"
2393 ";; \n\t"
2394 "(p9) ld8 r29 = [r29] \n\t"
2395 "cmp.ne p6, p0 = r0, r30 \n\t"
2396 ";; \n\t"
2397 "(p6) ld8 r30 = [r30] \n\t"
2398 /* Don't clobber p6-p9, which are in use at present. */
2399 "mov pr = r28, ~0x3c0 \n\t"
2400 "(p9) mov.i ar.lc = r29 \n\t"
2401 ";; \n\t"
2402 "mov.m r25 = ar.rsc \n\t"
2403 "(p6) mov.m ar.fpsr = r30 \n\t"
2404 ";; \n\t"
2405 "and r29 = 0x1c, r25 \n\t"
2406 "mov b0 = r26 \n\t"
2407 ";; \n\t"
2408 "mov.m ar.rsc = r29 \n\t"
2409 ";; \n\t"
2410 /* This must be done before setting AR.BSPSTORE, otherwise
2411 AR.BSP will be initialized with a random displacement
2412 below the value we want, based on the current number of
2413 dirty stacked registers. */
2414 "loadrs \n\t"
2415 "invala \n\t"
2416 ";; \n\t"
2417 "mov.m ar.bspstore = r23 \n\t"
2418 ";; \n\t"
2419 "mov.m ar.rnat = r22 \n\t"
2420 ";; \n\t"
2421 "mov.m ar.rsc = r25 \n\t"
2422 "mov sp = r24 \n\t"
2423 "br.ret.sptk.few b0"
2424 : : "r"(target), "r"(ireg_buf), "r"(ireg_nat), "r"(ireg_pr)
2425 : "r15", "r16", "r17", "r18", "r20", "r21", "r22",
2426 "r23", "r24", "r25", "r26", "r27", "r28", "r29",
2427 "r30", "r31");
2428 /* NOTREACHED */
2429 while (1);
2430 }
2431
2432 static inline _Unwind_Ptr
2433 uw_identify_context (struct _Unwind_Context *context)
2434 {
2435 return _Unwind_GetIP (context);
2436 }
2437
2438 #include "unwind.inc"
2439
2440 #if defined (USE_GAS_SYMVER) && defined (SHARED) && defined (USE_LIBUNWIND_EXCEPTIONS)
2441 alias (_Unwind_Backtrace);
2442 alias (_Unwind_DeleteException);
2443 alias (_Unwind_FindEnclosingFunction);
2444 alias (_Unwind_ForcedUnwind);
2445 alias (_Unwind_GetBSP);
2446 alias (_Unwind_GetCFA);
2447 alias (_Unwind_GetGR);
2448 alias (_Unwind_GetIP);
2449 alias (_Unwind_GetLanguageSpecificData);
2450 alias (_Unwind_GetRegionStart);
2451 alias (_Unwind_RaiseException);
2452 alias (_Unwind_Resume);
2453 alias (_Unwind_Resume_or_Rethrow);
2454 alias (_Unwind_SetGR);
2455 alias (_Unwind_SetIP);
2456 #endif
2457
2458 #endif