root/arch/sparc/mm/extable.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. sort_extable
  2. search_extable
  3. trim_init_extable
  4. search_extables_range

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  * linux/arch/sparc/mm/extable.c
   4  */
   5 
   6 #include <linux/module.h>
   7 #include <linux/extable.h>
   8 #include <linux/uaccess.h>
   9 
  10 void sort_extable(struct exception_table_entry *start,
  11                   struct exception_table_entry *finish)
  12 {
  13 }
  14 
  15 /* Caller knows they are in a range if ret->fixup == 0 */
  16 const struct exception_table_entry *
  17 search_extable(const struct exception_table_entry *base,
  18                const size_t num,
  19                unsigned long value)
  20 {
  21         int i;
  22 
  23         /* Single insn entries are encoded as:
  24          *      word 1: insn address
  25          *      word 2: fixup code address
  26          *
  27          * Range entries are encoded as:
  28          *      word 1: first insn address
  29          *      word 2: 0
  30          *      word 3: last insn address + 4 bytes
  31          *      word 4: fixup code address
  32          *
  33          * Deleted entries are encoded as:
  34          *      word 1: unused
  35          *      word 2: -1
  36          *
  37          * See asm/uaccess.h for more details.
  38          */
  39 
  40         /* 1. Try to find an exact match. */
  41         for (i = 0; i < num; i++) {
  42                 if (base[i].fixup == 0) {
  43                         /* A range entry, skip both parts. */
  44                         i++;
  45                         continue;
  46                 }
  47 
  48                 /* A deleted entry; see trim_init_extable */
  49                 if (base[i].fixup == -1)
  50                         continue;
  51 
  52                 if (base[i].insn == value)
  53                         return &base[i];
  54         }
  55 
  56         /* 2. Try to find a range match. */
  57         for (i = 0; i < (num - 1); i++) {
  58                 if (base[i].fixup)
  59                         continue;
  60 
  61                 if (base[i].insn <= value && base[i + 1].insn > value)
  62                         return &base[i];
  63 
  64                 i++;
  65         }
  66 
  67         return NULL;
  68 }
  69 
  70 #ifdef CONFIG_MODULES
  71 /* We could memmove them around; easier to mark the trimmed ones. */
  72 void trim_init_extable(struct module *m)
  73 {
  74         unsigned int i;
  75         bool range;
  76 
  77         for (i = 0; i < m->num_exentries; i += range ? 2 : 1) {
  78                 range = m->extable[i].fixup == 0;
  79 
  80                 if (within_module_init(m->extable[i].insn, m)) {
  81                         m->extable[i].fixup = -1;
  82                         if (range)
  83                                 m->extable[i+1].fixup = -1;
  84                 }
  85                 if (range)
  86                         i++;
  87         }
  88 }
  89 #endif /* CONFIG_MODULES */
  90 
  91 /* Special extable search, which handles ranges.  Returns fixup */
  92 unsigned long search_extables_range(unsigned long addr, unsigned long *g2)
  93 {
  94         const struct exception_table_entry *entry;
  95 
  96         entry = search_exception_tables(addr);
  97         if (!entry)
  98                 return 0;
  99 
 100         /* Inside range?  Fix g2 and return correct fixup */
 101         if (!entry->fixup) {
 102                 *g2 = (addr - entry->insn) / 4;
 103                 return (entry + 1)->fixup;
 104         }
 105 
 106         return entry->fixup;
 107 }

/* [<][>][^][v][top][bottom][index][help] */