extable.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:1k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /* $Id: extable.c,v 1.2 2001/03/31 10:43:18 gniibe Exp $
  2.  *
  3.  * linux/arch/sh/mm/extable.c
  4.  *  Taken from:
  5.  *   linux/arch/i386/mm/extable.c
  6.  */
  7. #include <linux/config.h>
  8. #include <linux/module.h>
  9. #include <asm/uaccess.h>
  10. extern const struct exception_table_entry __start___ex_table[];
  11. extern const struct exception_table_entry __stop___ex_table[];
  12. static inline unsigned long
  13. search_one_table(const struct exception_table_entry *first,
  14.  const struct exception_table_entry *last,
  15.  unsigned long value)
  16. {
  17.         while (first <= last) {
  18. const struct exception_table_entry *mid;
  19. long diff;
  20. mid = (last - first) / 2 + first;
  21. diff = mid->insn - value;
  22.                 if (diff == 0)
  23.                         return mid->fixup;
  24.                 else if (diff < 0)
  25.                         first = mid+1;
  26.                 else
  27.                         last = mid-1;
  28.         }
  29.         return 0;
  30. }
  31. unsigned long
  32. search_exception_table(unsigned long addr)
  33. {
  34. unsigned long ret;
  35. #ifndef CONFIG_MODULES
  36. /* There is only the kernel to search.  */
  37. ret = search_one_table(__start___ex_table, __stop___ex_table-1, addr);
  38. if (ret) return ret;
  39. #else
  40. /* The kernel is the last "module" -- no need to treat it special.  */
  41. struct module *mp;
  42. for (mp = module_list; mp != NULL; mp = mp->next) {
  43. if (mp->ex_table_start == NULL || !(mp->flags&(MOD_RUNNING|MOD_INITIALIZING)))
  44. continue;
  45. ret = search_one_table(mp->ex_table_start,
  46.        mp->ex_table_end - 1, addr);
  47. if (ret) return ret;
  48. }
  49. #endif
  50. return 0;
  51. }