linux/arch/sparc/mm/extable.c
<<
>>
Prefs
   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