1 /* 2 * Derived from arch/ppc/mm/extable.c and arch/i386/mm/extable.c. 3 * 4 * Copyright (C) 2004 Paul Mackerras, IBM Corp. 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License 8 * as published by the Free Software Foundation; either version 9 * 2 of the License, or (at your option) any later version. 10 */ 11 12 #include <linux/config.h> 13 #include <linux/module.h> 14 #include <linux/init.h> 15 #include <linux/sort.h> 16 #include <asm/uaccess.h> 17 18 #ifndef ARCH_HAS_SORT_EXTABLE 19 /* 20 * The exception table needs to be sorted so that the binary 21 * search that we use to find entries in it works properly. 22 * This is used both for the kernel exception table and for 23 * the exception tables of modules that get loaded. 24 */ 25 static int cmp_ex(const void *a, const void *b) 26 { 27 const struct exception_table_entry *x = a, *y = b; 28 29 /* avoid overflow */ 30 if (x->insn > y->insn) 31 return 1; 32 if (x->insn < y->insn) 33 return -1; 34 return 0; 35 } 36 37 void sort_extable(struct exception_table_entry *start, 38 struct exception_table_entry *finish) 39 { 40 sort(start, finish - start, sizeof(struct exception_table_entry), 41 cmp_ex, NULL); 42 } 43 #endif 44 45 #ifndef ARCH_HAS_SEARCH_EXTABLE 46 /* 47 * Search one exception table for an entry corresponding to the 48 * given instruction address, and return the address of the entry, 49 * or NULL if none is found. 50 * We use a binary search, and thus we assume that the table is 51 * already sorted. 52 */ 53 const struct exception_table_entry * 54 search_extable(const struct exception_table_entry *first, 55 const struct exception_table_entry *last, 56 unsigned long value) 57 { 58 while (first <= last) { 59 const struct exception_table_entry *mid; 60 61 mid = (last - first) / 2 + first; 62 /* 63 * careful, the distance between entries can be 64 * larger than 2GB: 65 */ 66 if (mid->insn < value) 67 first = mid + 1; 68 else if (mid->insn > value) 69 last = mid - 1; 70 else 71 return mid; 72 } 73 return NULL; 74 } 75 #endif 76