ia64/xen-unstable

view xen/arch/x86/extable.c @ 14054:43e9952b07ea

x86: Better BUG() and ASSERT() logging.
Signed-off-by: Keir Fraser <keir@xensource.com>
author kfraser@localhost.localdomain
date Wed Feb 21 14:40:37 2007 +0000 (2007-02-21)
parents 36679b74e24a
children ea0b50ca4999
line source
2 #include <xen/config.h>
3 #include <xen/perfc.h>
4 #include <xen/spinlock.h>
5 #include <asm/uaccess.h>
7 extern struct exception_table_entry __start___ex_table[];
8 extern struct exception_table_entry __stop___ex_table[];
9 extern struct exception_table_entry __start___pre_ex_table[];
10 extern struct exception_table_entry __stop___pre_ex_table[];
12 static void sort_exception_table(struct exception_table_entry *start,
13 struct exception_table_entry *end)
14 {
15 struct exception_table_entry *p, *q, tmp;
17 for ( p = start; p < end; p++ )
18 {
19 for ( q = p-1; q > start; q-- )
20 if ( p->insn > q->insn )
21 break;
22 if ( ++q != p )
23 {
24 tmp = *p;
25 memmove(q+1, q, (p-q)*sizeof(*p));
26 *q = tmp;
27 }
28 }
29 }
31 void sort_exception_tables(void)
32 {
33 sort_exception_table(__start___ex_table, __stop___ex_table);
34 sort_exception_table(__start___pre_ex_table, __stop___pre_ex_table);
35 }
37 static inline unsigned long
38 search_one_table(const struct exception_table_entry *first,
39 const struct exception_table_entry *last,
40 unsigned long value)
41 {
42 const struct exception_table_entry *mid;
43 long diff;
45 while ( first <= last )
46 {
47 mid = (last - first) / 2 + first;
48 diff = mid->insn - value;
49 if (diff == 0)
50 return mid->fixup;
51 else if (diff < 0)
52 first = mid+1;
53 else
54 last = mid-1;
55 }
56 return 0;
57 }
59 unsigned long
60 search_exception_table(unsigned long addr)
61 {
62 return search_one_table(
63 __start___ex_table, __stop___ex_table-1, addr);
64 }
66 unsigned long
67 search_pre_exception_table(struct cpu_user_regs *regs)
68 {
69 unsigned long addr = (unsigned long)regs->eip;
70 unsigned long fixup = search_one_table(
71 __start___pre_ex_table, __stop___pre_ex_table-1, addr);
72 if ( fixup )
73 {
74 dprintk(XENLOG_INFO, "Pre-exception: %p -> %p\n", _p(addr), _p(fixup));
75 perfc_incrc(exception_fixed);
76 }
77 return fixup;
78 }