module.c 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. /*
  2. * arch/xtensa/kernel/module.c
  3. *
  4. * Module support.
  5. *
  6. * This file is subject to the terms and conditions of the GNU General Public
  7. * License. See the file "COPYING" in the main directory of this archive
  8. * for more details.
  9. *
  10. * Copyright (C) 2001 - 2006 Tensilica Inc.
  11. *
  12. * Chris Zankel <chris@zankel.net>
  13. *
  14. */
  15. #include <linux/module.h>
  16. #include <linux/moduleloader.h>
  17. #include <linux/elf.h>
  18. #include <linux/vmalloc.h>
  19. #include <linux/fs.h>
  20. #include <linux/string.h>
  21. #include <linux/kernel.h>
  22. #include <linux/cache.h>
  23. #undef DEBUG_RELOCATE
  24. void *module_alloc(unsigned long size)
  25. {
  26. if (size == 0)
  27. return NULL;
  28. return vmalloc_exec(size);
  29. }
  30. void module_free(struct module *mod, void *module_region)
  31. {
  32. vfree(module_region);
  33. }
  34. int module_frob_arch_sections(Elf32_Ehdr *hdr,
  35. Elf32_Shdr *sechdrs,
  36. char *secstrings,
  37. struct module *mod)
  38. {
  39. return 0;
  40. }
  41. static int
  42. decode_calln_opcode (unsigned char *location)
  43. {
  44. #ifdef __XTENSA_EB__
  45. return (location[0] & 0xf0) == 0x50;
  46. #endif
  47. #ifdef __XTENSA_EL__
  48. return (location[0] & 0xf) == 0x5;
  49. #endif
  50. }
  51. static int
  52. decode_l32r_opcode (unsigned char *location)
  53. {
  54. #ifdef __XTENSA_EB__
  55. return (location[0] & 0xf0) == 0x10;
  56. #endif
  57. #ifdef __XTENSA_EL__
  58. return (location[0] & 0xf) == 0x1;
  59. #endif
  60. }
  61. int apply_relocate(Elf32_Shdr *sechdrs,
  62. const char *strtab,
  63. unsigned int symindex,
  64. unsigned int relsec,
  65. struct module *mod)
  66. {
  67. printk(KERN_ERR "module %s: REL RELOCATION unsupported\n",
  68. mod->name);
  69. return -ENOEXEC;
  70. }
  71. int apply_relocate_add(Elf32_Shdr *sechdrs,
  72. const char *strtab,
  73. unsigned int symindex,
  74. unsigned int relsec,
  75. struct module *mod)
  76. {
  77. unsigned int i;
  78. Elf32_Rela *rela = (void *)sechdrs[relsec].sh_addr;
  79. Elf32_Sym *sym;
  80. unsigned char *location;
  81. uint32_t value;
  82. #ifdef DEBUG_RELOCATE
  83. printk("Applying relocate section %u to %u\n", relsec,
  84. sechdrs[relsec].sh_info);
  85. #endif
  86. for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rela); i++) {
  87. location = (char *)sechdrs[sechdrs[relsec].sh_info].sh_addr
  88. + rela[i].r_offset;
  89. sym = (Elf32_Sym *)sechdrs[symindex].sh_addr
  90. + ELF32_R_SYM(rela[i].r_info);
  91. value = sym->st_value + rela[i].r_addend;
  92. switch (ELF32_R_TYPE(rela[i].r_info)) {
  93. case R_XTENSA_NONE:
  94. case R_XTENSA_DIFF8:
  95. case R_XTENSA_DIFF16:
  96. case R_XTENSA_DIFF32:
  97. case R_XTENSA_ASM_EXPAND:
  98. break;
  99. case R_XTENSA_32:
  100. case R_XTENSA_PLT:
  101. *(uint32_t *)location += value;
  102. break;
  103. case R_XTENSA_SLOT0_OP:
  104. if (decode_calln_opcode(location)) {
  105. value -= ((unsigned long)location & -4) + 4;
  106. if ((value & 3) != 0 ||
  107. ((value + (1 << 19)) >> 20) != 0) {
  108. printk("%s: relocation out of range, "
  109. "section %d reloc %d "
  110. "sym '%s'\n",
  111. mod->name, relsec, i,
  112. strtab + sym->st_name);
  113. return -ENOEXEC;
  114. }
  115. value = (signed int)value >> 2;
  116. #ifdef __XTENSA_EB__
  117. location[0] = ((location[0] & ~0x3) |
  118. ((value >> 16) & 0x3));
  119. location[1] = (value >> 8) & 0xff;
  120. location[2] = value & 0xff;
  121. #endif
  122. #ifdef __XTENSA_EL__
  123. location[0] = ((location[0] & ~0xc0) |
  124. ((value << 6) & 0xc0));
  125. location[1] = (value >> 2) & 0xff;
  126. location[2] = (value >> 10) & 0xff;
  127. #endif
  128. } else if (decode_l32r_opcode(location)) {
  129. value -= (((unsigned long)location + 3) & -4);
  130. if ((value & 3) != 0 ||
  131. (signed int)value >> 18 != -1) {
  132. printk("%s: relocation out of range, "
  133. "section %d reloc %d "
  134. "sym '%s'\n",
  135. mod->name, relsec, i,
  136. strtab + sym->st_name);
  137. return -ENOEXEC;
  138. }
  139. value = (signed int)value >> 2;
  140. #ifdef __XTENSA_EB__
  141. location[1] = (value >> 8) & 0xff;
  142. location[2] = value & 0xff;
  143. #endif
  144. #ifdef __XTENSA_EL__
  145. location[1] = value & 0xff;
  146. location[2] = (value >> 8) & 0xff;
  147. #endif
  148. }
  149. /* FIXME: Ignore any other opcodes. The Xtensa
  150. assembler currently assumes that the linker will
  151. always do relaxation and so all PC-relative
  152. operands need relocations. (The assembler also
  153. writes out the tentative PC-relative values,
  154. assuming no link-time relaxation, so it is usually
  155. safe to ignore the relocations.) If the
  156. assembler's "--no-link-relax" flag can be made to
  157. work, and if all kernel modules can be assembled
  158. with that flag, then unexpected relocations could
  159. be detected here. */
  160. break;
  161. case R_XTENSA_SLOT1_OP:
  162. case R_XTENSA_SLOT2_OP:
  163. case R_XTENSA_SLOT3_OP:
  164. case R_XTENSA_SLOT4_OP:
  165. case R_XTENSA_SLOT5_OP:
  166. case R_XTENSA_SLOT6_OP:
  167. case R_XTENSA_SLOT7_OP:
  168. case R_XTENSA_SLOT8_OP:
  169. case R_XTENSA_SLOT9_OP:
  170. case R_XTENSA_SLOT10_OP:
  171. case R_XTENSA_SLOT11_OP:
  172. case R_XTENSA_SLOT12_OP:
  173. case R_XTENSA_SLOT13_OP:
  174. case R_XTENSA_SLOT14_OP:
  175. printk("%s: unexpected FLIX relocation: %u\n",
  176. mod->name,
  177. ELF32_R_TYPE(rela[i].r_info));
  178. return -ENOEXEC;
  179. case R_XTENSA_SLOT0_ALT:
  180. case R_XTENSA_SLOT1_ALT:
  181. case R_XTENSA_SLOT2_ALT:
  182. case R_XTENSA_SLOT3_ALT:
  183. case R_XTENSA_SLOT4_ALT:
  184. case R_XTENSA_SLOT5_ALT:
  185. case R_XTENSA_SLOT6_ALT:
  186. case R_XTENSA_SLOT7_ALT:
  187. case R_XTENSA_SLOT8_ALT:
  188. case R_XTENSA_SLOT9_ALT:
  189. case R_XTENSA_SLOT10_ALT:
  190. case R_XTENSA_SLOT11_ALT:
  191. case R_XTENSA_SLOT12_ALT:
  192. case R_XTENSA_SLOT13_ALT:
  193. case R_XTENSA_SLOT14_ALT:
  194. printk("%s: unexpected ALT relocation: %u\n",
  195. mod->name,
  196. ELF32_R_TYPE(rela[i].r_info));
  197. return -ENOEXEC;
  198. default:
  199. printk("%s: unexpected relocation: %u\n",
  200. mod->name,
  201. ELF32_R_TYPE(rela[i].r_info));
  202. return -ENOEXEC;
  203. }
  204. }
  205. return 0;
  206. }
  207. int module_finalize(const Elf_Ehdr *hdr,
  208. const Elf_Shdr *sechdrs,
  209. struct module *mod)
  210. {
  211. return 0;
  212. }
  213. void module_arch_cleanup(struct module *mod)
  214. {
  215. }