1/* 2 * linux/arch/sparc/mm/extable.c 3 */ 4 5#include <linux/module.h> 6#include <asm/uaccess.h> 7 8void sort_extable(struct exception_table_entry *start, 9 struct exception_table_entry *finish) 10{ 11} 12 13/* Caller knows they are in a range if ret->fixup == 0 */ 14const struct exception_table_entry * 15search_extable(const struct exception_table_entry *start, 16 const struct exception_table_entry *last, 17 unsigned long value) 18{ 19 const struct exception_table_entry *walk; 20 21 /* Single insn entries are encoded as: 22 * word 1: insn address 23 * word 2: fixup code address 24 * 25 * Range entries are encoded as: 26 * word 1: first insn address 27 * word 2: 0 28 * word 3: last insn address + 4 bytes 29 * word 4: fixup code address 30 * 31 * See asm/uaccess.h for more details. 32 */ 33 34 /* 1. Try to find an exact match. */ 35 for (walk = start; walk <= last; walk++) { 36 if (walk->fixup == 0) { 37 /* A range entry, skip both parts. */ 38 walk++; 39 continue; 40 } 41 42 if (walk->insn == value) 43 return walk; 44 } 45 46 /* 2. Try to find a range match. */ 47 for (walk = start; walk <= (last - 1); walk++) { 48 if (walk->fixup) 49 continue; 50 51 if (walk[0].insn <= value && walk[1].insn > value) 52 return walk; 53 54 walk++; 55 } 56 57 return NULL; 58} 59 60/* Special extable search, which handles ranges. Returns fixup */ 61unsigned long search_extables_range(unsigned long addr, unsigned long *g2) 62{ 63 const struct exception_table_entry *entry; 64 65 entry = search_exception_tables(addr); 66 if (!entry) 67 return 0; 68 69 /* Inside range? Fix g2 and return correct fixup */ 70 if (!entry->fixup) { 71 *g2 = (addr - entry->insn) / 4; 72 return (entry + 1)->fixup; 73 } 74 75 return entry->fixup; 76} 77