module.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. #include <linux/moduleloader.h>
  2. #include <linux/elf.h>
  3. #include <linux/vmalloc.h>
  4. #include <linux/fs.h>
  5. #include <linux/string.h>
  6. #include <linux/kernel.h>
  7. #if 0
  8. #define DEBUGP printk
  9. #else
  10. #define DEBUGP(fmt...)
  11. #endif
  12. void *module_alloc(unsigned long size)
  13. {
  14. if (size == 0)
  15. return NULL;
  16. return vmalloc(size);
  17. }
  18. /* Free memory returned from module_alloc */
  19. void module_free(struct module *mod, void *module_region)
  20. {
  21. vfree(module_region);
  22. /* FIXME: If module_region == mod->init_region, trim exception
  23. table entries. */
  24. }
  25. /* We don't need anything special. */
  26. int module_frob_arch_sections(Elf_Ehdr *hdr,
  27. Elf_Shdr *sechdrs,
  28. char *secstrings,
  29. struct module *mod)
  30. {
  31. return 0;
  32. }
  33. int apply_relocate(Elf32_Shdr *sechdrs,
  34. const char *strtab,
  35. unsigned int symindex,
  36. unsigned int relsec,
  37. struct module *me)
  38. {
  39. unsigned int i;
  40. Elf32_Rel *rel = (void *)sechdrs[relsec].sh_addr;
  41. Elf32_Sym *sym;
  42. uint32_t *location;
  43. DEBUGP("Applying relocate section %u to %u\n", relsec,
  44. sechdrs[relsec].sh_info);
  45. for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
  46. /* This is where to make the change */
  47. location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
  48. + rel[i].r_offset;
  49. /* This is the symbol it is referring to. Note that all
  50. undefined symbols have been resolved. */
  51. sym = (Elf32_Sym *)sechdrs[symindex].sh_addr
  52. + ELF32_R_SYM(rel[i].r_info);
  53. switch (ELF32_R_TYPE(rel[i].r_info)) {
  54. case R_68K_32:
  55. /* We add the value into the location given */
  56. *location += sym->st_value;
  57. break;
  58. case R_68K_PC32:
  59. /* Add the value, subtract its postition */
  60. *location += sym->st_value - (uint32_t)location;
  61. break;
  62. default:
  63. printk(KERN_ERR "module %s: Unknown relocation: %u\n",
  64. me->name, ELF32_R_TYPE(rel[i].r_info));
  65. return -ENOEXEC;
  66. }
  67. }
  68. return 0;
  69. }
  70. int apply_relocate_add(Elf32_Shdr *sechdrs,
  71. const char *strtab,
  72. unsigned int symindex,
  73. unsigned int relsec,
  74. struct module *me)
  75. {
  76. unsigned int i;
  77. Elf32_Rela *rel = (void *)sechdrs[relsec].sh_addr;
  78. Elf32_Sym *sym;
  79. uint32_t *location;
  80. DEBUGP("Applying relocate_add section %u to %u\n", relsec,
  81. sechdrs[relsec].sh_info);
  82. for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
  83. /* This is where to make the change */
  84. location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
  85. + rel[i].r_offset;
  86. /* This is the symbol it is referring to. Note that all
  87. undefined symbols have been resolved. */
  88. sym = (Elf32_Sym *)sechdrs[symindex].sh_addr
  89. + ELF32_R_SYM(rel[i].r_info);
  90. switch (ELF32_R_TYPE(rel[i].r_info)) {
  91. case R_68K_32:
  92. /* We add the value into the location given */
  93. *location = rel[i].r_addend + sym->st_value;
  94. break;
  95. case R_68K_PC32:
  96. /* Add the value, subtract its postition */
  97. *location = rel[i].r_addend + sym->st_value - (uint32_t)location;
  98. break;
  99. default:
  100. printk(KERN_ERR "module %s: Unknown relocation: %u\n",
  101. me->name, ELF32_R_TYPE(rel[i].r_info));
  102. return -ENOEXEC;
  103. }
  104. }
  105. return 0;
  106. }
  107. int module_finalize(const Elf_Ehdr *hdr,
  108. const Elf_Shdr *sechdrs,
  109. struct module *me)
  110. {
  111. return 0;
  112. }
  113. void module_arch_cleanup(struct module *mod)
  114. {
  115. }