module.c 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. /*
  2. * arch/v850/kernel/module.c -- Architecture-specific module functions
  3. *
  4. * Copyright (C) 2002,03 NEC Electronics Corporation
  5. * Copyright (C) 2002,03 Miles Bader <miles@gnu.org>
  6. * Copyright (C) 2001,03 Rusty Russell
  7. *
  8. * This file is subject to the terms and conditions of the GNU General
  9. * Public License. See the file COPYING in the main directory of this
  10. * archive for more details.
  11. *
  12. * Written by Miles Bader <miles@gnu.org>
  13. *
  14. * Derived in part from arch/ppc/kernel/module.c
  15. */
  16. #include <linux/kernel.h>
  17. #include <linux/vmalloc.h>
  18. #include <linux/moduleloader.h>
  19. #include <linux/elf.h>
  20. #if 0
  21. #define DEBUGP printk
  22. #else
  23. #define DEBUGP(fmt , ...)
  24. #endif
  25. void *module_alloc (unsigned long size)
  26. {
  27. return size == 0 ? 0 : vmalloc (size);
  28. }
  29. void module_free (struct module *mod, void *module_region)
  30. {
  31. vfree (module_region);
  32. /* FIXME: If module_region == mod->init_region, trim exception
  33. table entries. */
  34. }
  35. int module_finalize (const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs,
  36. struct module *mod)
  37. {
  38. return 0;
  39. }
  40. /* Count how many different relocations (different symbol, different
  41. addend) */
  42. static unsigned int count_relocs(const Elf32_Rela *rela, unsigned int num)
  43. {
  44. unsigned int i, j, ret = 0;
  45. /* Sure, this is order(n^2), but it's usually short, and not
  46. time critical */
  47. for (i = 0; i < num; i++) {
  48. for (j = 0; j < i; j++) {
  49. /* If this addend appeared before, it's
  50. already been counted */
  51. if (ELF32_R_SYM(rela[i].r_info)
  52. == ELF32_R_SYM(rela[j].r_info)
  53. && rela[i].r_addend == rela[j].r_addend)
  54. break;
  55. }
  56. if (j == i) ret++;
  57. }
  58. return ret;
  59. }
  60. /* Get the potential trampolines size required of the init and
  61. non-init sections */
  62. static unsigned long get_plt_size(const Elf32_Ehdr *hdr,
  63. const Elf32_Shdr *sechdrs,
  64. const char *secstrings,
  65. int is_init)
  66. {
  67. unsigned long ret = 0;
  68. unsigned i;
  69. /* Everything marked ALLOC (this includes the exported
  70. symbols) */
  71. for (i = 1; i < hdr->e_shnum; i++) {
  72. /* If it's called *.init*, and we're not init, we're
  73. not interested */
  74. if ((strstr(secstrings + sechdrs[i].sh_name, ".init") != 0)
  75. != is_init)
  76. continue;
  77. if (sechdrs[i].sh_type == SHT_RELA) {
  78. DEBUGP("Found relocations in section %u\n", i);
  79. DEBUGP("Ptr: %p. Number: %u\n",
  80. (void *)hdr + sechdrs[i].sh_offset,
  81. sechdrs[i].sh_size / sizeof(Elf32_Rela));
  82. ret += count_relocs((void *)hdr
  83. + sechdrs[i].sh_offset,
  84. sechdrs[i].sh_size
  85. / sizeof(Elf32_Rela))
  86. * sizeof(struct v850_plt_entry);
  87. }
  88. }
  89. return ret;
  90. }
  91. int module_frob_arch_sections(Elf32_Ehdr *hdr,
  92. Elf32_Shdr *sechdrs,
  93. char *secstrings,
  94. struct module *me)
  95. {
  96. unsigned int i;
  97. /* Find .plt and .pltinit sections */
  98. for (i = 0; i < hdr->e_shnum; i++) {
  99. if (strcmp(secstrings + sechdrs[i].sh_name, ".init.plt") == 0)
  100. me->arch.init_plt_section = i;
  101. else if (strcmp(secstrings + sechdrs[i].sh_name, ".plt") == 0)
  102. me->arch.core_plt_section = i;
  103. }
  104. if (!me->arch.core_plt_section || !me->arch.init_plt_section) {
  105. printk("Module doesn't contain .plt or .plt.init sections.\n");
  106. return -ENOEXEC;
  107. }
  108. /* Override their sizes */
  109. sechdrs[me->arch.core_plt_section].sh_size
  110. = get_plt_size(hdr, sechdrs, secstrings, 0);
  111. sechdrs[me->arch.init_plt_section].sh_size
  112. = get_plt_size(hdr, sechdrs, secstrings, 1);
  113. return 0;
  114. }
  115. int apply_relocate (Elf32_Shdr *sechdrs, const char *strtab,
  116. unsigned int symindex, unsigned int relsec,
  117. struct module *mod)
  118. {
  119. printk ("Barf\n");
  120. return -ENOEXEC;
  121. }
  122. /* Set up a trampoline in the PLT to bounce us to the distant function */
  123. static uint32_t do_plt_call (void *location, Elf32_Addr val,
  124. Elf32_Shdr *sechdrs, struct module *mod)
  125. {
  126. struct v850_plt_entry *entry;
  127. /* Instructions used to do the indirect jump. */
  128. uint32_t tramp[2];
  129. /* We have to trash a register, so we assume that any control
  130. transfer more than 21-bits away must be a function call
  131. (so we can use a call-clobbered register). */
  132. tramp[0] = 0x0621 + ((val & 0xffff) << 16); /* mov sym, r1 ... */
  133. tramp[1] = ((val >> 16) & 0xffff) + 0x610000; /* ...; jmp r1 */
  134. /* Init, or core PLT? */
  135. if (location >= mod->module_core
  136. && location < mod->module_core + mod->core_size)
  137. entry = (void *)sechdrs[mod->arch.core_plt_section].sh_addr;
  138. else
  139. entry = (void *)sechdrs[mod->arch.init_plt_section].sh_addr;
  140. /* Find this entry, or if that fails, the next avail. entry */
  141. while (entry->tramp[0])
  142. if (entry->tramp[0] == tramp[0] && entry->tramp[1] == tramp[1])
  143. return (uint32_t)entry;
  144. else
  145. entry++;
  146. entry->tramp[0] = tramp[0];
  147. entry->tramp[1] = tramp[1];
  148. return (uint32_t)entry;
  149. }
  150. int apply_relocate_add (Elf32_Shdr *sechdrs, const char *strtab,
  151. unsigned int symindex, unsigned int relsec,
  152. struct module *mod)
  153. {
  154. unsigned int i;
  155. Elf32_Rela *rela = (void *)sechdrs[relsec].sh_addr;
  156. DEBUGP ("Applying relocate section %u to %u\n", relsec,
  157. sechdrs[relsec].sh_info);
  158. for (i = 0; i < sechdrs[relsec].sh_size / sizeof (*rela); i++) {
  159. /* This is where to make the change */
  160. uint32_t *loc
  161. = ((void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
  162. + rela[i].r_offset);
  163. /* This is the symbol it is referring to. Note that all
  164. undefined symbols have been resolved. */
  165. Elf32_Sym *sym
  166. = ((Elf32_Sym *)sechdrs[symindex].sh_addr
  167. + ELF32_R_SYM (rela[i].r_info));
  168. uint32_t val = sym->st_value + rela[i].r_addend;
  169. switch (ELF32_R_TYPE (rela[i].r_info)) {
  170. case R_V850_32:
  171. /* We write two shorts instead of a long because even
  172. 32-bit insns only need half-word alignment, but
  173. 32-bit data writes need to be long-word aligned. */
  174. val += ((uint16_t *)loc)[0];
  175. val += ((uint16_t *)loc)[1] << 16;
  176. ((uint16_t *)loc)[0] = val & 0xffff;
  177. ((uint16_t *)loc)[1] = (val >> 16) & 0xffff;
  178. break;
  179. case R_V850_22_PCREL:
  180. /* Maybe jump indirectly via a PLT table entry. */
  181. if ((int32_t)(val - (uint32_t)loc) > 0x1fffff
  182. || (int32_t)(val - (uint32_t)loc) < -0x200000)
  183. val = do_plt_call (loc, val, sechdrs, mod);
  184. val -= (uint32_t)loc;
  185. /* We write two shorts instead of a long because
  186. even 32-bit insns only need half-word alignment,
  187. but 32-bit data writes need to be long-word
  188. aligned. */
  189. ((uint16_t *)loc)[0] =
  190. (*(uint16_t *)loc & 0xffc0) /* opcode + reg */
  191. | ((val >> 16) & 0xffc03f); /* offs high */
  192. ((uint16_t *)loc)[1] =
  193. (val & 0xffff); /* offs low */
  194. break;
  195. default:
  196. printk (KERN_ERR "module %s: Unknown reloc: %u\n",
  197. mod->name, ELF32_R_TYPE (rela[i].r_info));
  198. return -ENOEXEC;
  199. }
  200. }
  201. return 0;
  202. }
  203. void
  204. module_arch_cleanup(struct module *mod)
  205. {
  206. }