29 #include <linux/module.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>
40 #include <asm/ptrace.h>
43 #include <asm/sections.h>
44 #include <asm/uaccess.h>
49 #define UNW_LOG_CACHE_SIZE 7
50 #define UNW_CACHE_SIZE (1 << UNW_LOG_CACHE_SIZE)
52 #define UNW_LOG_HASH_SIZE (UNW_LOG_CACHE_SIZE + 1)
53 #define UNW_HASH_SIZE (1 << UNW_LOG_HASH_SIZE)
58 static unsigned int unw_debug_level = UNW_DEBUG;
59 # define UNW_DEBUG_ON(n) unw_debug_level >= n
61 # define UNW_DPRINT(n, ...) if (UNW_DEBUG_ON(n)) printk(__VA_ARGS__)
65 # define UNW_DEBUG_ON(n) 0
66 # define UNW_DPRINT(n, ...)
75 #define alloc_reg_state() kmalloc(sizeof(struct unw_reg_state), GFP_ATOMIC)
76 #define free_reg_state(usr) kfree(usr)
77 #define alloc_labeled_state() kmalloc(sizeof(struct unw_labeled_state), GFP_ATOMIC)
78 #define free_labeled_state(usr) kfree(usr)
127 int collision_chain_traversals;
131 unsigned long run_time;
132 unsigned long parse_time;
139 unsigned long init_time;
140 unsigned long unwind_time;
147 .tables = &unw.kernel_table,
201 [4] = -1, [5] = -1, [6] = -1, [7] = -1,
230 "pri_unat_gr",
"pri_unat_mem",
"bsp",
"bspstore",
"ar.pfs",
"ar.rnat",
"psp",
"rp",
231 "r4",
"r5",
"r6",
"r7",
232 "ar.unat",
"pr",
"ar.lc",
"ar.fpsr",
233 "b1",
"b2",
"b3",
"b4",
"b5",
234 "f2",
"f3",
"f4",
"f5",
235 "f16",
"f17",
"f18",
"f19",
"f20",
"f21",
"f22",
"f23",
236 "f24",
"f25",
"f26",
"f27",
"f28",
"f29",
"f30",
"f31"
244 return (
unsigned long) ((
char *) addr - (
char *) &unw.r0) <
sizeof(unw.r0);
250 static inline unsigned long
251 pt_regs_off (
unsigned long reg)
256 off = unw.pt_regs_offsets[
reg];
259 UNW_DPRINT(0,
"unwind.%s: bad scratch reg r%lu\n", __func__, reg);
262 return (
unsigned long) off;
270 UNW_DPRINT(0,
"unwind.%s: bad unwind info: resetting info->pt\n", __func__);
274 info->
pt = info->
sp - 16;
276 UNW_DPRINT(3,
"unwind.%s: sp 0x%lx pt 0x%lx\n", __func__, info->
sp, info->
pt);
285 unsigned long *
addr, *nat_addr, nat_mask = 0, dummy_nat;
286 struct unw_ireg *ireg;
289 if ((
unsigned) regnum - 1 >= 127) {
290 if (regnum == 0 && !write) {
295 UNW_DPRINT(0,
"unwind.%s: trying to access non-existent r%u\n",
301 if (regnum >= 4 && regnum <= 7) {
303 ireg = &info->
r4 + (regnum - 4);
306 nat_addr = addr + ireg->nat.off;
307 switch (ireg->nat.type) {
319 if (addr[0] == 0 && addr[1] == 0x1ffe) {
329 nat_addr = &dummy_nat;
333 nat_mask = (1
UL << ((
long) addr & 0x1f8)/8);
337 nat_addr = ia64_rse_rnat_addr(addr);
338 if ((
unsigned long) addr < info->regstk.limit
339 || (
unsigned long) addr >= info->
regstk.top)
341 UNW_DPRINT(0,
"unwind.%s: %p outside of regstk "
343 __func__, (
void *) addr,
348 if ((
unsigned long) nat_addr >= info->
regstk.top)
349 nat_addr = &info->
sw->ar_rnat;
350 nat_mask = (1
UL << ia64_rse_slot_num(addr));
354 addr = &info->
sw->r4 + (regnum - 4);
355 nat_addr = &info->
sw->ar_unat;
356 nat_mask = (1
UL << ((
long) addr & 0x1f8)/8);
360 pt = get_scratch_regs(info);
361 addr = (
unsigned long *) ((
unsigned long)pt + pt_regs_off(regnum));
365 nat_addr = &info->
sw->caller_unat;
366 nat_mask = (1
UL << ((
long) addr & 0x1f8)/8);
370 addr = ia64_rse_skip_regs((
unsigned long *) info->
bsp, regnum - 32);
371 nat_addr = ia64_rse_rnat_addr(addr);
372 if ((
unsigned long) addr < info->regstk.limit
373 || (
unsigned long) addr >= info->
regstk.top)
375 UNW_DPRINT(0,
"unwind.%s: ignoring attempt to access register outside "
376 "of rbs\n", __func__);
379 if ((
unsigned long) nat_addr >= info->
regstk.top)
380 nat_addr = &info->
sw->ar_rnat;
381 nat_mask = (1
UL << ia64_rse_slot_num(addr));
386 UNW_DPRINT(0,
"unwind.%s: ignoring attempt to write read-only location\n",
391 *nat_addr |= nat_mask;
393 *nat_addr &= ~nat_mask;
396 if ((*nat_addr & nat_mask) == 0) {
416 case 0: pt = get_scratch_regs(info); addr = &pt->
b0;
break;
417 case 6: pt = get_scratch_regs(info); addr = &pt->
b6;
break;
418 case 7: pt = get_scratch_regs(info); addr = &pt->
b7;
break;
421 case 1:
case 2:
case 3:
case 4:
case 5:
422 addr = *(&info->
b1_loc + (regnum - 1));
424 addr = &info->
sw->b1 + (regnum - 1);
428 UNW_DPRINT(0,
"unwind.%s: trying to access non-existent b%u\n",
434 UNW_DPRINT(0,
"unwind.%s: ignoring attempt to write read-only location\n",
450 if ((
unsigned) (regnum - 2) >= 126) {
451 UNW_DPRINT(0,
"unwind.%s: trying to access non-existent f%u\n",
457 addr = *(&info->
f2_loc + (regnum - 2));
459 addr = &info->
sw->f2 + (regnum - 2);
460 }
else if (regnum <= 15) {
462 pt = get_scratch_regs(info);
463 addr = &pt->
f6 + (regnum - 6);
466 addr = &info->
sw->f12 + (regnum - 12);
467 }
else if (regnum <= 31) {
468 addr = info->
fr_loc[regnum - 16];
470 addr = &info->
sw->f16 + (regnum - 16);
478 addr = t->
thread.fph + (regnum - 32);
483 UNW_DPRINT(0,
"unwind.%s: ignoring attempt to write read-only location\n",
503 addr = &info->
sw->ar_bspstore;
509 addr = &info->
sw->ar_bspstore;
515 addr = &info->
sw->ar_pfs;
521 addr = &info->
sw->ar_rnat;
527 addr = &info->
sw->caller_unat;
533 addr = &info->
sw->ar_lc;
541 (*info->
cfm_loc & ~(0x3f
UL << 52)) | ((*val & 0x3f) << 52);
543 *val = (*info->
cfm_loc >> 52) & 0x3f;
549 addr = &info->
sw->ar_fpsr;
553 pt = get_scratch_regs(info);
558 pt = get_scratch_regs(info);
563 pt = get_scratch_regs(info);
568 pt = get_scratch_regs(info);
573 UNW_DPRINT(0,
"unwind.%s: trying to access non-existent ar%u\n",
580 UNW_DPRINT(0,
"unwind.%s: ignoring attempt to write read-only location\n",
597 addr = &info->
sw->pr;
601 UNW_DPRINT(0,
"unwind.%s: ignoring attempt to write read-only location\n",
653 memcpy(copy, rs,
sizeof(*copy));
670 for (p = rs->
next; p !=
NULL; p = next) {
680 decode_abreg (
unsigned char abreg,
int memory)
683 case 0x04 ... 0x07:
return UNW_REG_R4 + (abreg - 0x04);
684 case 0x22 ... 0x25:
return UNW_REG_F2 + (abreg - 0x22);
685 case 0x30 ... 0x3f:
return UNW_REG_F16 + (abreg - 0x30);
686 case 0x41 ... 0x45:
return UNW_REG_B1 + (abreg - 0x41);
701 UNW_DPRINT(0,
"unwind.%s: bad abreg=0x%x\n", __func__, abreg);
715 alloc_spill_area (
unsigned long *offp,
unsigned long regsize,
720 for (reg = hi; reg >= lo; --
reg) {
734 for (reg = *regp; reg <= lim; ++
reg) {
741 UNW_DPRINT(0,
"unwind.%s: excess spill!\n", __func__);
756 reg = sr->
curr.reg + unw.save_order[
i];
772 static const unsigned char limit[3] = {
784 kind = (mask >> 2*(3-(t & 3))) & 3;
786 spill_next_when(®s[kind - 1], sr->
curr.reg + limit[kind - 1],
806 desc_prologue (
int body,
unw_word rlen,
unsigned char mask,
unsigned char grsave,
835 for (i = 0; i < 4; ++
i) {
855 if (abi == 3 && context ==
'i') {
857 UNW_DPRINT(3,
"unwind.%s: interrupt frame\n", __func__);
860 UNW_DPRINT(0,
"unwind%s: ignoring unwabi(abi=0x%x,context=0x%x)\n",
861 __func__, abi, context);
869 for (i = 0; i < 5; ++
i) {
882 for (i = 0; i < 5; ++
i) {
897 for (i = 0; i < 4; ++
i) {
898 if ((grmask & 1) != 0) {
905 for (i = 0; i < 20; ++
i) {
906 if ((frmask & 1) != 0) {
921 for (i = 0; i < 4; ++
i) {
922 if ((frmask & 1) != 0) {
932 desc_gr_gr (
unsigned char grmask,
unsigned char gr,
struct unw_state_record *sr)
936 for (i = 0; i < 4; ++
i) {
937 if ((grmask & 1) != 0)
949 for (i = 0; i < 4; ++
i) {
950 if ((grmask & 1) != 0) {
1014 static inline unsigned char *
1037 if (ls->
label == label) {
1038 free_state_stack(&sr->
curr);
1044 printk(
KERN_ERR "unwind: failed to find state labeled 0x%lx\n", label);
1076 if ((sr->
pr_val & (1
UL << qp)) == 0)
1088 if (!desc_is_active(qp, t, sr))
1091 r = sr->
curr.reg + decode_abreg(abreg, 0);
1098 desc_spill_reg_p (
unsigned char qp,
unw_word t,
unsigned char abreg,
unsigned char x,
1104 if (!desc_is_active(qp, t, sr))
1109 else if (ytreg & 0x80)
1112 r = sr->
curr.reg + decode_abreg(abreg, 0);
1115 r->
val = (ytreg & 0x7f);
1119 desc_spill_psprel_p (
unsigned char qp,
unw_word t,
unsigned char abreg,
unw_word pspoff,
1124 if (!desc_is_active(qp, t, sr))
1127 r = sr->
curr.reg + decode_abreg(abreg, 1);
1130 r->
val = 0x10 - 4*pspoff;
1134 desc_spill_sprel_p (
unsigned char qp,
unw_word t,
unsigned char abreg,
unw_word spoff,
1139 if (!desc_is_active(qp, t, sr))
1142 r = sr->
curr.reg + decode_abreg(abreg, 1);
1148 #define UNW_DEC_BAD_CODE(code) printk(KERN_ERR "unwind: unknown code 0x%02x\n", \
1154 #define UNW_DEC_PROLOGUE_GR(fmt,r,m,gr,arg) desc_prologue(0,r,m,gr,arg)
1155 #define UNW_DEC_PROLOGUE(fmt,b,r,arg) desc_prologue(b,r,0,32,arg)
1159 #define UNW_DEC_ABI(fmt,a,c,arg) desc_abi(a,c,arg)
1160 #define UNW_DEC_BR_GR(fmt,b,g,arg) desc_br_gr(b,g,arg)
1161 #define UNW_DEC_BR_MEM(fmt,b,arg) desc_br_mem(b,arg)
1162 #define UNW_DEC_FRGR_MEM(fmt,g,f,arg) desc_frgr_mem(g,f,arg)
1163 #define UNW_DEC_FR_MEM(fmt,f,arg) desc_fr_mem(f,arg)
1164 #define UNW_DEC_GR_GR(fmt,m,g,arg) desc_gr_gr(m,g,arg)
1165 #define UNW_DEC_GR_MEM(fmt,m,arg) desc_gr_mem(m,arg)
1166 #define UNW_DEC_MEM_STACK_F(fmt,t,s,arg) desc_mem_stack_f(t,s,arg)
1167 #define UNW_DEC_MEM_STACK_V(fmt,t,arg) desc_mem_stack_v(t,arg)
1168 #define UNW_DEC_REG_GR(fmt,r,d,arg) desc_reg_gr(r,d,arg)
1169 #define UNW_DEC_REG_PSPREL(fmt,r,o,arg) desc_reg_psprel(r,o,arg)
1170 #define UNW_DEC_REG_SPREL(fmt,r,o,arg) desc_reg_sprel(r,o,arg)
1171 #define UNW_DEC_REG_WHEN(fmt,r,t,arg) desc_reg_when(r,t,arg)
1172 #define UNW_DEC_PRIUNAT_WHEN_GR(fmt,t,arg) desc_reg_when(UNW_REG_PRI_UNAT_GR,t,arg)
1173 #define UNW_DEC_PRIUNAT_WHEN_MEM(fmt,t,arg) desc_reg_when(UNW_REG_PRI_UNAT_MEM,t,arg)
1174 #define UNW_DEC_PRIUNAT_GR(fmt,r,arg) desc_reg_gr(UNW_REG_PRI_UNAT_GR,r,arg)
1175 #define UNW_DEC_PRIUNAT_PSPREL(fmt,o,arg) desc_reg_psprel(UNW_REG_PRI_UNAT_MEM,o,arg)
1176 #define UNW_DEC_PRIUNAT_SPREL(fmt,o,arg) desc_reg_sprel(UNW_REG_PRI_UNAT_MEM,o,arg)
1177 #define UNW_DEC_RP_BR(fmt,d,arg) desc_rp_br(d,arg)
1178 #define UNW_DEC_SPILL_BASE(fmt,o,arg) desc_spill_base(o,arg)
1179 #define UNW_DEC_SPILL_MASK(fmt,m,arg) (m = desc_spill_mask(m,arg))
1183 #define UNW_DEC_EPILOGUE(fmt,t,c,arg) desc_epilogue(t,c,arg)
1184 #define UNW_DEC_COPY_STATE(fmt,l,arg) desc_copy_state(l,arg)
1185 #define UNW_DEC_LABEL_STATE(fmt,l,arg) desc_label_state(l,arg)
1189 #define UNW_DEC_SPILL_REG_P(f,p,t,a,x,y,arg) desc_spill_reg_p(p,t,a,x,y,arg)
1190 #define UNW_DEC_SPILL_REG(f,t,a,x,y,arg) desc_spill_reg_p(0,t,a,x,y,arg)
1191 #define UNW_DEC_SPILL_PSPREL_P(f,p,t,a,o,arg) desc_spill_psprel_p(p,t,a,o,arg)
1192 #define UNW_DEC_SPILL_PSPREL(f,t,a,o,arg) desc_spill_psprel_p(0,t,a,o,arg)
1193 #define UNW_DEC_SPILL_SPREL_P(f,p,t,a,o,arg) desc_spill_sprel_p(p,t,a,o,arg)
1194 #define UNW_DEC_SPILL_SPREL(f,t,a,o,arg) desc_spill_sprel_p(0,t,a,o,arg)
1195 #define UNW_DEC_RESTORE_P(f,p,t,a,arg) desc_restore_p(p,t,a,arg)
1196 #define UNW_DEC_RESTORE(f,t,a,arg) desc_restore_p(0,t,a,arg)
1207 static const unsigned long hashmagic = 0x9e3779b97f4a7c16
UL;
1216 if (ip == script->
ip && ((pr ^ script->
pr_val) & script->
pr_mask) == 0)
1227 unsigned short index;
1228 unsigned long ip,
pr;
1233 STAT(++unw.stat.cache.lookups);
1238 if (cache_match(script, ip, pr)) {
1239 STAT(++unw.stat.cache.hinted_hits);
1243 index = unw.hash[
hash(ip)];
1247 script = unw.cache +
index;
1249 if (cache_match(script, ip, pr)) {
1251 STAT(++unw.stat.cache.normal_hits);
1252 unw.cache[info->
prev_script].hint = script - unw.cache;
1258 STAT(++unw.stat.cache.collision_chain_traversals);
1266 script_new (
unsigned long ip)
1270 unsigned short head;
1272 STAT(++unw.stat.script.news);
1278 head = unw.lru_head;
1279 script = unw.cache +
head;
1292 unw.cache[unw.lru_tail].lru_chain =
head;
1293 unw.lru_tail =
head;
1297 index =
hash(script->
ip);
1298 tmp = unw.cache + unw.hash[
index];
1301 if (tmp == script) {
1319 unw.hash[
index] = script - unw.cache;
1348 UNW_DPRINT(0,
"unwind.%s: script exceeds maximum size of %u instructions!\n",
1361 unsigned long val = 0;
1390 UNW_DPRINT(0,
"unwind.%s: don't know how to emit nat info for where = %u\n",
1391 __func__, r->
where);
1395 insn.
dst = unw.preg_index[
i];
1397 script_emit(script, insn);
1405 unsigned long val, rval;
1413 val = rval = r->
val;
1421 }
else if (rval >= 4 && rval <= 7) {
1422 if (need_nat_info) {
1426 val = unw.preg_index[
UNW_REG_R4 + (rval - 4)];
1427 }
else if (rval == 0) {
1433 val = pt_regs_off(rval);
1439 val = unw.preg_index[
UNW_REG_F2 + (rval - 2)];
1440 else if (rval >= 16 && rval <= 31)
1447 UNW_DPRINT(0,
"unwind.%s: kernel may not touch f%lu\n",
1453 if (rval >= 1 && rval <= 5)
1454 val = unw.preg_index[
UNW_REG_B1 + (rval - 1)];
1475 UNW_DPRINT(0,
"unwind%s: register %u has unexpected `where' value of %u\n",
1476 __func__, i, r->
where);
1480 insn.
dst = unw.preg_index[
i];
1482 script_emit(script, insn);
1484 emit_nat_info(sr, i, script);
1495 script_emit(script, insn);
1503 unsigned long lo, hi,
mid;
1506 for (lo = 0, hi = table->
length; lo < hi; ) {
1507 mid = (lo + hi) / 2;
1516 if (rel_ip < e->start_offset || rel_ip >= e->
end_offset)
1531 unsigned long ip = info->
ip;
1541 STAT(++unw.stat.script.builds; start = ia64_get_itc());
1544 memset(&sr, 0,
sizeof(sr));
1549 UNW_DPRINT(3,
"unwind.%s: ip 0x%lx\n", __func__, ip);
1550 script = script_new(ip);
1552 UNW_DPRINT(0,
"unwind.%s: failed to create unwind script\n", __func__);
1553 STAT(unw.stat.script.build_time += ia64_get_itc() - start);
1556 unw.cache[info->
prev_script].hint = script - unw.cache;
1560 STAT(parse_start = ia64_get_itc());
1563 for (table = unw.tables; table; table = table->
next) {
1564 if (ip >= table->
start && ip < table->
end) {
1572 if (prev && prev != unw.tables) {
1575 table->
next = unw.tables->next;
1576 unw.tables->next =
table;
1585 UNW_DPRINT(1,
"unwind.%s: no unwind info for ip=0x%lx (prev ip=0x%lx)\n",
1591 script_finalize(script, &sr);
1592 STAT(unw.stat.script.parse_time += ia64_get_itc() - parse_start);
1593 STAT(unw.stat.script.build_time += ia64_get_itc() - start);
1603 while (!sr.
done && dp < desc_end)
1604 dp = unw_decode(dp, sr.
in_body, &sr);
1634 UNW_DPRINT(1,
"unwind.%s: using default for rp at ip=0x%lx where=%d val=0x%lx\n",
1640 UNW_DPRINT(1,
"unwind.%s: state record for func 0x%lx, t=%u:\n",
1664 STAT(unw.stat.script.parse_time += ia64_get_itc() - parse_start);
1679 script_emit(script, insn);
1692 compile_reg(&sr, i, script);
1695 compile_reg(&sr, i, script);
1699 STAT(parse_start = ia64_get_itc());
1705 free_state_stack(&sr.
curr);
1706 STAT(unw.stat.script.parse_time += ia64_get_itc() - parse_start);
1708 script_finalize(script, &sr);
1709 STAT(unw.stat.script.build_time += ia64_get_itc() - start);
1723 unsigned long *
s = (
unsigned long *) state;
1724 STAT(
unsigned long start;)
1726 STAT(++unw.stat.script.runs; start = ia64_get_itc());
1732 while (ip++ < limit) {
1733 opc = next_insn.
opc;
1734 dst = next_insn.
dst;
1735 val = next_insn.
val;
1747 s[dst+1] = s[val+1];
1759 s[
dst] = (
unsigned long) get_scratch_regs(state) +
val;
1762 UNW_DPRINT(0,
"unwind.%s: no state->pt, dst=%ld, val=%ld\n",
1763 __func__, dst, val);
1769 s[
dst] = (
unsigned long) &unw.r0;
1772 UNW_DPRINT(0,
"unwind.%s: UNW_INSN_MOVE_CONST bad val=%ld\n",
1779 s[
dst] = (
unsigned long) ia64_rse_skip_regs((
unsigned long *)state->
bsp,
1807 UNW_DPRINT(0,
"unwind.%s: rejecting bad psp=0x%lx\n",
1812 s[
dst] = *(
unsigned long *) s[val];
1816 STAT(unw.stat.script.run_time += ia64_get_itc() - start);
1820 off = unw.sw_off[
val];
1821 s[
val] = (
unsigned long) state->
sw + off;
1835 int have_write_lock = 0;
1837 unsigned long flags = 0;
1842 UNW_DPRINT(1,
"unwind.%s: rejecting bad ip=0x%lx\n", __func__, info->
ip);
1847 scr = script_lookup(info);
1850 scr = build_script(info);
1852 spin_unlock_irqrestore(&unw.lock, flags);
1854 "unwind.%s: failed to locate/build unwind script for ip %lx\n",
1855 __func__, info->
ip);
1858 have_write_lock = 1;
1863 run_script(scr, info);
1865 if (have_write_lock) {
1867 spin_unlock_irqrestore(&unw.lock, flags);
1876 unsigned long loc = (
unsigned long)p;
1877 return (loc >= info->
regstk.limit && loc < info->regstk.top) ||
1884 unsigned long prev_ip, prev_sp, prev_bsp;
1885 unsigned long ip,
pr, num_regs;
1886 STAT(
unsigned long start, flags;)
1893 prev_bsp = info->
bsp;
1896 if (!unw_valid(info, info->
rp_loc)) {
1898 UNW_DPRINT(1,
"unwind.%s: failed to locate return link (ip=0x%lx)!\n",
1899 __func__, info->
ip);
1906 UNW_DPRINT(2,
"unwind.%s: reached user-space (ip=0x%lx)\n", __func__, ip);
1912 if (!unw_valid(info, info->
pfs_loc)) {
1913 UNW_DPRINT(0,
"unwind.%s: failed to locate ar.pfs!\n", __func__);
1924 info->
pt = info->
sp + 16;
1926 num_regs = *info->
cfm_loc & 0x7f;
1929 UNW_DPRINT(3,
"unwind.%s: interrupt_frame pt 0x%lx\n", __func__, info->
pt);
1931 num_regs = (*info->
cfm_loc >> 7) & 0x7f;
1932 info->
bsp = (
unsigned long) ia64_rse_skip_regs((
unsigned long *) info->
bsp, -num_regs);
1934 UNW_DPRINT(0,
"unwind.%s: bsp (0x%lx) out of range [0x%lx-0x%lx]\n",
1941 info->
sp = info->
psp;
1943 UNW_DPRINT(0,
"unwind.%s: sp (0x%lx) out of range [0x%lx-0x%lx]\n",
1949 if (info->
ip == prev_ip && info->
sp == prev_sp && info->
bsp == prev_bsp) {
1950 UNW_DPRINT(0,
"unwind.%s: ip, sp, bsp unchanged; stopping here (ip=0x%lx)\n",
1962 retval = find_save_locs(info);
1971 unsigned long ip,
sp, pr = info->
pr;
1974 unw_get_sp(info, &sp);
1976 < IA64_PT_REGS_SIZE) {
1977 UNW_DPRINT(0,
"unwind.%s: ran off the top of the kernel stack\n",
1985 unw_get_rp(info, &ip);
1987 "predicate register (ip=0x%lx)\n",
1992 unw_get_ip(info, &ip);
1993 UNW_DPRINT(0,
"unwind.%s: failed to unwind to user-level (ip=0x%lx)\n",
2003 unsigned long rbslimit, rbstop, stklimit;
2004 STAT(
unsigned long start, flags;)
2016 memset(info, 0,
sizeof(*info));
2022 if (rbstop > stklimit || rbstop < rbslimit)
2025 if (stktop <= rbstop)
2027 if (stktop > stklimit)
2030 info->
regstk.limit = rbslimit;
2031 info->
regstk.top = rbstop;
2032 info->
memstk.limit = stklimit;
2033 info->
memstk.top = stktop;
2036 info->
sp = info->
psp = stktop;
2040 " rbs = [0x%lx-0x%lx)\n"
2041 " stk = [0x%lx-0x%lx)\n"
2045 __func__, (
unsigned long) t, rbslimit, rbstop, stktop, stklimit,
2046 info->
pr, (
unsigned long) info->
sw, info->
sp);
2055 init_frame_info(info, t, sw, (
unsigned long) (sw + 1) - 16);
2057 sol = (*info->
cfm_loc >> 7) & 0x7f;
2058 info->
bsp = (
unsigned long) ia64_rse_skip_regs((
unsigned long *) info->
regstk.top, -sol);
2064 __func__, info->
bsp, sol, info->
ip);
2065 find_save_locs(info);
2081 init_unwind_table (
struct unw_table *table,
const char *
name,
unsigned long segment_base,
2082 unsigned long gp,
const void *table_start,
const void *table_end)
2090 table->
end = segment_base + end[-1].end_offset;
2097 const void *table_start,
const void *table_end)
2101 unsigned long flags;
2103 if (end - start <= 0) {
2104 UNW_DPRINT(0,
"unwind.%s: ignoring attempt to insert empty unwind table\n",
2113 init_unwind_table(table, name, segment_base, gp, table_start, table_end);
2118 table->
next = unw.tables->next;
2119 unw.tables->next =
table;
2121 spin_unlock_irqrestore(&unw.lock, flags);
2131 unsigned long flags;
2135 UNW_DPRINT(0,
"unwind.%s: ignoring attempt to remove non-existent unwind table\n",
2141 if (table == &unw.kernel_table) {
2142 UNW_DPRINT(0,
"unwind.%s: sorry, freeing the kernel's unwind table is a "
2143 "no-can-do!\n", __func__);
2151 for (prev = (
struct unw_table *) &unw.tables; prev; prev = prev->
next)
2152 if (prev->
next == table)
2155 UNW_DPRINT(0,
"unwind.%s: failed to find unwind table %p\n",
2156 __func__, (
void *) table);
2157 spin_unlock_irqrestore(&unw.lock, flags);
2162 spin_unlock_irqrestore(&unw.lock, flags);
2167 tmp = unw.cache + unw.hash[
index];
2186 create_gate_table (
void)
2190 size_t info_size,
size;
2195 for (i = 0; i <
GATE_EHDR->e_phnum; ++
i, ++phdr)
2202 printk(
"%s: failed to find gate DSO's unwind table!\n", __func__);
2212 for (entry = start; entry <
end; ++
entry)
2217 if (!unw.gate_table) {
2218 unw.gate_table_size = 0;
2219 printk(
KERN_ERR "%s: unable to create unwind data for gate page!\n", __func__);
2222 unw.gate_table_size =
size;
2224 lp = unw.gate_table;
2225 info = (
char *) unw.gate_table + size;
2227 for (entry = start; entry <
end; ++
entry, lp += 3) {
2234 lp[2] = info - (
char *) unw.gate_table;
2246 extern void unw_hash_index_t_is_too_narrow (
void);
2250 unw_hash_index_t_is_too_narrow();
2261 unw.sw_off[unw.preg_index[i]] = off;
2263 unw.sw_off[unw.preg_index[i]] = off;
2265 unw.sw_off[unw.preg_index[i]] = off;
2267 unw.sw_off[unw.preg_index[i]] = off;
2271 unw.cache[
i].lru_chain = (i - 1);
2272 unw.cache[
i].coll_chain = -1;
2275 unw.lru_head = UNW_CACHE_SIZE - 1;
2278 init_unwind_table(&unw.kernel_table,
"kernel",
KERNEL_START, (
unsigned long) __gp,
2315 if (buf && buf_size >= unw.gate_table_size)
2316 if (
copy_to_user(buf, unw.gate_table, unw.gate_table_size) != 0)
2318 return unw.gate_table_size;