1 // SPDX-License-Identifier: GPL-2.0 << 2 /* 1 /* 3 * linux/arch/arm/mm/extable.c !! 2 * arch/ppc/mm/extable.c >> 3 * >> 4 * from arch/i386/mm/extable.c 4 */ 5 */ 5 #include <linux/extable.h> << 6 #include <linux/uaccess.h> << 7 6 8 int fixup_exception(struct pt_regs *regs) !! 7 #include <linux/config.h> >> 8 #include <linux/module.h> >> 9 #include <linux/init.h> >> 10 #include <asm/uaccess.h> >> 11 >> 12 extern struct exception_table_entry __start___ex_table[]; >> 13 extern struct exception_table_entry __stop___ex_table[]; >> 14 >> 15 /* >> 16 * The exception table needs to be sorted because we use the macros >> 17 * which put things into the exception table in a variety of segments >> 18 * such as the prep, pmac, chrp, etc. segments as well as the init >> 19 * segment and the main kernel text segment. >> 20 */ >> 21 static inline void >> 22 sort_ex_table(struct exception_table_entry *start, >> 23 struct exception_table_entry *finish) 9 { 24 { 10 const struct exception_table_entry *fi !! 25 struct exception_table_entry el, *p, *q; 11 26 12 fixup = search_exception_tables(instru !! 27 /* insertion sort */ 13 if (fixup) { !! 28 for (p = start + 1; p < finish; ++p) { 14 regs->ARM_pc = fixup->fixup; !! 29 /* start .. p-1 is sorted */ 15 #ifdef CONFIG_THUMB2_KERNEL !! 30 if (p[0].insn < p[-1].insn) { 16 /* Clear the IT state to avoid !! 31 /* move element p down to its right place */ 17 regs->ARM_cpsr &= ~PSR_IT_MASK !! 32 el = *p; 18 #endif !! 33 q = p; >> 34 do { >> 35 /* el comes before q[-1], move q[-1] up one */ >> 36 q[0] = q[-1]; >> 37 --q; >> 38 } while (q > start && el.insn < q[-1].insn); >> 39 *q = el; >> 40 } 19 } 41 } >> 42 } >> 43 >> 44 void __init >> 45 sort_exception_table(void) >> 46 { >> 47 sort_ex_table(__start___ex_table, __stop___ex_table); >> 48 } >> 49 >> 50 /* Simple binary search */ >> 51 const struct exception_table_entry * >> 52 search_extable(const struct exception_table_entry *first, >> 53 const struct exception_table_entry *last, >> 54 unsigned long value) >> 55 { >> 56 while (first <= last) { >> 57 const struct exception_table_entry *mid; >> 58 long diff; 20 59 21 return fixup != NULL; !! 60 mid = (last - first) / 2 + first; >> 61 diff = mid->insn - value; >> 62 if (diff == 0) >> 63 return mid; >> 64 else if (diff < 0) >> 65 first = mid+1; >> 66 else >> 67 last = mid-1; >> 68 } >> 69 return NULL; 22 } 70 } 23 71
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.