#include "entry.h"
#include "unwind_i.h"
-#define p5 5
-
#define UNW_LOG_CACHE_SIZE 7 /* each unw_script is ~256 bytes in size */
#define UNW_CACHE_SIZE (1 << UNW_LOG_CACHE_SIZE)
num_regs = 0;
if ((info->flags & UNW_FLAG_INTERRUPT_FRAME)) {
info->pt = info->sp + 16;
- if ((pr & (1UL << pNonSys)) != 0)
+ if ((pr & (1UL << PRED_NON_SYSCALL)) != 0)
num_regs = *info->cfm_loc & 0x7f; /* size of frame */
info->pfs_loc =
(unsigned long *) (info->pt + offsetof(struct pt_regs, ar_pfs));
int
unw_unwind_to_user (struct unw_frame_info *info)
{
- unsigned long ip;
+ unsigned long ip, sp, pr = 0;
while (unw_unwind(info) >= 0) {
- if (unw_get_rp(info, &ip) < 0) {
- unw_get_ip(info, &ip);
- UNW_DPRINT(0, "unwind.%s: failed to read return pointer (ip=0x%lx)\n",
- __FUNCTION__, ip);
- return -1;
+ unw_get_sp(info, &sp);
+ if ((long)((unsigned long)info->task + IA64_STK_OFFSET - sp)
+ < IA64_PT_REGS_SIZE) {
+ UNW_DPRINT(0, "unwind.%s: ran off the top of the kernel stack\n",
+ __FUNCTION__);
+ break;
}
- if (ip < FIXADDR_USER_END)
+ if (unw_is_intr_frame(info) &&
+ (pr & (1UL << PRED_USER_STACK)))
return 0;
+ if (unw_get_pr (info, &pr) < 0) {
+ unw_get_rp(info, &ip);
+ UNW_DPRINT(0, "unwind.%s: failed to read "
+ "predicate register (ip=0x%lx)\n",
+ __FUNCTION__, ip);
+ return -1;
+ }
}
unw_get_ip(info, &ip);
- UNW_DPRINT(0, "unwind.%s: failed to unwind to user-level (ip=0x%lx)\n", __FUNCTION__, ip);
+ UNW_DPRINT(0, "unwind.%s: failed to unwind to user-level (ip=0x%lx)\n",
+ __FUNCTION__, ip);
return -1;
}
EXPORT_SYMBOL(unw_unwind_to_user);
find_save_locs(info);
}
+EXPORT_SYMBOL(unw_init_frame_info);
+
void
unw_init_from_blocked_task (struct unw_frame_info *info, struct task_struct *t)
{
if (i > 0)
unw.cache[i].lru_chain = (i - 1);
unw.cache[i].coll_chain = -1;
- unw.cache[i].lock = RW_LOCK_UNLOCKED;
+ rwlock_init(&unw.cache[i].lock);
}
unw.lru_head = UNW_CACHE_SIZE - 1;
unw.lru_tail = 0;