module.c 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. #include <linux/module.h>
  2. #include <linux/spinlock.h>
  3. static LIST_HEAD(dbe_list);
  4. static DEFINE_SPINLOCK(dbe_lock);
  5. /* Given an address, look for it in the module exception tables. */
  6. const struct exception_table_entry *search_module_dbetables(unsigned long addr)
  7. {
  8. unsigned long flags;
  9. const struct exception_table_entry *e = NULL;
  10. struct mod_arch_specific *dbe;
  11. spin_lock_irqsave(&dbe_lock, flags);
  12. list_for_each_entry(dbe, &dbe_list, dbe_list) {
  13. e = search_extable(dbe->dbe_start, dbe->dbe_end - 1, addr);
  14. if (e)
  15. break;
  16. }
  17. spin_unlock_irqrestore(&dbe_lock, flags);
  18. /* Now, if we found one, we are running inside it now, hence
  19. we cannot unload the module, hence no refcnt needed. */
  20. return e;
  21. }
  22. /* Put in dbe list if neccessary. */
  23. int module_finalize(const Elf_Ehdr *hdr,
  24. const Elf_Shdr *sechdrs,
  25. struct module *me)
  26. {
  27. const Elf_Shdr *s;
  28. char *secstrings = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
  29. INIT_LIST_HEAD(&me->arch.dbe_list);
  30. for (s = sechdrs; s < sechdrs + hdr->e_shnum; s++) {
  31. if (strcmp("__dbe_table", secstrings + s->sh_name) != 0)
  32. continue;
  33. me->arch.dbe_start = (void *)s->sh_addr;
  34. me->arch.dbe_end = (void *)s->sh_addr + s->sh_size;
  35. spin_lock_irq(&dbe_lock);
  36. list_add(&me->arch.dbe_list, &dbe_list);
  37. spin_unlock_irq(&dbe_lock);
  38. }
  39. return 0;
  40. }
  41. void module_arch_cleanup(struct module *mod)
  42. {
  43. spin_lock_irq(&dbe_lock);
  44. list_del(&mod->arch.dbe_list);
  45. spin_unlock_irq(&dbe_lock);
  46. }