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/sort.h>
10 #include <asm/uaccess.h>
11 #include <asm/module.h>
13 static int cmp_ex(const void *a
, const void *b
)
15 const struct exception_table_entry
*l
= a
, *r
= b
;
16 u64 lip
= (u64
) &l
->addr
+ l
->addr
;
17 u64 rip
= (u64
) &r
->addr
+ r
->addr
;
27 static void swap_ex(void *a
, void *b
, int size
)
29 struct exception_table_entry
*l
= a
, *r
= b
, tmp
;
30 u64 delta
= (u64
) r
- (u64
) l
;
33 l
->addr
= r
->addr
+ delta
;
34 l
->cont
= r
->cont
+ delta
;
35 r
->addr
= tmp
.addr
- delta
;
36 r
->cont
= tmp
.cont
- delta
;
40 * Sort the exception table. It's usually already sorted, but there
41 * may be unordered entries due to multiple text sections (such as the
42 * .init text section). Note that the exception-table-entries contain
43 * location-relative addresses, which requires a bit of care during
44 * sorting to avoid overflows in the offset members (e.g., it would
45 * not be safe to make a temporary copy of an exception-table entry on
46 * the stack, because the stack may be more than 2GB away from the
49 void sort_extable (struct exception_table_entry
*start
,
50 struct exception_table_entry
*finish
)
52 sort(start
, finish
- start
, sizeof(struct exception_table_entry
),
56 const struct exception_table_entry
*
57 search_extable (const struct exception_table_entry
*first
,
58 const struct exception_table_entry
*last
,
61 const struct exception_table_entry
*mid
;
65 while (first
<= last
) {
66 mid
= &first
[(last
- first
)/2];
67 mid_ip
= (u64
) &mid
->addr
+ mid
->addr
;
80 ia64_handle_exception (struct pt_regs
*regs
, const struct exception_table_entry
*e
)
82 long fix
= (u64
) &e
->cont
+ e
->cont
;
87 regs
->cr_iip
= fix
& ~0xf;
88 ia64_psr(regs
)->ri
= fix
& 0x3; /* set continuation slot number */