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