2 * Kernel exception handling table support. Derived from arch/alpha/mm/extable.c.
4 * Copyright (C) 1998, 1999, 2001-2002, 2004 Hewlett-Packard Co
5 * David Mosberger-Tang <davidm@hpl.hp.com>
8 #include <linux/config.h>
9 #include <linux/sort.h>
11 #include <asm/uaccess.h>
12 #include <asm/module.h>
14 static int cmp_ex(const void *a
, const void *b
)
16 const struct exception_table_entry
*l
= a
, *r
= b
;
17 u64 lip
= (u64
) &l
->addr
+ l
->addr
;
18 u64 rip
= (u64
) &r
->addr
+ r
->addr
;
28 static void swap_ex(void *a
, void *b
, int size
)
30 struct exception_table_entry
*l
= a
, *r
= b
, tmp
;
31 u64 delta
= (u64
) r
- (u64
) l
;
34 l
->addr
= r
->addr
+ delta
;
35 l
->cont
= r
->cont
+ delta
;
36 r
->addr
= tmp
.addr
- delta
;
37 r
->cont
= tmp
.cont
- delta
;
41 * Sort the exception table. It's usually already sorted, but there
42 * may be unordered entries due to multiple text sections (such as the
43 * .init text section). Note that the exception-table-entries contain
44 * location-relative addresses, which requires a bit of care during
45 * sorting to avoid overflows in the offset members (e.g., it would
46 * not be safe to make a temporary copy of an exception-table entry on
47 * the stack, because the stack may be more than 2GB away from the
50 void sort_extable (struct exception_table_entry
*start
,
51 struct exception_table_entry
*finish
)
53 sort(start
, finish
- start
, sizeof(struct exception_table_entry
),
57 const struct exception_table_entry
*
58 search_extable (const struct exception_table_entry
*first
,
59 const struct exception_table_entry
*last
,
62 const struct exception_table_entry
*mid
;
66 while (first
<= last
) {
67 mid
= &first
[(last
- first
)/2];
68 mid_ip
= (u64
) &mid
->addr
+ mid
->addr
;
81 ia64_handle_exception (struct pt_regs
*regs
, const struct exception_table_entry
*e
)
83 long fix
= (u64
) &e
->cont
+ e
->cont
;
88 regs
->cr_iip
= fix
& ~0xf;
89 ia64_psr(regs
)->ri
= fix
& 0x3; /* set continuation slot number */