module: trim exception table on init free.
[sfrench/cifs-2.6.git] / lib / extable.c
index 463f4560f16da1e6d03394b46d8e0763948501f7..4cac81ec225e09af4cfd69c36d63a574a8418110 100644 (file)
@@ -39,7 +39,26 @@ void sort_extable(struct exception_table_entry *start,
        sort(start, finish - start, sizeof(struct exception_table_entry),
             cmp_ex, NULL);
 }
-#endif
+
+#ifdef CONFIG_MODULES
+/*
+ * If the exception table is sorted, any referring to the module init
+ * will be at the beginning or the end.
+ */
+void trim_init_extable(struct module *m)
+{
+       /*trim the beginning*/
+       while (m->num_exentries && within_module_init(m->extable[0].insn, m)) {
+               m->extable++;
+               m->num_exentries--;
+       }
+       /*trim the end*/
+       while (m->num_exentries &&
+               within_module_init(m->extable[m->num_exentries-1].insn, m))
+               m->num_exentries--;
+}
+#endif /* CONFIG_MODULES */
+#endif /* !ARCH_HAS_SORT_EXTABLE */
 
 #ifndef ARCH_HAS_SEARCH_EXTABLE
 /*
@@ -57,10 +76,10 @@ search_extable(const struct exception_table_entry *first,
        while (first <= last) {
                const struct exception_table_entry *mid;
 
-               mid = (last - first) / 2 + first;
+               mid = ((last - first) >> 1) + first;
                /*
-                * careful, the distance between entries can be
-                * larger than 2GB:
+                * careful, the distance between value and insn
+                * can be larger than MAX_LONG:
                 */
                if (mid->insn < value)
                        first = mid + 1;