patch-2.4.17 linux/arch/sparc/mm/extable.c
Next file: linux/arch/sparc/mm/fault.c
Previous file: linux/arch/sparc/kernel/smp.c
Back to the patch index
Back to the overall index
- Lines: 77
- Date:
Fri Dec 21 16:40:32 2001
- Orig file:
linux-2.4.16/arch/sparc/mm/extable.c
- Orig date:
Sun Aug 12 18:23:32 2001
diff -Naur -X /home/marcelo/lib/dontdiff linux-2.4.16/arch/sparc/mm/extable.c linux/arch/sparc/mm/extable.c
@@ -11,35 +11,49 @@
static unsigned long
search_one_table(const struct exception_table_entry *start,
- const struct exception_table_entry *last,
+ const struct exception_table_entry *end,
unsigned long value, unsigned long *g2)
{
- const struct exception_table_entry *first = start;
- const struct exception_table_entry *mid;
- long diff = 0;
- while (first <= last) {
- mid = (last - first) / 2 + first;
- diff = mid->insn - value;
- if (diff == 0) {
- if (!mid->fixup) {
- *g2 = 0;
- return (mid + 1)->fixup;
- } else
- return mid->fixup;
- } else if (diff < 0)
- first = mid+1;
- else
- last = mid-1;
- }
- if (last->insn < value && !last->fixup && last[1].insn > value) {
- *g2 = (value - last->insn)/4;
- return last[1].fixup;
- }
- if (first > start && first[-1].insn < value
- && !first[-1].fixup && first->insn < value) {
- *g2 = (value - first[-1].insn)/4;
- return first->fixup;
- }
+ const struct exception_table_entry *walk;
+
+ /* Single insn entries are encoded as:
+ * word 1: insn address
+ * word 2: fixup code address
+ *
+ * Range entries are encoded as:
+ * word 1: first insn address
+ * word 2: 0
+ * word 3: last insn address + 4 bytes
+ * word 4: fixup code address
+ *
+ * See asm/uaccess.h for more details.
+ */
+
+ /* 1. Try to find an exact match. */
+ for (walk = start; walk <= end; walk++) {
+ if (walk->fixup == 0) {
+ /* A range entry, skip both parts. */
+ walk++;
+ continue;
+ }
+
+ if (walk->insn == value)
+ return walk->fixup;
+ }
+
+ /* 2. Try to find a range match. */
+ for (walk = start; walk <= (end - 1); walk++) {
+ if (walk->fixup)
+ continue;
+
+ if (walk[0].insn <= value &&
+ walk[1].insn > value) {
+ *g2 = (value - walk[0].insn) / 4;
+ return walk[1].fixup;
+ }
+ walk++;
+ }
+
return 0;
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)