Merge git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
[wrt350n-kernel.git] / arch / ia64 / kernel / unwind.c
blob248a4c39f622394d27c3a011b45870a3bea2e483
1 /*
2 * Copyright (C) 1999-2004 Hewlett-Packard Co
3 * David Mosberger-Tang <davidm@hpl.hp.com>
4 * Copyright (C) 2003 Fenghua Yu <fenghua.yu@intel.com>
5 * - Change pt_regs_off() to make it less dependent on pt_regs structure.
6 */
7 /*
8 * This file implements call frame unwind support for the Linux
9 * kernel. Parsing and processing the unwind information is
10 * time-consuming, so this implementation translates the unwind
11 * descriptors into unwind scripts. These scripts are very simple
12 * (basically a sequence of assignments) and efficient to execute.
13 * They are cached for later re-use. Each script is specific for a
14 * given instruction pointer address and the set of predicate values
15 * that the script depends on (most unwind descriptors are
16 * unconditional and scripts often do not depend on predicates at
17 * all). This code is based on the unwind conventions described in
18 * the "IA-64 Software Conventions and Runtime Architecture" manual.
20 * SMP conventions:
21 * o updates to the global unwind data (in structure "unw") are serialized
22 * by the unw.lock spinlock
23 * o each unwind script has its own read-write lock; a thread must acquire
24 * a read lock before executing a script and must acquire a write lock
25 * before modifying a script
26 * o if both the unw.lock spinlock and a script's read-write lock must be
27 * acquired, then the read-write lock must be acquired first.
29 #include <linux/module.h>
30 #include <linux/bootmem.h>
31 #include <linux/elf.h>
32 #include <linux/kernel.h>
33 #include <linux/sched.h>
34 #include <linux/slab.h>
36 #include <asm/unwind.h>
38 #include <asm/delay.h>
39 #include <asm/page.h>
40 #include <asm/ptrace.h>
41 #include <asm/ptrace_offsets.h>
42 #include <asm/rse.h>
43 #include <asm/sections.h>
44 #include <asm/system.h>
45 #include <asm/uaccess.h>
47 #include "entry.h"
48 #include "unwind_i.h"
50 #define UNW_LOG_CACHE_SIZE 7 /* each unw_script is ~256 bytes in size */
51 #define UNW_CACHE_SIZE (1 << UNW_LOG_CACHE_SIZE)
53 #define UNW_LOG_HASH_SIZE (UNW_LOG_CACHE_SIZE + 1)
54 #define UNW_HASH_SIZE (1 << UNW_LOG_HASH_SIZE)
56 #define UNW_STATS 0 /* WARNING: this disabled interrupts for long time-spans!! */
58 #ifdef UNW_DEBUG
59 static unsigned int unw_debug_level = UNW_DEBUG;
60 # define UNW_DEBUG_ON(n) unw_debug_level >= n
61 /* Do not code a printk level, not all debug lines end in newline */
62 # define UNW_DPRINT(n, ...) if (UNW_DEBUG_ON(n)) printk(__VA_ARGS__)
63 # undef inline
64 # define inline
65 #else /* !UNW_DEBUG */
66 # define UNW_DEBUG_ON(n) 0
67 # define UNW_DPRINT(n, ...)
68 #endif /* UNW_DEBUG */
70 #if UNW_STATS
71 # define STAT(x...) x
72 #else
73 # define STAT(x...)
74 #endif
76 #define alloc_reg_state() kmalloc(sizeof(struct unw_reg_state), GFP_ATOMIC)
77 #define free_reg_state(usr) kfree(usr)
78 #define alloc_labeled_state() kmalloc(sizeof(struct unw_labeled_state), GFP_ATOMIC)
79 #define free_labeled_state(usr) kfree(usr)
81 typedef unsigned long unw_word;
82 typedef unsigned char unw_hash_index_t;
84 static struct {
85 spinlock_t lock; /* spinlock for unwind data */
87 /* list of unwind tables (one per load-module) */
88 struct unw_table *tables;
90 unsigned long r0; /* constant 0 for r0 */
92 /* table of registers that prologues can save (and order in which they're saved): */
93 const unsigned char save_order[8];
95 /* maps a preserved register index (preg_index) to corresponding switch_stack offset: */
96 unsigned short sw_off[sizeof(struct unw_frame_info) / 8];
98 unsigned short lru_head; /* index of lead-recently used script */
99 unsigned short lru_tail; /* index of most-recently used script */
101 /* index into unw_frame_info for preserved register i */
102 unsigned short preg_index[UNW_NUM_REGS];
104 short pt_regs_offsets[32];
106 /* unwind table for the kernel: */
107 struct unw_table kernel_table;
109 /* unwind table describing the gate page (kernel code that is mapped into user space): */
110 size_t gate_table_size;
111 unsigned long *gate_table;
113 /* hash table that maps instruction pointer to script index: */
114 unsigned short hash[UNW_HASH_SIZE];
116 /* script cache: */
117 struct unw_script cache[UNW_CACHE_SIZE];
119 # ifdef UNW_DEBUG
120 const char *preg_name[UNW_NUM_REGS];
121 # endif
122 # if UNW_STATS
123 struct {
124 struct {
125 int lookups;
126 int hinted_hits;
127 int normal_hits;
128 int collision_chain_traversals;
129 } cache;
130 struct {
131 unsigned long build_time;
132 unsigned long run_time;
133 unsigned long parse_time;
134 int builds;
135 int news;
136 int collisions;
137 int runs;
138 } script;
139 struct {
140 unsigned long init_time;
141 unsigned long unwind_time;
142 int inits;
143 int unwinds;
144 } api;
145 } stat;
146 # endif
147 } unw = {
148 .tables = &unw.kernel_table,
149 .lock = __SPIN_LOCK_UNLOCKED(unw.lock),
150 .save_order = {
151 UNW_REG_RP, UNW_REG_PFS, UNW_REG_PSP, UNW_REG_PR,
152 UNW_REG_UNAT, UNW_REG_LC, UNW_REG_FPSR, UNW_REG_PRI_UNAT_GR
154 .preg_index = {
155 offsetof(struct unw_frame_info, pri_unat_loc)/8, /* PRI_UNAT_GR */
156 offsetof(struct unw_frame_info, pri_unat_loc)/8, /* PRI_UNAT_MEM */
157 offsetof(struct unw_frame_info, bsp_loc)/8,
158 offsetof(struct unw_frame_info, bspstore_loc)/8,
159 offsetof(struct unw_frame_info, pfs_loc)/8,
160 offsetof(struct unw_frame_info, rnat_loc)/8,
161 offsetof(struct unw_frame_info, psp)/8,
162 offsetof(struct unw_frame_info, rp_loc)/8,
163 offsetof(struct unw_frame_info, r4)/8,
164 offsetof(struct unw_frame_info, r5)/8,
165 offsetof(struct unw_frame_info, r6)/8,
166 offsetof(struct unw_frame_info, r7)/8,
167 offsetof(struct unw_frame_info, unat_loc)/8,
168 offsetof(struct unw_frame_info, pr_loc)/8,
169 offsetof(struct unw_frame_info, lc_loc)/8,
170 offsetof(struct unw_frame_info, fpsr_loc)/8,
171 offsetof(struct unw_frame_info, b1_loc)/8,
172 offsetof(struct unw_frame_info, b2_loc)/8,
173 offsetof(struct unw_frame_info, b3_loc)/8,
174 offsetof(struct unw_frame_info, b4_loc)/8,
175 offsetof(struct unw_frame_info, b5_loc)/8,
176 offsetof(struct unw_frame_info, f2_loc)/8,
177 offsetof(struct unw_frame_info, f3_loc)/8,
178 offsetof(struct unw_frame_info, f4_loc)/8,
179 offsetof(struct unw_frame_info, f5_loc)/8,
180 offsetof(struct unw_frame_info, fr_loc[16 - 16])/8,
181 offsetof(struct unw_frame_info, fr_loc[17 - 16])/8,
182 offsetof(struct unw_frame_info, fr_loc[18 - 16])/8,
183 offsetof(struct unw_frame_info, fr_loc[19 - 16])/8,
184 offsetof(struct unw_frame_info, fr_loc[20 - 16])/8,
185 offsetof(struct unw_frame_info, fr_loc[21 - 16])/8,
186 offsetof(struct unw_frame_info, fr_loc[22 - 16])/8,
187 offsetof(struct unw_frame_info, fr_loc[23 - 16])/8,
188 offsetof(struct unw_frame_info, fr_loc[24 - 16])/8,
189 offsetof(struct unw_frame_info, fr_loc[25 - 16])/8,
190 offsetof(struct unw_frame_info, fr_loc[26 - 16])/8,
191 offsetof(struct unw_frame_info, fr_loc[27 - 16])/8,
192 offsetof(struct unw_frame_info, fr_loc[28 - 16])/8,
193 offsetof(struct unw_frame_info, fr_loc[29 - 16])/8,
194 offsetof(struct unw_frame_info, fr_loc[30 - 16])/8,
195 offsetof(struct unw_frame_info, fr_loc[31 - 16])/8,
197 .pt_regs_offsets = {
198 [0] = -1,
199 offsetof(struct pt_regs, r1),
200 offsetof(struct pt_regs, r2),
201 offsetof(struct pt_regs, r3),
202 [4] = -1, [5] = -1, [6] = -1, [7] = -1,
203 offsetof(struct pt_regs, r8),
204 offsetof(struct pt_regs, r9),
205 offsetof(struct pt_regs, r10),
206 offsetof(struct pt_regs, r11),
207 offsetof(struct pt_regs, r12),
208 offsetof(struct pt_regs, r13),
209 offsetof(struct pt_regs, r14),
210 offsetof(struct pt_regs, r15),
211 offsetof(struct pt_regs, r16),
212 offsetof(struct pt_regs, r17),
213 offsetof(struct pt_regs, r18),
214 offsetof(struct pt_regs, r19),
215 offsetof(struct pt_regs, r20),
216 offsetof(struct pt_regs, r21),
217 offsetof(struct pt_regs, r22),
218 offsetof(struct pt_regs, r23),
219 offsetof(struct pt_regs, r24),
220 offsetof(struct pt_regs, r25),
221 offsetof(struct pt_regs, r26),
222 offsetof(struct pt_regs, r27),
223 offsetof(struct pt_regs, r28),
224 offsetof(struct pt_regs, r29),
225 offsetof(struct pt_regs, r30),
226 offsetof(struct pt_regs, r31),
228 .hash = { [0 ... UNW_HASH_SIZE - 1] = -1 },
229 #ifdef UNW_DEBUG
230 .preg_name = {
231 "pri_unat_gr", "pri_unat_mem", "bsp", "bspstore", "ar.pfs", "ar.rnat", "psp", "rp",
232 "r4", "r5", "r6", "r7",
233 "ar.unat", "pr", "ar.lc", "ar.fpsr",
234 "b1", "b2", "b3", "b4", "b5",
235 "f2", "f3", "f4", "f5",
236 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
237 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31"
239 #endif
242 static inline int
243 read_only (void *addr)
245 return (unsigned long) ((char *) addr - (char *) &unw.r0) < sizeof(unw.r0);
249 * Returns offset of rREG in struct pt_regs.
251 static inline unsigned long
252 pt_regs_off (unsigned long reg)
254 short off = -1;
256 if (reg < ARRAY_SIZE(unw.pt_regs_offsets))
257 off = unw.pt_regs_offsets[reg];
259 if (off < 0) {
260 <<<<<<< HEAD:arch/ia64/kernel/unwind.c
261 UNW_DPRINT(0, "unwind.%s: bad scratch reg r%lu\n", __FUNCTION__, reg);
262 =======
263 UNW_DPRINT(0, "unwind.%s: bad scratch reg r%lu\n", __func__, reg);
264 >>>>>>> 264e3e889d86e552b4191d69bb60f4f3b383135a:arch/ia64/kernel/unwind.c
265 off = 0;
267 return (unsigned long) off;
270 static inline struct pt_regs *
271 get_scratch_regs (struct unw_frame_info *info)
273 if (!info->pt) {
274 /* This should not happen with valid unwind info. */
275 <<<<<<< HEAD:arch/ia64/kernel/unwind.c
276 UNW_DPRINT(0, "unwind.%s: bad unwind info: resetting info->pt\n", __FUNCTION__);
277 =======
278 UNW_DPRINT(0, "unwind.%s: bad unwind info: resetting info->pt\n", __func__);
279 >>>>>>> 264e3e889d86e552b4191d69bb60f4f3b383135a:arch/ia64/kernel/unwind.c
280 if (info->flags & UNW_FLAG_INTERRUPT_FRAME)
281 info->pt = (unsigned long) ((struct pt_regs *) info->psp - 1);
282 else
283 info->pt = info->sp - 16;
285 <<<<<<< HEAD:arch/ia64/kernel/unwind.c
286 UNW_DPRINT(3, "unwind.%s: sp 0x%lx pt 0x%lx\n", __FUNCTION__, info->sp, info->pt);
287 =======
288 UNW_DPRINT(3, "unwind.%s: sp 0x%lx pt 0x%lx\n", __func__, info->sp, info->pt);
289 >>>>>>> 264e3e889d86e552b4191d69bb60f4f3b383135a:arch/ia64/kernel/unwind.c
290 return (struct pt_regs *) info->pt;
293 /* Unwind accessors. */
296 unw_access_gr (struct unw_frame_info *info, int regnum, unsigned long *val, char *nat, int write)
298 unsigned long *addr, *nat_addr, nat_mask = 0, dummy_nat;
299 struct unw_ireg *ireg;
300 struct pt_regs *pt;
302 if ((unsigned) regnum - 1 >= 127) {
303 if (regnum == 0 && !write) {
304 *val = 0; /* read r0 always returns 0 */
305 *nat = 0;
306 return 0;
308 UNW_DPRINT(0, "unwind.%s: trying to access non-existent r%u\n",
309 <<<<<<< HEAD:arch/ia64/kernel/unwind.c
310 __FUNCTION__, regnum);
311 =======
312 __func__, regnum);
313 >>>>>>> 264e3e889d86e552b4191d69bb60f4f3b383135a:arch/ia64/kernel/unwind.c
314 return -1;
317 if (regnum < 32) {
318 if (regnum >= 4 && regnum <= 7) {
319 /* access a preserved register */
320 ireg = &info->r4 + (regnum - 4);
321 addr = ireg->loc;
322 if (addr) {
323 nat_addr = addr + ireg->nat.off;
324 switch (ireg->nat.type) {
325 case UNW_NAT_VAL:
326 /* simulate getf.sig/setf.sig */
327 if (write) {
328 if (*nat) {
329 /* write NaTVal and be done with it */
330 addr[0] = 0;
331 addr[1] = 0x1fffe;
332 return 0;
334 addr[1] = 0x1003e;
335 } else {
336 if (addr[0] == 0 && addr[1] == 0x1ffe) {
337 /* return NaT and be done with it */
338 *val = 0;
339 *nat = 1;
340 return 0;
343 /* fall through */
344 case UNW_NAT_NONE:
345 dummy_nat = 0;
346 nat_addr = &dummy_nat;
347 break;
349 case UNW_NAT_MEMSTK:
350 nat_mask = (1UL << ((long) addr & 0x1f8)/8);
351 break;
353 case UNW_NAT_REGSTK:
354 nat_addr = ia64_rse_rnat_addr(addr);
355 if ((unsigned long) addr < info->regstk.limit
356 || (unsigned long) addr >= info->regstk.top)
358 UNW_DPRINT(0, "unwind.%s: %p outside of regstk "
359 "[0x%lx-0x%lx)\n",
360 <<<<<<< HEAD:arch/ia64/kernel/unwind.c
361 __FUNCTION__, (void *) addr,
362 =======
363 __func__, (void *) addr,
364 >>>>>>> 264e3e889d86e552b4191d69bb60f4f3b383135a:arch/ia64/kernel/unwind.c
365 info->regstk.limit,
366 info->regstk.top);
367 return -1;
369 if ((unsigned long) nat_addr >= info->regstk.top)
370 nat_addr = &info->sw->ar_rnat;
371 nat_mask = (1UL << ia64_rse_slot_num(addr));
372 break;
374 } else {
375 addr = &info->sw->r4 + (regnum - 4);
376 nat_addr = &info->sw->ar_unat;
377 nat_mask = (1UL << ((long) addr & 0x1f8)/8);
379 } else {
380 /* access a scratch register */
381 pt = get_scratch_regs(info);
382 addr = (unsigned long *) ((unsigned long)pt + pt_regs_off(regnum));
383 if (info->pri_unat_loc)
384 nat_addr = info->pri_unat_loc;
385 else
386 nat_addr = &info->sw->caller_unat;
387 nat_mask = (1UL << ((long) addr & 0x1f8)/8);
389 } else {
390 /* access a stacked register */
391 addr = ia64_rse_skip_regs((unsigned long *) info->bsp, regnum - 32);
392 nat_addr = ia64_rse_rnat_addr(addr);
393 if ((unsigned long) addr < info->regstk.limit
394 || (unsigned long) addr >= info->regstk.top)
396 UNW_DPRINT(0, "unwind.%s: ignoring attempt to access register outside "
397 <<<<<<< HEAD:arch/ia64/kernel/unwind.c
398 "of rbs\n", __FUNCTION__);
399 =======
400 "of rbs\n", __func__);
401 >>>>>>> 264e3e889d86e552b4191d69bb60f4f3b383135a:arch/ia64/kernel/unwind.c
402 return -1;
404 if ((unsigned long) nat_addr >= info->regstk.top)
405 nat_addr = &info->sw->ar_rnat;
406 nat_mask = (1UL << ia64_rse_slot_num(addr));
409 if (write) {
410 if (read_only(addr)) {
411 UNW_DPRINT(0, "unwind.%s: ignoring attempt to write read-only location\n",
412 <<<<<<< HEAD:arch/ia64/kernel/unwind.c
413 __FUNCTION__);
414 =======
415 __func__);
416 >>>>>>> 264e3e889d86e552b4191d69bb60f4f3b383135a:arch/ia64/kernel/unwind.c
417 } else {
418 *addr = *val;
419 if (*nat)
420 *nat_addr |= nat_mask;
421 else
422 *nat_addr &= ~nat_mask;
424 } else {
425 if ((*nat_addr & nat_mask) == 0) {
426 *val = *addr;
427 *nat = 0;
428 } else {
429 *val = 0; /* if register is a NaT, *addr may contain kernel data! */
430 *nat = 1;
433 return 0;
435 EXPORT_SYMBOL(unw_access_gr);
438 unw_access_br (struct unw_frame_info *info, int regnum, unsigned long *val, int write)
440 unsigned long *addr;
441 struct pt_regs *pt;
443 switch (regnum) {
444 /* scratch: */
445 case 0: pt = get_scratch_regs(info); addr = &pt->b0; break;
446 case 6: pt = get_scratch_regs(info); addr = &pt->b6; break;
447 case 7: pt = get_scratch_regs(info); addr = &pt->b7; break;
449 /* preserved: */
450 case 1: case 2: case 3: case 4: case 5:
451 addr = *(&info->b1_loc + (regnum - 1));
452 if (!addr)
453 addr = &info->sw->b1 + (regnum - 1);
454 break;
456 default:
457 UNW_DPRINT(0, "unwind.%s: trying to access non-existent b%u\n",
458 <<<<<<< HEAD:arch/ia64/kernel/unwind.c
459 __FUNCTION__, regnum);
460 =======
461 __func__, regnum);
462 >>>>>>> 264e3e889d86e552b4191d69bb60f4f3b383135a:arch/ia64/kernel/unwind.c
463 return -1;
465 if (write)
466 if (read_only(addr)) {
467 UNW_DPRINT(0, "unwind.%s: ignoring attempt to write read-only location\n",
468 <<<<<<< HEAD:arch/ia64/kernel/unwind.c
469 __FUNCTION__);
470 =======
471 __func__);
472 >>>>>>> 264e3e889d86e552b4191d69bb60f4f3b383135a:arch/ia64/kernel/unwind.c
473 } else
474 *addr = *val;
475 else
476 *val = *addr;
477 return 0;
479 EXPORT_SYMBOL(unw_access_br);
482 unw_access_fr (struct unw_frame_info *info, int regnum, struct ia64_fpreg *val, int write)
484 struct ia64_fpreg *addr = NULL;
485 struct pt_regs *pt;
487 if ((unsigned) (regnum - 2) >= 126) {
488 UNW_DPRINT(0, "unwind.%s: trying to access non-existent f%u\n",
489 <<<<<<< HEAD:arch/ia64/kernel/unwind.c
490 __FUNCTION__, regnum);
491 =======
492 __func__, regnum);
493 >>>>>>> 264e3e889d86e552b4191d69bb60f4f3b383135a:arch/ia64/kernel/unwind.c
494 return -1;
497 if (regnum <= 5) {
498 addr = *(&info->f2_loc + (regnum - 2));
499 if (!addr)
500 addr = &info->sw->f2 + (regnum - 2);
501 } else if (regnum <= 15) {
502 if (regnum <= 11) {
503 pt = get_scratch_regs(info);
504 addr = &pt->f6 + (regnum - 6);
506 else
507 addr = &info->sw->f12 + (regnum - 12);
508 } else if (regnum <= 31) {
509 addr = info->fr_loc[regnum - 16];
510 if (!addr)
511 addr = &info->sw->f16 + (regnum - 16);
512 } else {
513 struct task_struct *t = info->task;
515 if (write)
516 ia64_sync_fph(t);
517 else
518 ia64_flush_fph(t);
519 addr = t->thread.fph + (regnum - 32);
522 if (write)
523 if (read_only(addr)) {
524 UNW_DPRINT(0, "unwind.%s: ignoring attempt to write read-only location\n",
525 <<<<<<< HEAD:arch/ia64/kernel/unwind.c
526 __FUNCTION__);
527 =======
528 __func__);
529 >>>>>>> 264e3e889d86e552b4191d69bb60f4f3b383135a:arch/ia64/kernel/unwind.c
530 } else
531 *addr = *val;
532 else
533 *val = *addr;
534 return 0;
536 EXPORT_SYMBOL(unw_access_fr);
539 unw_access_ar (struct unw_frame_info *info, int regnum, unsigned long *val, int write)
541 unsigned long *addr;
542 struct pt_regs *pt;
544 switch (regnum) {
545 case UNW_AR_BSP:
546 addr = info->bsp_loc;
547 if (!addr)
548 addr = &info->sw->ar_bspstore;
549 break;
551 case UNW_AR_BSPSTORE:
552 addr = info->bspstore_loc;
553 if (!addr)
554 addr = &info->sw->ar_bspstore;
555 break;
557 case UNW_AR_PFS:
558 addr = info->pfs_loc;
559 if (!addr)
560 addr = &info->sw->ar_pfs;
561 break;
563 case UNW_AR_RNAT:
564 addr = info->rnat_loc;
565 if (!addr)
566 addr = &info->sw->ar_rnat;
567 break;
569 case UNW_AR_UNAT:
570 addr = info->unat_loc;
571 if (!addr)
572 addr = &info->sw->caller_unat;
573 break;
575 case UNW_AR_LC:
576 addr = info->lc_loc;
577 if (!addr)
578 addr = &info->sw->ar_lc;
579 break;
581 case UNW_AR_EC:
582 if (!info->cfm_loc)
583 return -1;
584 if (write)
585 *info->cfm_loc =
586 (*info->cfm_loc & ~(0x3fUL << 52)) | ((*val & 0x3f) << 52);
587 else
588 *val = (*info->cfm_loc >> 52) & 0x3f;
589 return 0;
591 case UNW_AR_FPSR:
592 addr = info->fpsr_loc;
593 if (!addr)
594 addr = &info->sw->ar_fpsr;
595 break;
597 case UNW_AR_RSC:
598 pt = get_scratch_regs(info);
599 addr = &pt->ar_rsc;
600 break;
602 case UNW_AR_CCV:
603 pt = get_scratch_regs(info);
604 addr = &pt->ar_ccv;
605 break;
607 case UNW_AR_CSD:
608 pt = get_scratch_regs(info);
609 addr = &pt->ar_csd;
610 break;
612 case UNW_AR_SSD:
613 pt = get_scratch_regs(info);
614 addr = &pt->ar_ssd;
615 break;
617 default:
618 UNW_DPRINT(0, "unwind.%s: trying to access non-existent ar%u\n",
619 <<<<<<< HEAD:arch/ia64/kernel/unwind.c
620 __FUNCTION__, regnum);
621 =======
622 __func__, regnum);
623 >>>>>>> 264e3e889d86e552b4191d69bb60f4f3b383135a:arch/ia64/kernel/unwind.c
624 return -1;
627 if (write) {
628 if (read_only(addr)) {
629 UNW_DPRINT(0, "unwind.%s: ignoring attempt to write read-only location\n",
630 <<<<<<< HEAD:arch/ia64/kernel/unwind.c
631 __FUNCTION__);
632 =======
633 __func__);
634 >>>>>>> 264e3e889d86e552b4191d69bb60f4f3b383135a:arch/ia64/kernel/unwind.c
635 } else
636 *addr = *val;
637 } else
638 *val = *addr;
639 return 0;
641 EXPORT_SYMBOL(unw_access_ar);
644 unw_access_pr (struct unw_frame_info *info, unsigned long *val, int write)
646 unsigned long *addr;
648 addr = info->pr_loc;
649 if (!addr)
650 addr = &info->sw->pr;
652 if (write) {
653 if (read_only(addr)) {
654 UNW_DPRINT(0, "unwind.%s: ignoring attempt to write read-only location\n",
655 <<<<<<< HEAD:arch/ia64/kernel/unwind.c
656 __FUNCTION__);
657 =======
658 __func__);
659 >>>>>>> 264e3e889d86e552b4191d69bb60f4f3b383135a:arch/ia64/kernel/unwind.c
660 } else
661 *addr = *val;
662 } else
663 *val = *addr;
664 return 0;
666 EXPORT_SYMBOL(unw_access_pr);
669 /* Routines to manipulate the state stack. */
671 static inline void
672 push (struct unw_state_record *sr)
674 struct unw_reg_state *rs;
676 rs = alloc_reg_state();
677 if (!rs) {
678 printk(KERN_ERR "unwind: cannot stack reg state!\n");
679 return;
681 memcpy(rs, &sr->curr, sizeof(*rs));
682 sr->curr.next = rs;
685 static void
686 pop (struct unw_state_record *sr)
688 struct unw_reg_state *rs = sr->curr.next;
690 if (!rs) {
691 printk(KERN_ERR "unwind: stack underflow!\n");
692 return;
694 memcpy(&sr->curr, rs, sizeof(*rs));
695 free_reg_state(rs);
698 /* Make a copy of the state stack. Non-recursive to avoid stack overflows. */
699 static struct unw_reg_state *
700 dup_state_stack (struct unw_reg_state *rs)
702 struct unw_reg_state *copy, *prev = NULL, *first = NULL;
704 while (rs) {
705 copy = alloc_reg_state();
706 if (!copy) {
707 printk(KERN_ERR "unwind.dup_state_stack: out of memory\n");
708 return NULL;
710 memcpy(copy, rs, sizeof(*copy));
711 if (first)
712 prev->next = copy;
713 else
714 first = copy;
715 rs = rs->next;
716 prev = copy;
718 return first;
721 /* Free all stacked register states (but not RS itself). */
722 static void
723 free_state_stack (struct unw_reg_state *rs)
725 struct unw_reg_state *p, *next;
727 for (p = rs->next; p != NULL; p = next) {
728 next = p->next;
729 free_reg_state(p);
731 rs->next = NULL;
734 /* Unwind decoder routines */
736 static enum unw_register_index __attribute_const__
737 decode_abreg (unsigned char abreg, int memory)
739 switch (abreg) {
740 case 0x04 ... 0x07: return UNW_REG_R4 + (abreg - 0x04);
741 case 0x22 ... 0x25: return UNW_REG_F2 + (abreg - 0x22);
742 case 0x30 ... 0x3f: return UNW_REG_F16 + (abreg - 0x30);
743 case 0x41 ... 0x45: return UNW_REG_B1 + (abreg - 0x41);
744 case 0x60: return UNW_REG_PR;
745 case 0x61: return UNW_REG_PSP;
746 case 0x62: return memory ? UNW_REG_PRI_UNAT_MEM : UNW_REG_PRI_UNAT_GR;
747 case 0x63: return UNW_REG_RP;
748 case 0x64: return UNW_REG_BSP;
749 case 0x65: return UNW_REG_BSPSTORE;
750 case 0x66: return UNW_REG_RNAT;
751 case 0x67: return UNW_REG_UNAT;
752 case 0x68: return UNW_REG_FPSR;
753 case 0x69: return UNW_REG_PFS;
754 case 0x6a: return UNW_REG_LC;
755 default:
756 break;
758 <<<<<<< HEAD:arch/ia64/kernel/unwind.c
759 UNW_DPRINT(0, "unwind.%s: bad abreg=0x%x\n", __FUNCTION__, abreg);
760 =======
761 UNW_DPRINT(0, "unwind.%s: bad abreg=0x%x\n", __func__, abreg);
762 >>>>>>> 264e3e889d86e552b4191d69bb60f4f3b383135a:arch/ia64/kernel/unwind.c
763 return UNW_REG_LC;
766 static void
767 set_reg (struct unw_reg_info *reg, enum unw_where where, int when, unsigned long val)
769 reg->val = val;
770 reg->where = where;
771 if (reg->when == UNW_WHEN_NEVER)
772 reg->when = when;
775 static void
776 alloc_spill_area (unsigned long *offp, unsigned long regsize,
777 struct unw_reg_info *lo, struct unw_reg_info *hi)
779 struct unw_reg_info *reg;
781 for (reg = hi; reg >= lo; --reg) {
782 if (reg->where == UNW_WHERE_SPILL_HOME) {
783 reg->where = UNW_WHERE_PSPREL;
784 *offp -= regsize;
785 reg->val = *offp;
790 static inline void
791 spill_next_when (struct unw_reg_info **regp, struct unw_reg_info *lim, unw_word t)
793 struct unw_reg_info *reg;
795 for (reg = *regp; reg <= lim; ++reg) {
796 if (reg->where == UNW_WHERE_SPILL_HOME) {
797 reg->when = t;
798 *regp = reg + 1;
799 return;
802 <<<<<<< HEAD:arch/ia64/kernel/unwind.c
803 UNW_DPRINT(0, "unwind.%s: excess spill!\n", __FUNCTION__);
804 =======
805 UNW_DPRINT(0, "unwind.%s: excess spill!\n", __func__);
806 >>>>>>> 264e3e889d86e552b4191d69bb60f4f3b383135a:arch/ia64/kernel/unwind.c
809 static inline void
810 finish_prologue (struct unw_state_record *sr)
812 struct unw_reg_info *reg;
813 unsigned long off;
814 int i;
817 * First, resolve implicit register save locations (see Section "11.4.2.3 Rules
818 * for Using Unwind Descriptors", rule 3):
820 for (i = 0; i < (int) ARRAY_SIZE(unw.save_order); ++i) {
821 reg = sr->curr.reg + unw.save_order[i];
822 if (reg->where == UNW_WHERE_GR_SAVE) {
823 reg->where = UNW_WHERE_GR;
824 reg->val = sr->gr_save_loc++;
829 * Next, compute when the fp, general, and branch registers get
830 * saved. This must come before alloc_spill_area() because
831 * we need to know which registers are spilled to their home
832 * locations.
834 if (sr->imask) {
835 unsigned char kind, mask = 0, *cp = sr->imask;
836 int t;
837 static const unsigned char limit[3] = {
838 UNW_REG_F31, UNW_REG_R7, UNW_REG_B5
840 struct unw_reg_info *(regs[3]);
842 regs[0] = sr->curr.reg + UNW_REG_F2;
843 regs[1] = sr->curr.reg + UNW_REG_R4;
844 regs[2] = sr->curr.reg + UNW_REG_B1;
846 for (t = 0; t < sr->region_len; ++t) {
847 if ((t & 3) == 0)
848 mask = *cp++;
849 kind = (mask >> 2*(3-(t & 3))) & 3;
850 if (kind > 0)
851 spill_next_when(&regs[kind - 1], sr->curr.reg + limit[kind - 1],
852 sr->region_start + t);
856 * Next, lay out the memory stack spill area:
858 if (sr->any_spills) {
859 off = sr->spill_offset;
860 alloc_spill_area(&off, 16, sr->curr.reg + UNW_REG_F2, sr->curr.reg + UNW_REG_F31);
861 alloc_spill_area(&off, 8, sr->curr.reg + UNW_REG_B1, sr->curr.reg + UNW_REG_B5);
862 alloc_spill_area(&off, 8, sr->curr.reg + UNW_REG_R4, sr->curr.reg + UNW_REG_R7);
867 * Region header descriptors.
870 static void
871 desc_prologue (int body, unw_word rlen, unsigned char mask, unsigned char grsave,
872 struct unw_state_record *sr)
874 int i, region_start;
876 if (!(sr->in_body || sr->first_region))
877 finish_prologue(sr);
878 sr->first_region = 0;
880 /* check if we're done: */
881 if (sr->when_target < sr->region_start + sr->region_len) {
882 sr->done = 1;
883 return;
886 region_start = sr->region_start + sr->region_len;
888 for (i = 0; i < sr->epilogue_count; ++i)
889 pop(sr);
890 sr->epilogue_count = 0;
891 sr->epilogue_start = UNW_WHEN_NEVER;
893 sr->region_start = region_start;
894 sr->region_len = rlen;
895 sr->in_body = body;
897 if (!body) {
898 push(sr);
900 for (i = 0; i < 4; ++i) {
901 if (mask & 0x8)
902 set_reg(sr->curr.reg + unw.save_order[i], UNW_WHERE_GR,
903 sr->region_start + sr->region_len - 1, grsave++);
904 mask <<= 1;
906 sr->gr_save_loc = grsave;
907 sr->any_spills = 0;
908 sr->imask = NULL;
909 sr->spill_offset = 0x10; /* default to psp+16 */
914 * Prologue descriptors.
917 static inline void
918 desc_abi (unsigned char abi, unsigned char context, struct unw_state_record *sr)
920 if (abi == 3 && context == 'i') {
921 sr->flags |= UNW_FLAG_INTERRUPT_FRAME;
922 <<<<<<< HEAD:arch/ia64/kernel/unwind.c
923 UNW_DPRINT(3, "unwind.%s: interrupt frame\n", __FUNCTION__);
924 =======
925 UNW_DPRINT(3, "unwind.%s: interrupt frame\n", __func__);
926 >>>>>>> 264e3e889d86e552b4191d69bb60f4f3b383135a:arch/ia64/kernel/unwind.c
928 else
929 UNW_DPRINT(0, "unwind%s: ignoring unwabi(abi=0x%x,context=0x%x)\n",
930 <<<<<<< HEAD:arch/ia64/kernel/unwind.c
931 __FUNCTION__, abi, context);
932 =======
933 __func__, abi, context);
934 >>>>>>> 264e3e889d86e552b4191d69bb60f4f3b383135a:arch/ia64/kernel/unwind.c
937 static inline void
938 desc_br_gr (unsigned char brmask, unsigned char gr, struct unw_state_record *sr)
940 int i;
942 for (i = 0; i < 5; ++i) {
943 if (brmask & 1)
944 set_reg(sr->curr.reg + UNW_REG_B1 + i, UNW_WHERE_GR,
945 sr->region_start + sr->region_len - 1, gr++);
946 brmask >>= 1;
950 static inline void
951 desc_br_mem (unsigned char brmask, struct unw_state_record *sr)
953 int i;
955 for (i = 0; i < 5; ++i) {
956 if (brmask & 1) {
957 set_reg(sr->curr.reg + UNW_REG_B1 + i, UNW_WHERE_SPILL_HOME,
958 sr->region_start + sr->region_len - 1, 0);
959 sr->any_spills = 1;
961 brmask >>= 1;
965 static inline void
966 desc_frgr_mem (unsigned char grmask, unw_word frmask, struct unw_state_record *sr)
968 int i;
970 for (i = 0; i < 4; ++i) {
971 if ((grmask & 1) != 0) {
972 set_reg(sr->curr.reg + UNW_REG_R4 + i, UNW_WHERE_SPILL_HOME,
973 sr->region_start + sr->region_len - 1, 0);
974 sr->any_spills = 1;
976 grmask >>= 1;
978 for (i = 0; i < 20; ++i) {
979 if ((frmask & 1) != 0) {
980 int base = (i < 4) ? UNW_REG_F2 : UNW_REG_F16 - 4;
981 set_reg(sr->curr.reg + base + i, UNW_WHERE_SPILL_HOME,
982 sr->region_start + sr->region_len - 1, 0);
983 sr->any_spills = 1;
985 frmask >>= 1;
989 static inline void
990 desc_fr_mem (unsigned char frmask, struct unw_state_record *sr)
992 int i;
994 for (i = 0; i < 4; ++i) {
995 if ((frmask & 1) != 0) {
996 set_reg(sr->curr.reg + UNW_REG_F2 + i, UNW_WHERE_SPILL_HOME,
997 sr->region_start + sr->region_len - 1, 0);
998 sr->any_spills = 1;
1000 frmask >>= 1;
1004 static inline void
1005 desc_gr_gr (unsigned char grmask, unsigned char gr, struct unw_state_record *sr)
1007 int i;
1009 for (i = 0; i < 4; ++i) {
1010 if ((grmask & 1) != 0)
1011 set_reg(sr->curr.reg + UNW_REG_R4 + i, UNW_WHERE_GR,
1012 sr->region_start + sr->region_len - 1, gr++);
1013 grmask >>= 1;
1017 static inline void
1018 desc_gr_mem (unsigned char grmask, struct unw_state_record *sr)
1020 int i;
1022 for (i = 0; i < 4; ++i) {
1023 if ((grmask & 1) != 0) {
1024 set_reg(sr->curr.reg + UNW_REG_R4 + i, UNW_WHERE_SPILL_HOME,
1025 sr->region_start + sr->region_len - 1, 0);
1026 sr->any_spills = 1;
1028 grmask >>= 1;
1032 static inline void
1033 desc_mem_stack_f (unw_word t, unw_word size, struct unw_state_record *sr)
1035 set_reg(sr->curr.reg + UNW_REG_PSP, UNW_WHERE_NONE,
1036 sr->region_start + min_t(int, t, sr->region_len - 1), 16*size);
1039 static inline void
1040 desc_mem_stack_v (unw_word t, struct unw_state_record *sr)
1042 sr->curr.reg[UNW_REG_PSP].when = sr->region_start + min_t(int, t, sr->region_len - 1);
1045 static inline void
1046 desc_reg_gr (unsigned char reg, unsigned char dst, struct unw_state_record *sr)
1048 set_reg(sr->curr.reg + reg, UNW_WHERE_GR, sr->region_start + sr->region_len - 1, dst);
1051 static inline void
1052 desc_reg_psprel (unsigned char reg, unw_word pspoff, struct unw_state_record *sr)
1054 set_reg(sr->curr.reg + reg, UNW_WHERE_PSPREL, sr->region_start + sr->region_len - 1,
1055 0x10 - 4*pspoff);
1058 static inline void
1059 desc_reg_sprel (unsigned char reg, unw_word spoff, struct unw_state_record *sr)
1061 set_reg(sr->curr.reg + reg, UNW_WHERE_SPREL, sr->region_start + sr->region_len - 1,
1062 4*spoff);
1065 static inline void
1066 desc_rp_br (unsigned char dst, struct unw_state_record *sr)
1068 sr->return_link_reg = dst;
1071 static inline void
1072 desc_reg_when (unsigned char regnum, unw_word t, struct unw_state_record *sr)
1074 struct unw_reg_info *reg = sr->curr.reg + regnum;
1076 if (reg->where == UNW_WHERE_NONE)
1077 reg->where = UNW_WHERE_GR_SAVE;
1078 reg->when = sr->region_start + min_t(int, t, sr->region_len - 1);
1081 static inline void
1082 desc_spill_base (unw_word pspoff, struct unw_state_record *sr)
1084 sr->spill_offset = 0x10 - 4*pspoff;
1087 static inline unsigned char *
1088 desc_spill_mask (unsigned char *imaskp, struct unw_state_record *sr)
1090 sr->imask = imaskp;
1091 return imaskp + (2*sr->region_len + 7)/8;
1095 * Body descriptors.
1097 static inline void
1098 desc_epilogue (unw_word t, unw_word ecount, struct unw_state_record *sr)
1100 sr->epilogue_start = sr->region_start + sr->region_len - 1 - t;
1101 sr->epilogue_count = ecount + 1;
1104 static inline void
1105 desc_copy_state (unw_word label, struct unw_state_record *sr)
1107 struct unw_labeled_state *ls;
1109 for (ls = sr->labeled_states; ls; ls = ls->next) {
1110 if (ls->label == label) {
1111 free_state_stack(&sr->curr);
1112 memcpy(&sr->curr, &ls->saved_state, sizeof(sr->curr));
1113 sr->curr.next = dup_state_stack(ls->saved_state.next);
1114 return;
1117 printk(KERN_ERR "unwind: failed to find state labeled 0x%lx\n", label);
1120 static inline void
1121 desc_label_state (unw_word label, struct unw_state_record *sr)
1123 struct unw_labeled_state *ls;
1125 ls = alloc_labeled_state();
1126 if (!ls) {
1127 printk(KERN_ERR "unwind.desc_label_state(): out of memory\n");
1128 return;
1130 ls->label = label;
1131 memcpy(&ls->saved_state, &sr->curr, sizeof(ls->saved_state));
1132 ls->saved_state.next = dup_state_stack(sr->curr.next);
1134 /* insert into list of labeled states: */
1135 ls->next = sr->labeled_states;
1136 sr->labeled_states = ls;
1140 * General descriptors.
1143 static inline int
1144 desc_is_active (unsigned char qp, unw_word t, struct unw_state_record *sr)
1146 if (sr->when_target <= sr->region_start + min_t(int, t, sr->region_len - 1))
1147 return 0;
1148 if (qp > 0) {
1149 if ((sr->pr_val & (1UL << qp)) == 0)
1150 return 0;
1151 sr->pr_mask |= (1UL << qp);
1153 return 1;
1156 static inline void
1157 desc_restore_p (unsigned char qp, unw_word t, unsigned char abreg, struct unw_state_record *sr)
1159 struct unw_reg_info *r;
1161 if (!desc_is_active(qp, t, sr))
1162 return;
1164 r = sr->curr.reg + decode_abreg(abreg, 0);
1165 r->where = UNW_WHERE_NONE;
1166 r->when = UNW_WHEN_NEVER;
1167 r->val = 0;
1170 static inline void
1171 desc_spill_reg_p (unsigned char qp, unw_word t, unsigned char abreg, unsigned char x,
1172 unsigned char ytreg, struct unw_state_record *sr)
1174 enum unw_where where = UNW_WHERE_GR;
1175 struct unw_reg_info *r;
1177 if (!desc_is_active(qp, t, sr))
1178 return;
1180 if (x)
1181 where = UNW_WHERE_BR;
1182 else if (ytreg & 0x80)
1183 where = UNW_WHERE_FR;
1185 r = sr->curr.reg + decode_abreg(abreg, 0);
1186 r->where = where;
1187 r->when = sr->region_start + min_t(int, t, sr->region_len - 1);
1188 r->val = (ytreg & 0x7f);
1191 static inline void
1192 desc_spill_psprel_p (unsigned char qp, unw_word t, unsigned char abreg, unw_word pspoff,
1193 struct unw_state_record *sr)
1195 struct unw_reg_info *r;
1197 if (!desc_is_active(qp, t, sr))
1198 return;
1200 r = sr->curr.reg + decode_abreg(abreg, 1);
1201 r->where = UNW_WHERE_PSPREL;
1202 r->when = sr->region_start + min_t(int, t, sr->region_len - 1);
1203 r->val = 0x10 - 4*pspoff;
1206 static inline void
1207 desc_spill_sprel_p (unsigned char qp, unw_word t, unsigned char abreg, unw_word spoff,
1208 struct unw_state_record *sr)
1210 struct unw_reg_info *r;
1212 if (!desc_is_active(qp, t, sr))
1213 return;
1215 r = sr->curr.reg + decode_abreg(abreg, 1);
1216 r->where = UNW_WHERE_SPREL;
1217 r->when = sr->region_start + min_t(int, t, sr->region_len - 1);
1218 r->val = 4*spoff;
1221 #define UNW_DEC_BAD_CODE(code) printk(KERN_ERR "unwind: unknown code 0x%02x\n", \
1222 code);
1225 * region headers:
1227 #define UNW_DEC_PROLOGUE_GR(fmt,r,m,gr,arg) desc_prologue(0,r,m,gr,arg)
1228 #define UNW_DEC_PROLOGUE(fmt,b,r,arg) desc_prologue(b,r,0,32,arg)
1230 * prologue descriptors:
1232 #define UNW_DEC_ABI(fmt,a,c,arg) desc_abi(a,c,arg)
1233 #define UNW_DEC_BR_GR(fmt,b,g,arg) desc_br_gr(b,g,arg)
1234 #define UNW_DEC_BR_MEM(fmt,b,arg) desc_br_mem(b,arg)
1235 #define UNW_DEC_FRGR_MEM(fmt,g,f,arg) desc_frgr_mem(g,f,arg)
1236 #define UNW_DEC_FR_MEM(fmt,f,arg) desc_fr_mem(f,arg)
1237 #define UNW_DEC_GR_GR(fmt,m,g,arg) desc_gr_gr(m,g,arg)
1238 #define UNW_DEC_GR_MEM(fmt,m,arg) desc_gr_mem(m,arg)
1239 #define UNW_DEC_MEM_STACK_F(fmt,t,s,arg) desc_mem_stack_f(t,s,arg)
1240 #define UNW_DEC_MEM_STACK_V(fmt,t,arg) desc_mem_stack_v(t,arg)
1241 #define UNW_DEC_REG_GR(fmt,r,d,arg) desc_reg_gr(r,d,arg)
1242 #define UNW_DEC_REG_PSPREL(fmt,r,o,arg) desc_reg_psprel(r,o,arg)
1243 #define UNW_DEC_REG_SPREL(fmt,r,o,arg) desc_reg_sprel(r,o,arg)
1244 #define UNW_DEC_REG_WHEN(fmt,r,t,arg) desc_reg_when(r,t,arg)
1245 #define UNW_DEC_PRIUNAT_WHEN_GR(fmt,t,arg) desc_reg_when(UNW_REG_PRI_UNAT_GR,t,arg)
1246 #define UNW_DEC_PRIUNAT_WHEN_MEM(fmt,t,arg) desc_reg_when(UNW_REG_PRI_UNAT_MEM,t,arg)
1247 #define UNW_DEC_PRIUNAT_GR(fmt,r,arg) desc_reg_gr(UNW_REG_PRI_UNAT_GR,r,arg)
1248 #define UNW_DEC_PRIUNAT_PSPREL(fmt,o,arg) desc_reg_psprel(UNW_REG_PRI_UNAT_MEM,o,arg)
1249 #define UNW_DEC_PRIUNAT_SPREL(fmt,o,arg) desc_reg_sprel(UNW_REG_PRI_UNAT_MEM,o,arg)
1250 #define UNW_DEC_RP_BR(fmt,d,arg) desc_rp_br(d,arg)
1251 #define UNW_DEC_SPILL_BASE(fmt,o,arg) desc_spill_base(o,arg)
1252 #define UNW_DEC_SPILL_MASK(fmt,m,arg) (m = desc_spill_mask(m,arg))
1254 * body descriptors:
1256 #define UNW_DEC_EPILOGUE(fmt,t,c,arg) desc_epilogue(t,c,arg)
1257 #define UNW_DEC_COPY_STATE(fmt,l,arg) desc_copy_state(l,arg)
1258 #define UNW_DEC_LABEL_STATE(fmt,l,arg) desc_label_state(l,arg)
1260 * general unwind descriptors:
1262 #define UNW_DEC_SPILL_REG_P(f,p,t,a,x,y,arg) desc_spill_reg_p(p,t,a,x,y,arg)
1263 #define UNW_DEC_SPILL_REG(f,t,a,x,y,arg) desc_spill_reg_p(0,t,a,x,y,arg)
1264 #define UNW_DEC_SPILL_PSPREL_P(f,p,t,a,o,arg) desc_spill_psprel_p(p,t,a,o,arg)
1265 #define UNW_DEC_SPILL_PSPREL(f,t,a,o,arg) desc_spill_psprel_p(0,t,a,o,arg)
1266 #define UNW_DEC_SPILL_SPREL_P(f,p,t,a,o,arg) desc_spill_sprel_p(p,t,a,o,arg)
1267 #define UNW_DEC_SPILL_SPREL(f,t,a,o,arg) desc_spill_sprel_p(0,t,a,o,arg)
1268 #define UNW_DEC_RESTORE_P(f,p,t,a,arg) desc_restore_p(p,t,a,arg)
1269 #define UNW_DEC_RESTORE(f,t,a,arg) desc_restore_p(0,t,a,arg)
1271 #include "unwind_decoder.c"
1274 /* Unwind scripts. */
1276 static inline unw_hash_index_t
1277 hash (unsigned long ip)
1279 # define hashmagic 0x9e3779b97f4a7c16UL /* based on (sqrt(5)/2-1)*2^64 */
1281 return (ip >> 4)*hashmagic >> (64 - UNW_LOG_HASH_SIZE);
1282 #undef hashmagic
1285 static inline long
1286 cache_match (struct unw_script *script, unsigned long ip, unsigned long pr)
1288 read_lock(&script->lock);
1289 if (ip == script->ip && ((pr ^ script->pr_val) & script->pr_mask) == 0)
1290 /* keep the read lock... */
1291 return 1;
1292 read_unlock(&script->lock);
1293 return 0;
1296 static inline struct unw_script *
1297 script_lookup (struct unw_frame_info *info)
1299 struct unw_script *script = unw.cache + info->hint;
1300 unsigned short index;
1301 unsigned long ip, pr;
1303 if (UNW_DEBUG_ON(0))
1304 return NULL; /* Always regenerate scripts in debug mode */
1306 STAT(++unw.stat.cache.lookups);
1308 ip = info->ip;
1309 pr = info->pr;
1311 if (cache_match(script, ip, pr)) {
1312 STAT(++unw.stat.cache.hinted_hits);
1313 return script;
1316 index = unw.hash[hash(ip)];
1317 if (index >= UNW_CACHE_SIZE)
1318 return NULL;
1320 script = unw.cache + index;
1321 while (1) {
1322 if (cache_match(script, ip, pr)) {
1323 /* update hint; no locking required as single-word writes are atomic */
1324 STAT(++unw.stat.cache.normal_hits);
1325 unw.cache[info->prev_script].hint = script - unw.cache;
1326 return script;
1328 if (script->coll_chain >= UNW_HASH_SIZE)
1329 return NULL;
1330 script = unw.cache + script->coll_chain;
1331 STAT(++unw.stat.cache.collision_chain_traversals);
1336 * On returning, a write lock for the SCRIPT is still being held.
1338 static inline struct unw_script *
1339 script_new (unsigned long ip)
1341 struct unw_script *script, *prev, *tmp;
1342 unw_hash_index_t index;
1343 unsigned short head;
1345 STAT(++unw.stat.script.news);
1348 * Can't (easily) use cmpxchg() here because of ABA problem
1349 * that is intrinsic in cmpxchg()...
1351 head = unw.lru_head;
1352 script = unw.cache + head;
1353 unw.lru_head = script->lru_chain;
1356 * We'd deadlock here if we interrupted a thread that is holding a read lock on
1357 * script->lock. Thus, if the write_trylock() fails, we simply bail out. The
1358 * alternative would be to disable interrupts whenever we hold a read-lock, but
1359 * that seems silly.
1361 if (!write_trylock(&script->lock))
1362 return NULL;
1364 /* re-insert script at the tail of the LRU chain: */
1365 unw.cache[unw.lru_tail].lru_chain = head;
1366 unw.lru_tail = head;
1368 /* remove the old script from the hash table (if it's there): */
1369 if (script->ip) {
1370 index = hash(script->ip);
1371 tmp = unw.cache + unw.hash[index];
1372 prev = NULL;
1373 while (1) {
1374 if (tmp == script) {
1375 if (prev)
1376 prev->coll_chain = tmp->coll_chain;
1377 else
1378 unw.hash[index] = tmp->coll_chain;
1379 break;
1380 } else
1381 prev = tmp;
1382 if (tmp->coll_chain >= UNW_CACHE_SIZE)
1383 /* old script wasn't in the hash-table */
1384 break;
1385 tmp = unw.cache + tmp->coll_chain;
1389 /* enter new script in the hash table */
1390 index = hash(ip);
1391 script->coll_chain = unw.hash[index];
1392 unw.hash[index] = script - unw.cache;
1394 script->ip = ip; /* set new IP while we're holding the locks */
1396 STAT(if (script->coll_chain < UNW_CACHE_SIZE) ++unw.stat.script.collisions);
1398 script->flags = 0;
1399 script->hint = 0;
1400 script->count = 0;
1401 return script;
1404 static void
1405 script_finalize (struct unw_script *script, struct unw_state_record *sr)
1407 script->pr_mask = sr->pr_mask;
1408 script->pr_val = sr->pr_val;
1410 * We could down-grade our write-lock on script->lock here but
1411 * the rwlock API doesn't offer atomic lock downgrading, so
1412 * we'll just keep the write-lock and release it later when
1413 * we're done using the script.
1417 static inline void
1418 script_emit (struct unw_script *script, struct unw_insn insn)
1420 if (script->count >= UNW_MAX_SCRIPT_LEN) {
1421 UNW_DPRINT(0, "unwind.%s: script exceeds maximum size of %u instructions!\n",
1422 <<<<<<< HEAD:arch/ia64/kernel/unwind.c
1423 __FUNCTION__, UNW_MAX_SCRIPT_LEN);
1424 =======
1425 __func__, UNW_MAX_SCRIPT_LEN);
1426 >>>>>>> 264e3e889d86e552b4191d69bb60f4f3b383135a:arch/ia64/kernel/unwind.c
1427 return;
1429 script->insn[script->count++] = insn;
1432 static inline void
1433 emit_nat_info (struct unw_state_record *sr, int i, struct unw_script *script)
1435 struct unw_reg_info *r = sr->curr.reg + i;
1436 enum unw_insn_opcode opc;
1437 struct unw_insn insn;
1438 unsigned long val = 0;
1440 switch (r->where) {
1441 case UNW_WHERE_GR:
1442 if (r->val >= 32) {
1443 /* register got spilled to a stacked register */
1444 opc = UNW_INSN_SETNAT_TYPE;
1445 val = UNW_NAT_REGSTK;
1446 } else
1447 /* register got spilled to a scratch register */
1448 opc = UNW_INSN_SETNAT_MEMSTK;
1449 break;
1451 case UNW_WHERE_FR:
1452 opc = UNW_INSN_SETNAT_TYPE;
1453 val = UNW_NAT_VAL;
1454 break;
1456 case UNW_WHERE_BR:
1457 opc = UNW_INSN_SETNAT_TYPE;
1458 val = UNW_NAT_NONE;
1459 break;
1461 case UNW_WHERE_PSPREL:
1462 case UNW_WHERE_SPREL:
1463 opc = UNW_INSN_SETNAT_MEMSTK;
1464 break;
1466 default:
1467 UNW_DPRINT(0, "unwind.%s: don't know how to emit nat info for where = %u\n",
1468 <<<<<<< HEAD:arch/ia64/kernel/unwind.c
1469 __FUNCTION__, r->where);
1470 =======
1471 __func__, r->where);
1472 >>>>>>> 264e3e889d86e552b4191d69bb60f4f3b383135a:arch/ia64/kernel/unwind.c
1473 return;
1475 insn.opc = opc;
1476 insn.dst = unw.preg_index[i];
1477 insn.val = val;
1478 script_emit(script, insn);
1481 static void
1482 compile_reg (struct unw_state_record *sr, int i, struct unw_script *script)
1484 struct unw_reg_info *r = sr->curr.reg + i;
1485 enum unw_insn_opcode opc;
1486 unsigned long val, rval;
1487 struct unw_insn insn;
1488 long need_nat_info;
1490 if (r->where == UNW_WHERE_NONE || r->when >= sr->when_target)
1491 return;
1493 opc = UNW_INSN_MOVE;
1494 val = rval = r->val;
1495 need_nat_info = (i >= UNW_REG_R4 && i <= UNW_REG_R7);
1497 switch (r->where) {
1498 case UNW_WHERE_GR:
1499 if (rval >= 32) {
1500 opc = UNW_INSN_MOVE_STACKED;
1501 val = rval - 32;
1502 } else if (rval >= 4 && rval <= 7) {
1503 if (need_nat_info) {
1504 opc = UNW_INSN_MOVE2;
1505 need_nat_info = 0;
1507 val = unw.preg_index[UNW_REG_R4 + (rval - 4)];
1508 } else if (rval == 0) {
1509 opc = UNW_INSN_MOVE_CONST;
1510 val = 0;
1511 } else {
1512 /* register got spilled to a scratch register */
1513 opc = UNW_INSN_MOVE_SCRATCH;
1514 val = pt_regs_off(rval);
1516 break;
1518 case UNW_WHERE_FR:
1519 if (rval <= 5)
1520 val = unw.preg_index[UNW_REG_F2 + (rval - 2)];
1521 else if (rval >= 16 && rval <= 31)
1522 val = unw.preg_index[UNW_REG_F16 + (rval - 16)];
1523 else {
1524 opc = UNW_INSN_MOVE_SCRATCH;
1525 if (rval <= 11)
1526 val = offsetof(struct pt_regs, f6) + 16*(rval - 6);
1527 else
1528 UNW_DPRINT(0, "unwind.%s: kernel may not touch f%lu\n",
1529 <<<<<<< HEAD:arch/ia64/kernel/unwind.c
1530 __FUNCTION__, rval);
1531 =======
1532 __func__, rval);
1533 >>>>>>> 264e3e889d86e552b4191d69bb60f4f3b383135a:arch/ia64/kernel/unwind.c
1535 break;
1537 case UNW_WHERE_BR:
1538 if (rval >= 1 && rval <= 5)
1539 val = unw.preg_index[UNW_REG_B1 + (rval - 1)];
1540 else {
1541 opc = UNW_INSN_MOVE_SCRATCH;
1542 if (rval == 0)
1543 val = offsetof(struct pt_regs, b0);
1544 else if (rval == 6)
1545 val = offsetof(struct pt_regs, b6);
1546 else
1547 val = offsetof(struct pt_regs, b7);
1549 break;
1551 case UNW_WHERE_SPREL:
1552 opc = UNW_INSN_ADD_SP;
1553 break;
1555 case UNW_WHERE_PSPREL:
1556 opc = UNW_INSN_ADD_PSP;
1557 break;
1559 default:
1560 UNW_DPRINT(0, "unwind%s: register %u has unexpected `where' value of %u\n",
1561 <<<<<<< HEAD:arch/ia64/kernel/unwind.c
1562 __FUNCTION__, i, r->where);
1563 =======
1564 __func__, i, r->where);
1565 >>>>>>> 264e3e889d86e552b4191d69bb60f4f3b383135a:arch/ia64/kernel/unwind.c
1566 break;
1568 insn.opc = opc;
1569 insn.dst = unw.preg_index[i];
1570 insn.val = val;
1571 script_emit(script, insn);
1572 if (need_nat_info)
1573 emit_nat_info(sr, i, script);
1575 if (i == UNW_REG_PSP) {
1577 * info->psp must contain the _value_ of the previous
1578 * sp, not it's save location. We get this by
1579 * dereferencing the value we just stored in
1580 * info->psp:
1582 insn.opc = UNW_INSN_LOAD;
1583 insn.dst = insn.val = unw.preg_index[UNW_REG_PSP];
1584 script_emit(script, insn);
1588 static inline const struct unw_table_entry *
1589 lookup (struct unw_table *table, unsigned long rel_ip)
1591 const struct unw_table_entry *e = NULL;
1592 unsigned long lo, hi, mid;
1594 /* do a binary search for right entry: */
1595 for (lo = 0, hi = table->length; lo < hi; ) {
1596 mid = (lo + hi) / 2;
1597 e = &table->array[mid];
1598 if (rel_ip < e->start_offset)
1599 hi = mid;
1600 else if (rel_ip >= e->end_offset)
1601 lo = mid + 1;
1602 else
1603 break;
1605 if (rel_ip < e->start_offset || rel_ip >= e->end_offset)
1606 return NULL;
1607 return e;
1611 * Build an unwind script that unwinds from state OLD_STATE to the
1612 * entrypoint of the function that called OLD_STATE.
1614 static inline struct unw_script *
1615 build_script (struct unw_frame_info *info)
1617 const struct unw_table_entry *e = NULL;
1618 struct unw_script *script = NULL;
1619 struct unw_labeled_state *ls, *next;
1620 unsigned long ip = info->ip;
1621 struct unw_state_record sr;
1622 struct unw_table *table;
1623 struct unw_reg_info *r;
1624 struct unw_insn insn;
1625 u8 *dp, *desc_end;
1626 u64 hdr;
1627 int i;
1628 STAT(unsigned long start, parse_start;)
1630 STAT(++unw.stat.script.builds; start = ia64_get_itc());
1632 /* build state record */
1633 memset(&sr, 0, sizeof(sr));
1634 for (r = sr.curr.reg; r < sr.curr.reg + UNW_NUM_REGS; ++r)
1635 r->when = UNW_WHEN_NEVER;
1636 sr.pr_val = info->pr;
1638 <<<<<<< HEAD:arch/ia64/kernel/unwind.c
1639 UNW_DPRINT(3, "unwind.%s: ip 0x%lx\n", __FUNCTION__, ip);
1640 =======
1641 UNW_DPRINT(3, "unwind.%s: ip 0x%lx\n", __func__, ip);
1642 >>>>>>> 264e3e889d86e552b4191d69bb60f4f3b383135a:arch/ia64/kernel/unwind.c
1643 script = script_new(ip);
1644 if (!script) {
1645 <<<<<<< HEAD:arch/ia64/kernel/unwind.c
1646 UNW_DPRINT(0, "unwind.%s: failed to create unwind script\n", __FUNCTION__);
1647 =======
1648 UNW_DPRINT(0, "unwind.%s: failed to create unwind script\n", __func__);
1649 >>>>>>> 264e3e889d86e552b4191d69bb60f4f3b383135a:arch/ia64/kernel/unwind.c
1650 STAT(unw.stat.script.build_time += ia64_get_itc() - start);
1651 return NULL;
1653 unw.cache[info->prev_script].hint = script - unw.cache;
1655 /* search the kernels and the modules' unwind tables for IP: */
1657 STAT(parse_start = ia64_get_itc());
1659 for (table = unw.tables; table; table = table->next) {
1660 if (ip >= table->start && ip < table->end) {
1661 e = lookup(table, ip - table->segment_base);
1662 break;
1665 if (!e) {
1666 /* no info, return default unwinder (leaf proc, no mem stack, no saved regs) */
1667 UNW_DPRINT(1, "unwind.%s: no unwind info for ip=0x%lx (prev ip=0x%lx)\n",
1668 <<<<<<< HEAD:arch/ia64/kernel/unwind.c
1669 __FUNCTION__, ip, unw.cache[info->prev_script].ip);
1670 =======
1671 __func__, ip, unw.cache[info->prev_script].ip);
1672 >>>>>>> 264e3e889d86e552b4191d69bb60f4f3b383135a:arch/ia64/kernel/unwind.c
1673 sr.curr.reg[UNW_REG_RP].where = UNW_WHERE_BR;
1674 sr.curr.reg[UNW_REG_RP].when = -1;
1675 sr.curr.reg[UNW_REG_RP].val = 0;
1676 compile_reg(&sr, UNW_REG_RP, script);
1677 script_finalize(script, &sr);
1678 STAT(unw.stat.script.parse_time += ia64_get_itc() - parse_start);
1679 STAT(unw.stat.script.build_time += ia64_get_itc() - start);
1680 return script;
1683 sr.when_target = (3*((ip & ~0xfUL) - (table->segment_base + e->start_offset))/16
1684 + (ip & 0xfUL));
1685 hdr = *(u64 *) (table->segment_base + e->info_offset);
1686 dp = (u8 *) (table->segment_base + e->info_offset + 8);
1687 desc_end = dp + 8*UNW_LENGTH(hdr);
1689 while (!sr.done && dp < desc_end)
1690 dp = unw_decode(dp, sr.in_body, &sr);
1692 if (sr.when_target > sr.epilogue_start) {
1694 * sp has been restored and all values on the memory stack below
1695 * psp also have been restored.
1697 sr.curr.reg[UNW_REG_PSP].val = 0;
1698 sr.curr.reg[UNW_REG_PSP].where = UNW_WHERE_NONE;
1699 sr.curr.reg[UNW_REG_PSP].when = UNW_WHEN_NEVER;
1700 for (r = sr.curr.reg; r < sr.curr.reg + UNW_NUM_REGS; ++r)
1701 if ((r->where == UNW_WHERE_PSPREL && r->val <= 0x10)
1702 || r->where == UNW_WHERE_SPREL)
1704 r->val = 0;
1705 r->where = UNW_WHERE_NONE;
1706 r->when = UNW_WHEN_NEVER;
1710 script->flags = sr.flags;
1713 * If RP did't get saved, generate entry for the return link
1714 * register.
1716 if (sr.curr.reg[UNW_REG_RP].when >= sr.when_target) {
1717 sr.curr.reg[UNW_REG_RP].where = UNW_WHERE_BR;
1718 sr.curr.reg[UNW_REG_RP].when = -1;
1719 sr.curr.reg[UNW_REG_RP].val = sr.return_link_reg;
1720 UNW_DPRINT(1, "unwind.%s: using default for rp at ip=0x%lx where=%d val=0x%lx\n",
1721 <<<<<<< HEAD:arch/ia64/kernel/unwind.c
1722 __FUNCTION__, ip, sr.curr.reg[UNW_REG_RP].where,
1723 =======
1724 __func__, ip, sr.curr.reg[UNW_REG_RP].where,
1725 >>>>>>> 264e3e889d86e552b4191d69bb60f4f3b383135a:arch/ia64/kernel/unwind.c
1726 sr.curr.reg[UNW_REG_RP].val);
1729 #ifdef UNW_DEBUG
1730 UNW_DPRINT(1, "unwind.%s: state record for func 0x%lx, t=%u:\n",
1731 <<<<<<< HEAD:arch/ia64/kernel/unwind.c
1732 __FUNCTION__, table->segment_base + e->start_offset, sr.when_target);
1733 =======
1734 __func__, table->segment_base + e->start_offset, sr.when_target);
1735 >>>>>>> 264e3e889d86e552b4191d69bb60f4f3b383135a:arch/ia64/kernel/unwind.c
1736 for (r = sr.curr.reg; r < sr.curr.reg + UNW_NUM_REGS; ++r) {
1737 if (r->where != UNW_WHERE_NONE || r->when != UNW_WHEN_NEVER) {
1738 UNW_DPRINT(1, " %s <- ", unw.preg_name[r - sr.curr.reg]);
1739 switch (r->where) {
1740 case UNW_WHERE_GR: UNW_DPRINT(1, "r%lu", r->val); break;
1741 case UNW_WHERE_FR: UNW_DPRINT(1, "f%lu", r->val); break;
1742 case UNW_WHERE_BR: UNW_DPRINT(1, "b%lu", r->val); break;
1743 case UNW_WHERE_SPREL: UNW_DPRINT(1, "[sp+0x%lx]", r->val); break;
1744 case UNW_WHERE_PSPREL: UNW_DPRINT(1, "[psp+0x%lx]", r->val); break;
1745 case UNW_WHERE_NONE:
1746 UNW_DPRINT(1, "%s+0x%lx", unw.preg_name[r - sr.curr.reg], r->val);
1747 break;
1749 default:
1750 UNW_DPRINT(1, "BADWHERE(%d)", r->where);
1751 break;
1753 UNW_DPRINT(1, "\t\t%d\n", r->when);
1756 #endif
1758 STAT(unw.stat.script.parse_time += ia64_get_itc() - parse_start);
1760 /* translate state record into unwinder instructions: */
1763 * First, set psp if we're dealing with a fixed-size frame;
1764 * subsequent instructions may depend on this value.
1766 if (sr.when_target > sr.curr.reg[UNW_REG_PSP].when
1767 && (sr.curr.reg[UNW_REG_PSP].where == UNW_WHERE_NONE)
1768 && sr.curr.reg[UNW_REG_PSP].val != 0) {
1769 /* new psp is sp plus frame size */
1770 insn.opc = UNW_INSN_ADD;
1771 insn.dst = offsetof(struct unw_frame_info, psp)/8;
1772 insn.val = sr.curr.reg[UNW_REG_PSP].val; /* frame size */
1773 script_emit(script, insn);
1776 /* determine where the primary UNaT is: */
1777 if (sr.when_target < sr.curr.reg[UNW_REG_PRI_UNAT_GR].when)
1778 i = UNW_REG_PRI_UNAT_MEM;
1779 else if (sr.when_target < sr.curr.reg[UNW_REG_PRI_UNAT_MEM].when)
1780 i = UNW_REG_PRI_UNAT_GR;
1781 else if (sr.curr.reg[UNW_REG_PRI_UNAT_MEM].when > sr.curr.reg[UNW_REG_PRI_UNAT_GR].when)
1782 i = UNW_REG_PRI_UNAT_MEM;
1783 else
1784 i = UNW_REG_PRI_UNAT_GR;
1786 compile_reg(&sr, i, script);
1788 for (i = UNW_REG_BSP; i < UNW_NUM_REGS; ++i)
1789 compile_reg(&sr, i, script);
1791 /* free labeled register states & stack: */
1793 STAT(parse_start = ia64_get_itc());
1794 for (ls = sr.labeled_states; ls; ls = next) {
1795 next = ls->next;
1796 free_state_stack(&ls->saved_state);
1797 free_labeled_state(ls);
1799 free_state_stack(&sr.curr);
1800 STAT(unw.stat.script.parse_time += ia64_get_itc() - parse_start);
1802 script_finalize(script, &sr);
1803 STAT(unw.stat.script.build_time += ia64_get_itc() - start);
1804 return script;
1808 * Apply the unwinding actions represented by OPS and update SR to
1809 * reflect the state that existed upon entry to the function that this
1810 * unwinder represents.
1812 static inline void
1813 run_script (struct unw_script *script, struct unw_frame_info *state)
1815 struct unw_insn *ip, *limit, next_insn;
1816 unsigned long opc, dst, val, off;
1817 unsigned long *s = (unsigned long *) state;
1818 STAT(unsigned long start;)
1820 STAT(++unw.stat.script.runs; start = ia64_get_itc());
1821 state->flags = script->flags;
1822 ip = script->insn;
1823 limit = script->insn + script->count;
1824 next_insn = *ip;
1826 while (ip++ < limit) {
1827 opc = next_insn.opc;
1828 dst = next_insn.dst;
1829 val = next_insn.val;
1830 next_insn = *ip;
1832 redo:
1833 switch (opc) {
1834 case UNW_INSN_ADD:
1835 s[dst] += val;
1836 break;
1838 case UNW_INSN_MOVE2:
1839 if (!s[val])
1840 goto lazy_init;
1841 s[dst+1] = s[val+1];
1842 s[dst] = s[val];
1843 break;
1845 case UNW_INSN_MOVE:
1846 if (!s[val])
1847 goto lazy_init;
1848 s[dst] = s[val];
1849 break;
1851 case UNW_INSN_MOVE_SCRATCH:
1852 if (state->pt) {
1853 s[dst] = (unsigned long) get_scratch_regs(state) + val;
1854 } else {
1855 s[dst] = 0;
1856 UNW_DPRINT(0, "unwind.%s: no state->pt, dst=%ld, val=%ld\n",
1857 <<<<<<< HEAD:arch/ia64/kernel/unwind.c
1858 __FUNCTION__, dst, val);
1859 =======
1860 __func__, dst, val);
1861 >>>>>>> 264e3e889d86e552b4191d69bb60f4f3b383135a:arch/ia64/kernel/unwind.c
1863 break;
1865 case UNW_INSN_MOVE_CONST:
1866 if (val == 0)
1867 s[dst] = (unsigned long) &unw.r0;
1868 else {
1869 s[dst] = 0;
1870 UNW_DPRINT(0, "unwind.%s: UNW_INSN_MOVE_CONST bad val=%ld\n",
1871 <<<<<<< HEAD:arch/ia64/kernel/unwind.c
1872 __FUNCTION__, val);
1873 =======
1874 __func__, val);
1875 >>>>>>> 264e3e889d86e552b4191d69bb60f4f3b383135a:arch/ia64/kernel/unwind.c
1877 break;
1880 case UNW_INSN_MOVE_STACKED:
1881 s[dst] = (unsigned long) ia64_rse_skip_regs((unsigned long *)state->bsp,
1882 val);
1883 break;
1885 case UNW_INSN_ADD_PSP:
1886 s[dst] = state->psp + val;
1887 break;
1889 case UNW_INSN_ADD_SP:
1890 s[dst] = state->sp + val;
1891 break;
1893 case UNW_INSN_SETNAT_MEMSTK:
1894 if (!state->pri_unat_loc)
1895 state->pri_unat_loc = &state->sw->caller_unat;
1896 /* register off. is a multiple of 8, so the least 3 bits (type) are 0 */
1897 s[dst+1] = ((unsigned long) state->pri_unat_loc - s[dst]) | UNW_NAT_MEMSTK;
1898 break;
1900 case UNW_INSN_SETNAT_TYPE:
1901 s[dst+1] = val;
1902 break;
1904 case UNW_INSN_LOAD:
1905 #ifdef UNW_DEBUG
1906 if ((s[val] & (local_cpu_data->unimpl_va_mask | 0x7)) != 0
1907 || s[val] < TASK_SIZE)
1909 UNW_DPRINT(0, "unwind.%s: rejecting bad psp=0x%lx\n",
1910 <<<<<<< HEAD:arch/ia64/kernel/unwind.c
1911 __FUNCTION__, s[val]);
1912 =======
1913 __func__, s[val]);
1914 >>>>>>> 264e3e889d86e552b4191d69bb60f4f3b383135a:arch/ia64/kernel/unwind.c
1915 break;
1917 #endif
1918 s[dst] = *(unsigned long *) s[val];
1919 break;
1922 STAT(unw.stat.script.run_time += ia64_get_itc() - start);
1923 return;
1925 lazy_init:
1926 off = unw.sw_off[val];
1927 s[val] = (unsigned long) state->sw + off;
1928 if (off >= offsetof(struct switch_stack, r4) && off <= offsetof(struct switch_stack, r7))
1930 * We're initializing a general register: init NaT info, too. Note that
1931 * the offset is a multiple of 8 which gives us the 3 bits needed for
1932 * the type field.
1934 s[val+1] = (offsetof(struct switch_stack, ar_unat) - off) | UNW_NAT_MEMSTK;
1935 goto redo;
1938 static int
1939 find_save_locs (struct unw_frame_info *info)
1941 int have_write_lock = 0;
1942 struct unw_script *scr;
1943 unsigned long flags = 0;
1945 if ((info->ip & (local_cpu_data->unimpl_va_mask | 0xf)) || info->ip < TASK_SIZE) {
1946 /* don't let obviously bad addresses pollute the cache */
1947 /* FIXME: should really be level 0 but it occurs too often. KAO */
1948 <<<<<<< HEAD:arch/ia64/kernel/unwind.c
1949 UNW_DPRINT(1, "unwind.%s: rejecting bad ip=0x%lx\n", __FUNCTION__, info->ip);
1950 =======
1951 UNW_DPRINT(1, "unwind.%s: rejecting bad ip=0x%lx\n", __func__, info->ip);
1952 >>>>>>> 264e3e889d86e552b4191d69bb60f4f3b383135a:arch/ia64/kernel/unwind.c
1953 info->rp_loc = NULL;
1954 return -1;
1957 scr = script_lookup(info);
1958 if (!scr) {
1959 spin_lock_irqsave(&unw.lock, flags);
1960 scr = build_script(info);
1961 if (!scr) {
1962 spin_unlock_irqrestore(&unw.lock, flags);
1963 UNW_DPRINT(0,
1964 "unwind.%s: failed to locate/build unwind script for ip %lx\n",
1965 <<<<<<< HEAD:arch/ia64/kernel/unwind.c
1966 __FUNCTION__, info->ip);
1967 =======
1968 __func__, info->ip);
1969 >>>>>>> 264e3e889d86e552b4191d69bb60f4f3b383135a:arch/ia64/kernel/unwind.c
1970 return -1;
1972 have_write_lock = 1;
1974 info->hint = scr->hint;
1975 info->prev_script = scr - unw.cache;
1977 run_script(scr, info);
1979 if (have_write_lock) {
1980 write_unlock(&scr->lock);
1981 spin_unlock_irqrestore(&unw.lock, flags);
1982 } else
1983 read_unlock(&scr->lock);
1984 return 0;
1987 static int
1988 unw_valid(const struct unw_frame_info *info, unsigned long* p)
1990 unsigned long loc = (unsigned long)p;
1991 return (loc >= info->regstk.limit && loc < info->regstk.top) ||
1992 (loc >= info->memstk.top && loc < info->memstk.limit);
1996 unw_unwind (struct unw_frame_info *info)
1998 unsigned long prev_ip, prev_sp, prev_bsp;
1999 unsigned long ip, pr, num_regs;
2000 STAT(unsigned long start, flags;)
2001 int retval;
2003 STAT(local_irq_save(flags); ++unw.stat.api.unwinds; start = ia64_get_itc());
2005 prev_ip = info->ip;
2006 prev_sp = info->sp;
2007 prev_bsp = info->bsp;
2009 /* validate the return IP pointer */
2010 if (!unw_valid(info, info->rp_loc)) {
2011 /* FIXME: should really be level 0 but it occurs too often. KAO */
2012 UNW_DPRINT(1, "unwind.%s: failed to locate return link (ip=0x%lx)!\n",
2013 <<<<<<< HEAD:arch/ia64/kernel/unwind.c
2014 __FUNCTION__, info->ip);
2015 =======
2016 __func__, info->ip);
2017 >>>>>>> 264e3e889d86e552b4191d69bb60f4f3b383135a:arch/ia64/kernel/unwind.c
2018 STAT(unw.stat.api.unwind_time += ia64_get_itc() - start; local_irq_restore(flags));
2019 return -1;
2021 /* restore the ip */
2022 ip = info->ip = *info->rp_loc;
2023 if (ip < GATE_ADDR) {
2024 <<<<<<< HEAD:arch/ia64/kernel/unwind.c
2025 UNW_DPRINT(2, "unwind.%s: reached user-space (ip=0x%lx)\n", __FUNCTION__, ip);
2026 =======
2027 UNW_DPRINT(2, "unwind.%s: reached user-space (ip=0x%lx)\n", __func__, ip);
2028 >>>>>>> 264e3e889d86e552b4191d69bb60f4f3b383135a:arch/ia64/kernel/unwind.c
2029 STAT(unw.stat.api.unwind_time += ia64_get_itc() - start; local_irq_restore(flags));
2030 return -1;
2033 /* validate the previous stack frame pointer */
2034 if (!unw_valid(info, info->pfs_loc)) {
2035 <<<<<<< HEAD:arch/ia64/kernel/unwind.c
2036 UNW_DPRINT(0, "unwind.%s: failed to locate ar.pfs!\n", __FUNCTION__);
2037 =======
2038 UNW_DPRINT(0, "unwind.%s: failed to locate ar.pfs!\n", __func__);
2039 >>>>>>> 264e3e889d86e552b4191d69bb60f4f3b383135a:arch/ia64/kernel/unwind.c
2040 STAT(unw.stat.api.unwind_time += ia64_get_itc() - start; local_irq_restore(flags));
2041 return -1;
2043 /* restore the cfm: */
2044 info->cfm_loc = info->pfs_loc;
2046 /* restore the bsp: */
2047 pr = info->pr;
2048 num_regs = 0;
2049 if ((info->flags & UNW_FLAG_INTERRUPT_FRAME)) {
2050 info->pt = info->sp + 16;
2051 if ((pr & (1UL << PRED_NON_SYSCALL)) != 0)
2052 num_regs = *info->cfm_loc & 0x7f; /* size of frame */
2053 info->pfs_loc =
2054 (unsigned long *) (info->pt + offsetof(struct pt_regs, ar_pfs));
2055 <<<<<<< HEAD:arch/ia64/kernel/unwind.c
2056 UNW_DPRINT(3, "unwind.%s: interrupt_frame pt 0x%lx\n", __FUNCTION__, info->pt);
2057 =======
2058 UNW_DPRINT(3, "unwind.%s: interrupt_frame pt 0x%lx\n", __func__, info->pt);
2059 >>>>>>> 264e3e889d86e552b4191d69bb60f4f3b383135a:arch/ia64/kernel/unwind.c
2060 } else
2061 num_regs = (*info->cfm_loc >> 7) & 0x7f; /* size of locals */
2062 info->bsp = (unsigned long) ia64_rse_skip_regs((unsigned long *) info->bsp, -num_regs);
2063 if (info->bsp < info->regstk.limit || info->bsp > info->regstk.top) {
2064 UNW_DPRINT(0, "unwind.%s: bsp (0x%lx) out of range [0x%lx-0x%lx]\n",
2065 <<<<<<< HEAD:arch/ia64/kernel/unwind.c
2066 __FUNCTION__, info->bsp, info->regstk.limit, info->regstk.top);
2067 =======
2068 __func__, info->bsp, info->regstk.limit, info->regstk.top);
2069 >>>>>>> 264e3e889d86e552b4191d69bb60f4f3b383135a:arch/ia64/kernel/unwind.c
2070 STAT(unw.stat.api.unwind_time += ia64_get_itc() - start; local_irq_restore(flags));
2071 return -1;
2074 /* restore the sp: */
2075 info->sp = info->psp;
2076 if (info->sp < info->memstk.top || info->sp > info->memstk.limit) {
2077 UNW_DPRINT(0, "unwind.%s: sp (0x%lx) out of range [0x%lx-0x%lx]\n",
2078 <<<<<<< HEAD:arch/ia64/kernel/unwind.c
2079 __FUNCTION__, info->sp, info->memstk.top, info->memstk.limit);
2080 =======
2081 __func__, info->sp, info->memstk.top, info->memstk.limit);
2082 >>>>>>> 264e3e889d86e552b4191d69bb60f4f3b383135a:arch/ia64/kernel/unwind.c
2083 STAT(unw.stat.api.unwind_time += ia64_get_itc() - start; local_irq_restore(flags));
2084 return -1;
2087 if (info->ip == prev_ip && info->sp == prev_sp && info->bsp == prev_bsp) {
2088 UNW_DPRINT(0, "unwind.%s: ip, sp, bsp unchanged; stopping here (ip=0x%lx)\n",
2089 <<<<<<< HEAD:arch/ia64/kernel/unwind.c
2090 __FUNCTION__, ip);
2091 =======
2092 __func__, ip);
2093 >>>>>>> 264e3e889d86e552b4191d69bb60f4f3b383135a:arch/ia64/kernel/unwind.c
2094 STAT(unw.stat.api.unwind_time += ia64_get_itc() - start; local_irq_restore(flags));
2095 return -1;
2098 /* as we unwind, the saved ar.unat becomes the primary unat: */
2099 info->pri_unat_loc = info->unat_loc;
2101 /* finally, restore the predicates: */
2102 unw_get_pr(info, &info->pr);
2104 retval = find_save_locs(info);
2105 STAT(unw.stat.api.unwind_time += ia64_get_itc() - start; local_irq_restore(flags));
2106 return retval;
2108 EXPORT_SYMBOL(unw_unwind);
2111 unw_unwind_to_user (struct unw_frame_info *info)
2113 unsigned long ip, sp, pr = info->pr;
2115 do {
2116 unw_get_sp(info, &sp);
2117 if ((long)((unsigned long)info->task + IA64_STK_OFFSET - sp)
2118 < IA64_PT_REGS_SIZE) {
2119 UNW_DPRINT(0, "unwind.%s: ran off the top of the kernel stack\n",
2120 <<<<<<< HEAD:arch/ia64/kernel/unwind.c
2121 __FUNCTION__);
2122 =======
2123 __func__);
2124 >>>>>>> 264e3e889d86e552b4191d69bb60f4f3b383135a:arch/ia64/kernel/unwind.c
2125 break;
2127 if (unw_is_intr_frame(info) &&
2128 (pr & (1UL << PRED_USER_STACK)))
2129 return 0;
2130 if (unw_get_pr (info, &pr) < 0) {
2131 unw_get_rp(info, &ip);
2132 UNW_DPRINT(0, "unwind.%s: failed to read "
2133 "predicate register (ip=0x%lx)\n",
2134 <<<<<<< HEAD:arch/ia64/kernel/unwind.c
2135 __FUNCTION__, ip);
2136 =======
2137 __func__, ip);
2138 >>>>>>> 264e3e889d86e552b4191d69bb60f4f3b383135a:arch/ia64/kernel/unwind.c
2139 return -1;
2141 } while (unw_unwind(info) >= 0);
2142 unw_get_ip(info, &ip);
2143 UNW_DPRINT(0, "unwind.%s: failed to unwind to user-level (ip=0x%lx)\n",
2144 <<<<<<< HEAD:arch/ia64/kernel/unwind.c
2145 __FUNCTION__, ip);
2146 =======
2147 __func__, ip);
2148 >>>>>>> 264e3e889d86e552b4191d69bb60f4f3b383135a:arch/ia64/kernel/unwind.c
2149 return -1;
2151 EXPORT_SYMBOL(unw_unwind_to_user);
2153 static void
2154 init_frame_info (struct unw_frame_info *info, struct task_struct *t,
2155 struct switch_stack *sw, unsigned long stktop)
2157 unsigned long rbslimit, rbstop, stklimit;
2158 STAT(unsigned long start, flags;)
2160 STAT(local_irq_save(flags); ++unw.stat.api.inits; start = ia64_get_itc());
2163 * Subtle stuff here: we _could_ unwind through the switch_stack frame but we
2164 * don't want to do that because it would be slow as each preserved register would
2165 * have to be processed. Instead, what we do here is zero out the frame info and
2166 * start the unwind process at the function that created the switch_stack frame.
2167 * When a preserved value in switch_stack needs to be accessed, run_script() will
2168 * initialize the appropriate pointer on demand.
2170 memset(info, 0, sizeof(*info));
2172 rbslimit = (unsigned long) t + IA64_RBS_OFFSET;
2173 stklimit = (unsigned long) t + IA64_STK_OFFSET;
2175 rbstop = sw->ar_bspstore;
2176 if (rbstop > stklimit || rbstop < rbslimit)
2177 rbstop = rbslimit;
2179 if (stktop <= rbstop)
2180 stktop = rbstop;
2181 if (stktop > stklimit)
2182 stktop = stklimit;
2184 info->regstk.limit = rbslimit;
2185 info->regstk.top = rbstop;
2186 info->memstk.limit = stklimit;
2187 info->memstk.top = stktop;
2188 info->task = t;
2189 info->sw = sw;
2190 info->sp = info->psp = stktop;
2191 info->pr = sw->pr;
2192 UNW_DPRINT(3, "unwind.%s:\n"
2193 " task 0x%lx\n"
2194 " rbs = [0x%lx-0x%lx)\n"
2195 " stk = [0x%lx-0x%lx)\n"
2196 " pr 0x%lx\n"
2197 " sw 0x%lx\n"
2198 " sp 0x%lx\n",
2199 <<<<<<< HEAD:arch/ia64/kernel/unwind.c
2200 __FUNCTION__, (unsigned long) t, rbslimit, rbstop, stktop, stklimit,
2201 =======
2202 __func__, (unsigned long) t, rbslimit, rbstop, stktop, stklimit,
2203 >>>>>>> 264e3e889d86e552b4191d69bb60f4f3b383135a:arch/ia64/kernel/unwind.c
2204 info->pr, (unsigned long) info->sw, info->sp);
2205 STAT(unw.stat.api.init_time += ia64_get_itc() - start; local_irq_restore(flags));
2208 void
2209 unw_init_frame_info (struct unw_frame_info *info, struct task_struct *t, struct switch_stack *sw)
2211 unsigned long sol;
2213 init_frame_info(info, t, sw, (unsigned long) (sw + 1) - 16);
2214 info->cfm_loc = &sw->ar_pfs;
2215 sol = (*info->cfm_loc >> 7) & 0x7f;
2216 info->bsp = (unsigned long) ia64_rse_skip_regs((unsigned long *) info->regstk.top, -sol);
2217 info->ip = sw->b0;
2218 UNW_DPRINT(3, "unwind.%s:\n"
2219 " bsp 0x%lx\n"
2220 " sol 0x%lx\n"
2221 " ip 0x%lx\n",
2222 <<<<<<< HEAD:arch/ia64/kernel/unwind.c
2223 __FUNCTION__, info->bsp, sol, info->ip);
2224 =======
2225 __func__, info->bsp, sol, info->ip);
2226 >>>>>>> 264e3e889d86e552b4191d69bb60f4f3b383135a:arch/ia64/kernel/unwind.c
2227 find_save_locs(info);
2230 EXPORT_SYMBOL(unw_init_frame_info);
2232 void
2233 unw_init_from_blocked_task (struct unw_frame_info *info, struct task_struct *t)
2235 struct switch_stack *sw = (struct switch_stack *) (t->thread.ksp + 16);
2237 <<<<<<< HEAD:arch/ia64/kernel/unwind.c
2238 UNW_DPRINT(1, "unwind.%s\n", __FUNCTION__);
2239 =======
2240 UNW_DPRINT(1, "unwind.%s\n", __func__);
2241 >>>>>>> 264e3e889d86e552b4191d69bb60f4f3b383135a:arch/ia64/kernel/unwind.c
2242 unw_init_frame_info(info, t, sw);
2244 EXPORT_SYMBOL(unw_init_from_blocked_task);
2246 static void
2247 init_unwind_table (struct unw_table *table, const char *name, unsigned long segment_base,
2248 unsigned long gp, const void *table_start, const void *table_end)
2250 const struct unw_table_entry *start = table_start, *end = table_end;
2252 table->name = name;
2253 table->segment_base = segment_base;
2254 table->gp = gp;
2255 table->start = segment_base + start[0].start_offset;
2256 table->end = segment_base + end[-1].end_offset;
2257 table->array = start;
2258 table->length = end - start;
2261 void *
2262 unw_add_unwind_table (const char *name, unsigned long segment_base, unsigned long gp,
2263 const void *table_start, const void *table_end)
2265 const struct unw_table_entry *start = table_start, *end = table_end;
2266 struct unw_table *table;
2267 unsigned long flags;
2269 if (end - start <= 0) {
2270 UNW_DPRINT(0, "unwind.%s: ignoring attempt to insert empty unwind table\n",
2271 <<<<<<< HEAD:arch/ia64/kernel/unwind.c
2272 __FUNCTION__);
2273 =======
2274 __func__);
2275 >>>>>>> 264e3e889d86e552b4191d69bb60f4f3b383135a:arch/ia64/kernel/unwind.c
2276 return NULL;
2279 table = kmalloc(sizeof(*table), GFP_USER);
2280 if (!table)
2281 return NULL;
2283 init_unwind_table(table, name, segment_base, gp, table_start, table_end);
2285 spin_lock_irqsave(&unw.lock, flags);
2287 /* keep kernel unwind table at the front (it's searched most commonly): */
2288 table->next = unw.tables->next;
2289 unw.tables->next = table;
2291 spin_unlock_irqrestore(&unw.lock, flags);
2293 return table;
2296 void
2297 unw_remove_unwind_table (void *handle)
2299 struct unw_table *table, *prev;
2300 struct unw_script *tmp;
2301 unsigned long flags;
2302 long index;
2304 if (!handle) {
2305 UNW_DPRINT(0, "unwind.%s: ignoring attempt to remove non-existent unwind table\n",
2306 <<<<<<< HEAD:arch/ia64/kernel/unwind.c
2307 __FUNCTION__);
2308 =======
2309 __func__);
2310 >>>>>>> 264e3e889d86e552b4191d69bb60f4f3b383135a:arch/ia64/kernel/unwind.c
2311 return;
2314 table = handle;
2315 if (table == &unw.kernel_table) {
2316 UNW_DPRINT(0, "unwind.%s: sorry, freeing the kernel's unwind table is a "
2317 <<<<<<< HEAD:arch/ia64/kernel/unwind.c
2318 "no-can-do!\n", __FUNCTION__);
2319 =======
2320 "no-can-do!\n", __func__);
2321 >>>>>>> 264e3e889d86e552b4191d69bb60f4f3b383135a:arch/ia64/kernel/unwind.c
2322 return;
2325 spin_lock_irqsave(&unw.lock, flags);
2327 /* first, delete the table: */
2329 for (prev = (struct unw_table *) &unw.tables; prev; prev = prev->next)
2330 if (prev->next == table)
2331 break;
2332 if (!prev) {
2333 UNW_DPRINT(0, "unwind.%s: failed to find unwind table %p\n",
2334 <<<<<<< HEAD:arch/ia64/kernel/unwind.c
2335 __FUNCTION__, (void *) table);
2336 =======
2337 __func__, (void *) table);
2338 >>>>>>> 264e3e889d86e552b4191d69bb60f4f3b383135a:arch/ia64/kernel/unwind.c
2339 spin_unlock_irqrestore(&unw.lock, flags);
2340 return;
2342 prev->next = table->next;
2344 spin_unlock_irqrestore(&unw.lock, flags);
2346 /* next, remove hash table entries for this table */
2348 for (index = 0; index <= UNW_HASH_SIZE; ++index) {
2349 tmp = unw.cache + unw.hash[index];
2350 if (unw.hash[index] >= UNW_CACHE_SIZE
2351 || tmp->ip < table->start || tmp->ip >= table->end)
2352 continue;
2354 write_lock(&tmp->lock);
2356 if (tmp->ip >= table->start && tmp->ip < table->end) {
2357 unw.hash[index] = tmp->coll_chain;
2358 tmp->ip = 0;
2361 write_unlock(&tmp->lock);
2364 kfree(table);
2367 static int __init
2368 create_gate_table (void)
2370 const struct unw_table_entry *entry, *start, *end;
2371 unsigned long *lp, segbase = GATE_ADDR;
2372 size_t info_size, size;
2373 char *info;
2374 Elf64_Phdr *punw = NULL, *phdr = (Elf64_Phdr *) (GATE_ADDR + GATE_EHDR->e_phoff);
2375 int i;
2377 for (i = 0; i < GATE_EHDR->e_phnum; ++i, ++phdr)
2378 if (phdr->p_type == PT_IA_64_UNWIND) {
2379 punw = phdr;
2380 break;
2383 if (!punw) {
2384 <<<<<<< HEAD:arch/ia64/kernel/unwind.c
2385 printk("%s: failed to find gate DSO's unwind table!\n", __FUNCTION__);
2386 =======
2387 printk("%s: failed to find gate DSO's unwind table!\n", __func__);
2388 >>>>>>> 264e3e889d86e552b4191d69bb60f4f3b383135a:arch/ia64/kernel/unwind.c
2389 return 0;
2392 start = (const struct unw_table_entry *) punw->p_vaddr;
2393 end = (struct unw_table_entry *) ((char *) start + punw->p_memsz);
2394 size = 0;
2396 unw_add_unwind_table("linux-gate.so", segbase, 0, start, end);
2398 for (entry = start; entry < end; ++entry)
2399 size += 3*8 + 8 + 8*UNW_LENGTH(*(u64 *) (segbase + entry->info_offset));
2400 size += 8; /* reserve space for "end of table" marker */
2402 unw.gate_table = kmalloc(size, GFP_KERNEL);
2403 if (!unw.gate_table) {
2404 unw.gate_table_size = 0;
2405 <<<<<<< HEAD:arch/ia64/kernel/unwind.c
2406 printk(KERN_ERR "%s: unable to create unwind data for gate page!\n", __FUNCTION__);
2407 =======
2408 printk(KERN_ERR "%s: unable to create unwind data for gate page!\n", __func__);
2409 >>>>>>> 264e3e889d86e552b4191d69bb60f4f3b383135a:arch/ia64/kernel/unwind.c
2410 return 0;
2412 unw.gate_table_size = size;
2414 lp = unw.gate_table;
2415 info = (char *) unw.gate_table + size;
2417 for (entry = start; entry < end; ++entry, lp += 3) {
2418 info_size = 8 + 8*UNW_LENGTH(*(u64 *) (segbase + entry->info_offset));
2419 info -= info_size;
2420 memcpy(info, (char *) segbase + entry->info_offset, info_size);
2422 lp[0] = segbase + entry->start_offset; /* start */
2423 lp[1] = segbase + entry->end_offset; /* end */
2424 lp[2] = info - (char *) unw.gate_table; /* info */
2426 *lp = 0; /* end-of-table marker */
2427 return 0;
2430 __initcall(create_gate_table);
2432 void __init
2433 unw_init (void)
2435 extern char __gp[];
2436 extern void unw_hash_index_t_is_too_narrow (void);
2437 long i, off;
2439 if (8*sizeof(unw_hash_index_t) < UNW_LOG_HASH_SIZE)
2440 unw_hash_index_t_is_too_narrow();
2442 unw.sw_off[unw.preg_index[UNW_REG_PRI_UNAT_GR]] = SW(CALLER_UNAT);
2443 unw.sw_off[unw.preg_index[UNW_REG_BSPSTORE]] = SW(AR_BSPSTORE);
2444 unw.sw_off[unw.preg_index[UNW_REG_PFS]] = SW(AR_PFS);
2445 unw.sw_off[unw.preg_index[UNW_REG_RP]] = SW(B0);
2446 unw.sw_off[unw.preg_index[UNW_REG_UNAT]] = SW(CALLER_UNAT);
2447 unw.sw_off[unw.preg_index[UNW_REG_PR]] = SW(PR);
2448 unw.sw_off[unw.preg_index[UNW_REG_LC]] = SW(AR_LC);
2449 unw.sw_off[unw.preg_index[UNW_REG_FPSR]] = SW(AR_FPSR);
2450 for (i = UNW_REG_R4, off = SW(R4); i <= UNW_REG_R7; ++i, off += 8)
2451 unw.sw_off[unw.preg_index[i]] = off;
2452 for (i = UNW_REG_B1, off = SW(B1); i <= UNW_REG_B5; ++i, off += 8)
2453 unw.sw_off[unw.preg_index[i]] = off;
2454 for (i = UNW_REG_F2, off = SW(F2); i <= UNW_REG_F5; ++i, off += 16)
2455 unw.sw_off[unw.preg_index[i]] = off;
2456 for (i = UNW_REG_F16, off = SW(F16); i <= UNW_REG_F31; ++i, off += 16)
2457 unw.sw_off[unw.preg_index[i]] = off;
2459 for (i = 0; i < UNW_CACHE_SIZE; ++i) {
2460 if (i > 0)
2461 unw.cache[i].lru_chain = (i - 1);
2462 unw.cache[i].coll_chain = -1;
2463 rwlock_init(&unw.cache[i].lock);
2465 unw.lru_head = UNW_CACHE_SIZE - 1;
2466 unw.lru_tail = 0;
2468 init_unwind_table(&unw.kernel_table, "kernel", KERNEL_START, (unsigned long) __gp,
2469 __start_unwind, __end_unwind);
2473 * DEPRECATED DEPRECATED DEPRECATED DEPRECATED DEPRECATED DEPRECATED DEPRECATED
2475 * This system call has been deprecated. The new and improved way to get
2476 * at the kernel's unwind info is via the gate DSO. The address of the
2477 * ELF header for this DSO is passed to user-level via AT_SYSINFO_EHDR.
2479 * DEPRECATED DEPRECATED DEPRECATED DEPRECATED DEPRECATED DEPRECATED DEPRECATED
2481 * This system call copies the unwind data into the buffer pointed to by BUF and returns
2482 * the size of the unwind data. If BUF_SIZE is smaller than the size of the unwind data
2483 * or if BUF is NULL, nothing is copied, but the system call still returns the size of the
2484 * unwind data.
2486 * The first portion of the unwind data contains an unwind table and rest contains the
2487 * associated unwind info (in no particular order). The unwind table consists of a table
2488 * of entries of the form:
2490 * u64 start; (64-bit address of start of function)
2491 * u64 end; (64-bit address of start of function)
2492 * u64 info; (BUF-relative offset to unwind info)
2494 * The end of the unwind table is indicated by an entry with a START address of zero.
2496 * Please see the IA-64 Software Conventions and Runtime Architecture manual for details
2497 * on the format of the unwind info.
2499 * ERRORS
2500 * EFAULT BUF points outside your accessible address space.
2502 asmlinkage long
2503 sys_getunwind (void __user *buf, size_t buf_size)
2505 if (buf && buf_size >= unw.gate_table_size)
2506 if (copy_to_user(buf, unw.gate_table, unw.gate_table_size) != 0)
2507 return -EFAULT;
2508 return unw.gate_table_size;