diff options
Diffstat (limited to 'arch/sparc/mm/extable.c')
| -rw-r--r-- | arch/sparc/mm/extable.c | 29 | 
1 files changed, 29 insertions, 0 deletions
diff --git a/arch/sparc/mm/extable.c b/arch/sparc/mm/extable.c index 16cc28935e3..a61c349448e 100644 --- a/arch/sparc/mm/extable.c +++ b/arch/sparc/mm/extable.c @@ -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)  {  |