File: /usr/src/linux/arch/i386/mm/extable.c

1     /*
2      * linux/arch/i386/mm/extable.c
3      */
4     
5     #include <linux/config.h>
6     #include <linux/module.h>
7     #include <linux/spinlock.h>
8     #include <asm/uaccess.h>
9     
10     extern const struct exception_table_entry __start___ex_table[];
11     extern const struct exception_table_entry __stop___ex_table[];
12     
13     static inline unsigned long
14     search_one_table(const struct exception_table_entry *first,
15     		 const struct exception_table_entry *last,
16     		 unsigned long value)
17     {
18             while (first <= last) {
19     		const struct exception_table_entry *mid;
20     		long diff;
21     
22     		mid = (last - first) / 2 + first;
23     		diff = mid->insn - value;
24                     if (diff == 0)
25                             return mid->fixup;
26                     else if (diff < 0)
27                             first = mid+1;
28                     else
29                             last = mid-1;
30             }
31             return 0;
32     }
33     
34     extern spinlock_t modlist_lock;
35     
36     unsigned long
37     search_exception_table(unsigned long addr)
38     {
39     	unsigned long ret = 0;
40     	
41     #ifndef CONFIG_MODULES
42     	/* There is only the kernel to search.  */
43     	ret = search_one_table(__start___ex_table, __stop___ex_table-1, addr);
44     	return ret;
45     #else
46     	unsigned long flags;
47     	/* The kernel is the last "module" -- no need to treat it special.  */
48     	struct module *mp;
49     
50     	spin_lock_irqsave(&modlist_lock, flags);
51     	for (mp = module_list; mp != NULL; mp = mp->next) {
52     		if (mp->ex_table_start == NULL || !(mp->flags&(MOD_RUNNING|MOD_INITIALIZING)))
53     			continue;
54     		ret = search_one_table(mp->ex_table_start,
55     				       mp->ex_table_end - 1, addr);
56     		if (ret)
57     			break;
58     	}
59     	spin_unlock_irqrestore(&modlist_lock, flags);
60     	return ret;
61     #endif
62     }
63