|
@@ -28,6 +28,10 @@ search_extable(const struct exception_table_entry *start,
|
|
|
* word 3: last insn address + 4 bytes
|
|
|
* word 4: fixup code address
|
|
|
*
|
|
|
+ * Deleted entries are encoded as:
|
|
|
+ * word 1: unused
|
|
|
+ * word 2: -1
|
|
|
+ *
|
|
|
* See asm/uaccess.h for more details.
|
|
|
*/
|
|
|
|
|
@@ -39,6 +43,10 @@ search_extable(const struct exception_table_entry *start,
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
+ /* A deleted entry; see trim_init_extable */
|
|
|
+ if (walk->fixup == -1)
|
|
|
+ continue;
|
|
|
+
|
|
|
if (walk->insn == value)
|
|
|
return walk;
|
|
|
}
|
|
@@ -57,6 +65,27 @@ search_extable(const struct exception_table_entry *start,
|
|
|
return NULL;
|
|
|
}
|
|
|
|
|
|
+#ifdef CONFIG_MODULES
|
|
|
+/* We could memmove them around; easier to mark the trimmed ones. */
|
|
|
+void trim_init_extable(struct module *m)
|
|
|
+{
|
|
|
+ unsigned int i;
|
|
|
+ bool range;
|
|
|
+
|
|
|
+ for (i = 0; i < m->num_exentries; i += range ? 2 : 1) {
|
|
|
+ range = m->extable[i].fixup == 0;
|
|
|
+
|
|
|
+ if (within_module_init(m->extable[i].insn, m)) {
|
|
|
+ m->extable[i].fixup = -1;
|
|
|
+ if (range)
|
|
|
+ m->extable[i+1].fixup = -1;
|
|
|
+ }
|
|
|
+ if (range)
|
|
|
+ i++;
|
|
|
+ }
|
|
|
+}
|
|
|
+#endif /* CONFIG_MODULES */
|
|
|
+
|
|
|
/* Special extable search, which handles ranges. Returns fixup */
|
|
|
unsigned long search_extables_range(unsigned long addr, unsigned long *g2)
|
|
|
{
|