LCOV - code coverage report
Current view: top level - lib - extable.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 18 22 81.8 %
Date: 2015-04-12 14:34:49 Functions: 4 4 100.0 %

          Line data    Source code
       1             : /*
       2             :  * Derived from arch/ppc/mm/extable.c and arch/i386/mm/extable.c.
       3             :  *
       4             :  * Copyright (C) 2004 Paul Mackerras, IBM Corp.
       5             :  *
       6             :  * This program is free software; you can redistribute it and/or
       7             :  * modify it under the terms of the GNU General Public License
       8             :  * as published by the Free Software Foundation; either version
       9             :  * 2 of the License, or (at your option) any later version.
      10             :  */
      11             : 
      12             : #include <linux/module.h>
      13             : #include <linux/init.h>
      14             : #include <linux/sort.h>
      15             : #include <asm/uaccess.h>
      16             : 
      17             : #ifndef ARCH_HAS_SORT_EXTABLE
      18             : /*
      19             :  * The exception table needs to be sorted so that the binary
      20             :  * search that we use to find entries in it works properly.
      21             :  * This is used both for the kernel exception table and for
      22             :  * the exception tables of modules that get loaded.
      23             :  */
      24          27 : static int cmp_ex(const void *a, const void *b)
      25             : {
      26             :         const struct exception_table_entry *x = a, *y = b;
      27             : 
      28             :         /* avoid overflow */
      29          27 :         if (x->insn > y->insn)
      30             :                 return 1;
      31          20 :         if (x->insn < y->insn)
      32             :                 return -1;
      33           0 :         return 0;
      34             : }
      35             : 
      36          16 : void sort_extable(struct exception_table_entry *start,
      37             :                   struct exception_table_entry *finish)
      38             : {
      39          16 :         sort(start, finish - start, sizeof(struct exception_table_entry),
      40             :              cmp_ex, NULL);
      41          16 : }
      42             : 
      43             : #ifdef CONFIG_MODULES
      44             : /*
      45             :  * If the exception table is sorted, any referring to the module init
      46             :  * will be at the beginning or the end.
      47             :  */
      48          18 : void trim_init_extable(struct module *m)
      49             : {
      50             :         /*trim the beginning*/
      51          33 :         while (m->num_exentries && within_module_init(m->extable[0].insn, m)) {
      52           0 :                 m->extable++;
      53           0 :                 m->num_exentries--;
      54             :         }
      55             :         /*trim the end*/
      56          17 :         while (m->num_exentries &&
      57           1 :                 within_module_init(m->extable[m->num_exentries-1].insn, m))
      58           0 :                 m->num_exentries--;
      59          16 : }
      60             : #endif /* CONFIG_MODULES */
      61             : #endif /* !ARCH_HAS_SORT_EXTABLE */
      62             : 
      63             : #ifndef ARCH_HAS_SEARCH_EXTABLE
      64             : /*
      65             :  * Search one exception table for an entry corresponding to the
      66             :  * given instruction address, and return the address of the entry,
      67             :  * or NULL if none is found.
      68             :  * We use a binary search, and thus we assume that the table is
      69             :  * already sorted.
      70             :  */
      71             : const struct exception_table_entry *
      72          12 : search_extable(const struct exception_table_entry *first,
      73             :                const struct exception_table_entry *last,
      74             :                unsigned long value)
      75             : {
      76         116 :         while (first <= last) {
      77             :                 const struct exception_table_entry *mid;
      78             : 
      79         104 :                 mid = ((last - first) >> 1) + first;
      80             :                 /*
      81             :                  * careful, the distance between value and insn
      82             :                  * can be larger than MAX_LONG:
      83             :                  */
      84         104 :                 if (mid->insn < value)
      85          65 :                         first = mid + 1;
      86          39 :                 else if (mid->insn > value)
      87          27 :                         last = mid - 1;
      88             :                 else
      89             :                         return mid;
      90             :         }
      91             :         return NULL;
      92             : }
      93             : #endif

Generated by: LCOV version 1.11