99 * 2 of the License, or (at your option) any later version.
1010 */
1111
12+ #include <linux/bsearch.h>
1213#include <linux/module.h>
1314#include <linux/init.h>
1415#include <linux/sort.h>
@@ -51,7 +52,7 @@ static void swap_ex(void *a, void *b, int size)
5152 * This is used both for the kernel exception table and for
5253 * the exception tables of modules that get loaded.
5354 */
54- static int cmp_ex (const void * a , const void * b )
55+ static int cmp_ex_sort (const void * a , const void * b )
5556{
5657 const struct exception_table_entry * x = a , * y = b ;
5758
@@ -67,7 +68,7 @@ void sort_extable(struct exception_table_entry *start,
6768 struct exception_table_entry * finish )
6869{
6970 sort (start , finish - start , sizeof (struct exception_table_entry ),
70- cmp_ex , swap_ex );
71+ cmp_ex_sort , swap_ex );
7172}
7273
7374#ifdef CONFIG_MODULES
@@ -93,6 +94,20 @@ void trim_init_extable(struct module *m)
9394#endif /* !ARCH_HAS_SORT_EXTABLE */
9495
9596#ifndef ARCH_HAS_SEARCH_EXTABLE
97+
98+ static int cmp_ex_search (const void * key , const void * elt )
99+ {
100+ const struct exception_table_entry * _elt = elt ;
101+ unsigned long k = * (unsigned long * ) key ;
102+
103+ /* avoid overflow */
104+ if (k > ex_to_insn (_elt ))
105+ return 1 ;
106+ if (k < ex_to_insn (_elt ))
107+ return -1 ;
108+ return 0 ;
109+ }
110+
96111/*
97112 * Search one exception table for an entry corresponding to the
98113 * given instruction address, and return the address of the entry,
@@ -102,24 +117,9 @@ void trim_init_extable(struct module *m)
102117 */
103118const struct exception_table_entry *
104119search_extable (const struct exception_table_entry * first ,
105- const struct exception_table_entry * last ,
120+ const size_t num ,
106121 unsigned long value )
107122{
108- while (first <= last ) {
109- const struct exception_table_entry * mid ;
110-
111- mid = ((last - first ) >> 1 ) + first ;
112- /*
113- * careful, the distance between value and insn
114- * can be larger than MAX_LONG:
115- */
116- if (ex_to_insn (mid ) < value )
117- first = mid + 1 ;
118- else if (ex_to_insn (mid ) > value )
119- last = mid - 1 ;
120- else
121- return mid ;
122- }
123- return NULL ;
123+ return bsearch (& value , first , num , sizeof (struct exception_table_entry ), cmp_ex_search );
124124}
125125#endif
0 commit comments