#include #include #include #include #include extern struct exception_table_entry __start___ex_table[]; extern struct exception_table_entry __stop___ex_table[]; extern struct exception_table_entry __start___pre_ex_table[]; extern struct exception_table_entry __stop___pre_ex_table[]; static void __init sort_exception_table(struct exception_table_entry *start, struct exception_table_entry *end) { struct exception_table_entry *p, *q, tmp; for ( p = start; p < end; p++ ) { for ( q = p-1; q > start; q-- ) if ( p->insn > q->insn ) break; if ( ++q != p ) { tmp = *p; memmove(q+1, q, (p-q)*sizeof(*p)); *q = tmp; } } } void __init sort_exception_tables(void) { sort_exception_table(__start___ex_table, __stop___ex_table); sort_exception_table(__start___pre_ex_table, __stop___pre_ex_table); } static inline unsigned long search_one_table(const struct exception_table_entry *first, const struct exception_table_entry *last, unsigned long value) { const struct exception_table_entry *mid; long diff; while ( first <= last ) { mid = (last - first) / 2 + first; diff = mid->insn - value; if (diff == 0) return mid->fixup; else if (diff < 0) first = mid+1; else last = mid-1; } return 0; } unsigned long search_exception_table(unsigned long addr) { return search_one_table( __start___ex_table, __stop___ex_table-1, addr); } unsigned long search_pre_exception_table(struct cpu_user_regs *regs) { unsigned long addr = (unsigned long)regs->eip; unsigned long fixup = search_one_table( __start___pre_ex_table, __stop___pre_ex_table-1, addr); if ( fixup ) { dprintk(XENLOG_INFO, "Pre-exception: %p -> %p\n", _p(addr), _p(fixup)); perfc_incr(exception_fixed); } return fixup; } action='/cgit/iCE40/nextpnr/log/3rdparty/googletest/googlemock/CONTRIBUTORS'>
blob: 6e9ae362b60c384c743cd654903ec287fb6a270c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40