module.c 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336
  1. /*
  2. * File: arch/blackfin/kernel/module.c
  3. * Based on:
  4. * Author:
  5. *
  6. * Created:
  7. * Description:
  8. *
  9. * Modified:
  10. * Copyright 2004-2006 Analog Devices Inc.
  11. *
  12. * Bugs: Enter bugs at http://blackfin.uclinux.org/
  13. *
  14. * This program is free software; you can redistribute it and/or modify
  15. * it under the terms of the GNU General Public License as published by
  16. * the Free Software Foundation; either version 2 of the License, or
  17. * (at your option) any later version.
  18. *
  19. * This program is distributed in the hope that it will be useful,
  20. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  21. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  22. * GNU General Public License for more details.
  23. *
  24. * You should have received a copy of the GNU General Public License
  25. * along with this program; if not, see the file COPYING, or write
  26. * to the Free Software Foundation, Inc.,
  27. * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  28. */
  29. #define pr_fmt(fmt) "module %s: " fmt
  30. #include <linux/moduleloader.h>
  31. #include <linux/elf.h>
  32. #include <linux/vmalloc.h>
  33. #include <linux/fs.h>
  34. #include <linux/string.h>
  35. #include <linux/kernel.h>
  36. #include <asm/dma.h>
  37. #include <asm/cacheflush.h>
  38. void *module_alloc(unsigned long size)
  39. {
  40. if (size == 0)
  41. return NULL;
  42. return vmalloc(size);
  43. }
  44. /* Free memory returned from module_alloc */
  45. void module_free(struct module *mod, void *module_region)
  46. {
  47. vfree(module_region);
  48. }
  49. /* Transfer the section to the L1 memory */
  50. int
  51. module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs,
  52. char *secstrings, struct module *mod)
  53. {
  54. /*
  55. * XXX: sechdrs are vmalloced in kernel/module.c
  56. * and would be vfreed just after module is loaded,
  57. * so we hack to keep the only information we needed
  58. * in mod->arch to correctly free L1 I/D sram later.
  59. * NOTE: this breaks the semantic of mod->arch structure.
  60. */
  61. Elf_Shdr *s, *sechdrs_end = sechdrs + hdr->e_shnum;
  62. void *dest;
  63. for (s = sechdrs; s < sechdrs_end; ++s) {
  64. const char *shname = secstrings + s->sh_name;
  65. if (s->sh_size == 0)
  66. continue;
  67. if (!strcmp(".l1.text", shname) ||
  68. (!strcmp(".text", shname) &&
  69. (hdr->e_flags & EF_BFIN_CODE_IN_L1))) {
  70. dest = l1_inst_sram_alloc(s->sh_size);
  71. mod->arch.text_l1 = dest;
  72. if (dest == NULL) {
  73. pr_err("L1 inst memory allocation failed\n",
  74. mod->name);
  75. return -1;
  76. }
  77. dma_memcpy(dest, (void *)s->sh_addr, s->sh_size);
  78. } else if (!strcmp(".l1.data", shname) ||
  79. (!strcmp(".data", shname) &&
  80. (hdr->e_flags & EF_BFIN_DATA_IN_L1))) {
  81. dest = l1_data_sram_alloc(s->sh_size);
  82. mod->arch.data_a_l1 = dest;
  83. if (dest == NULL) {
  84. pr_err("L1 data memory allocation failed\n",
  85. mod->name);
  86. return -1;
  87. }
  88. memcpy(dest, (void *)s->sh_addr, s->sh_size);
  89. } else if (!strcmp(".l1.bss", shname) ||
  90. (!strcmp(".bss", shname) &&
  91. (hdr->e_flags & EF_BFIN_DATA_IN_L1))) {
  92. dest = l1_data_sram_zalloc(s->sh_size);
  93. mod->arch.bss_a_l1 = dest;
  94. if (dest == NULL) {
  95. pr_err("L1 data memory allocation failed\n",
  96. mod->name);
  97. return -1;
  98. }
  99. } else if (!strcmp(".l1.data.B", shname)) {
  100. dest = l1_data_B_sram_alloc(s->sh_size);
  101. mod->arch.data_b_l1 = dest;
  102. if (dest == NULL) {
  103. pr_err("L1 data memory allocation failed\n",
  104. mod->name);
  105. return -1;
  106. }
  107. memcpy(dest, (void *)s->sh_addr, s->sh_size);
  108. } else if (!strcmp(".l1.bss.B", shname)) {
  109. dest = l1_data_B_sram_alloc(s->sh_size);
  110. mod->arch.bss_b_l1 = dest;
  111. if (dest == NULL) {
  112. pr_err("L1 data memory allocation failed\n",
  113. mod->name);
  114. return -1;
  115. }
  116. memset(dest, 0, s->sh_size);
  117. } else if (!strcmp(".l2.text", shname) ||
  118. (!strcmp(".text", shname) &&
  119. (hdr->e_flags & EF_BFIN_CODE_IN_L2))) {
  120. dest = l2_sram_alloc(s->sh_size);
  121. mod->arch.text_l2 = dest;
  122. if (dest == NULL) {
  123. pr_err("L2 SRAM allocation failed\n",
  124. mod->name);
  125. return -1;
  126. }
  127. memcpy(dest, (void *)s->sh_addr, s->sh_size);
  128. } else if (!strcmp(".l2.data", shname) ||
  129. (!strcmp(".data", shname) &&
  130. (hdr->e_flags & EF_BFIN_DATA_IN_L2))) {
  131. dest = l2_sram_alloc(s->sh_size);
  132. mod->arch.data_l2 = dest;
  133. if (dest == NULL) {
  134. pr_err("L2 SRAM allocation failed\n",
  135. mod->name);
  136. return -1;
  137. }
  138. memcpy(dest, (void *)s->sh_addr, s->sh_size);
  139. } else if (!strcmp(".l2.bss", shname) ||
  140. (!strcmp(".bss", shname) &&
  141. (hdr->e_flags & EF_BFIN_DATA_IN_L2))) {
  142. dest = l2_sram_zalloc(s->sh_size);
  143. mod->arch.bss_l2 = dest;
  144. if (dest == NULL) {
  145. pr_err("L2 SRAM allocation failed\n",
  146. mod->name);
  147. return -1;
  148. }
  149. } else
  150. continue;
  151. s->sh_flags &= ~SHF_ALLOC;
  152. s->sh_addr = (unsigned long)dest;
  153. }
  154. return 0;
  155. }
  156. int
  157. apply_relocate(Elf_Shdr * sechdrs, const char *strtab,
  158. unsigned int symindex, unsigned int relsec, struct module *me)
  159. {
  160. pr_err(".rel unsupported\n", me->name);
  161. return -ENOEXEC;
  162. }
  163. /*************************************************************************/
  164. /* FUNCTION : apply_relocate_add */
  165. /* ABSTRACT : Blackfin specific relocation handling for the loadable */
  166. /* modules. Modules are expected to be .o files. */
  167. /* Arithmetic relocations are handled. */
  168. /* We do not expect LSETUP to be split and hence is not */
  169. /* handled. */
  170. /* R_BFIN_BYTE and R_BFIN_BYTE2 are also not handled as the */
  171. /* gas does not generate it. */
  172. /*************************************************************************/
  173. int
  174. apply_relocate_add(Elf_Shdr * sechdrs, const char *strtab,
  175. unsigned int symindex, unsigned int relsec,
  176. struct module *mod)
  177. {
  178. unsigned int i;
  179. unsigned short tmp;
  180. Elf32_Rela *rel = (void *)sechdrs[relsec].sh_addr;
  181. Elf32_Sym *sym;
  182. uint32_t *location32;
  183. uint16_t *location16;
  184. uint32_t value;
  185. pr_debug("applying relocate section %u to %u\n", mod->name,
  186. relsec, sechdrs[relsec].sh_info);
  187. for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
  188. /* This is where to make the change */
  189. location16 =
  190. (uint16_t *) (sechdrs[sechdrs[relsec].sh_info].sh_addr +
  191. rel[i].r_offset);
  192. location32 = (uint32_t *) location16;
  193. /* This is the symbol it is referring to. Note that all
  194. undefined symbols have been resolved. */
  195. sym = (Elf32_Sym *) sechdrs[symindex].sh_addr
  196. + ELF32_R_SYM(rel[i].r_info);
  197. value = sym->st_value;
  198. value += rel[i].r_addend;
  199. #ifdef CONFIG_SMP
  200. if ((unsigned long)location16 >= COREB_L1_DATA_A_START) {
  201. pr_err("cannot relocate in L1: %u (SMP kernel)",
  202. mod->name, ELF32_R_TYPE(rel[i].r_info));
  203. return -ENOEXEC;
  204. }
  205. #endif
  206. pr_debug("location is %lx, value is %x type is %d\n",
  207. mod->name, (unsigned long)location32, value,
  208. ELF32_R_TYPE(rel[i].r_info));
  209. switch (ELF32_R_TYPE(rel[i].r_info)) {
  210. case R_BFIN_LUIMM16:
  211. tmp = (value & 0xffff);
  212. if ((unsigned long)location16 >= L1_CODE_START) {
  213. dma_memcpy(location16, &tmp, 2);
  214. } else
  215. *location16 = tmp;
  216. break;
  217. case R_BFIN_HUIMM16:
  218. tmp = ((value >> 16) & 0xffff);
  219. if ((unsigned long)location16 >= L1_CODE_START) {
  220. dma_memcpy(location16, &tmp, 2);
  221. } else
  222. *location16 = tmp;
  223. break;
  224. case R_BFIN_RIMM16:
  225. *location16 = (value & 0xffff);
  226. break;
  227. case R_BFIN_BYTE4_DATA:
  228. *location32 = value;
  229. break;
  230. case R_BFIN_PCREL24:
  231. case R_BFIN_PCREL24_JUMP_L:
  232. case R_BFIN_PCREL12_JUMP:
  233. case R_BFIN_PCREL12_JUMP_S:
  234. case R_BFIN_PCREL10:
  235. pr_err("unsupported relocation: %u (no -mlong-calls?)\n",
  236. mod->name, ELF32_R_TYPE(rel[i].r_info));
  237. return -ENOEXEC;
  238. default:
  239. pr_err("unknown relocation: %u\n", mod->name,
  240. ELF32_R_TYPE(rel[i].r_info));
  241. return -ENOEXEC;
  242. }
  243. }
  244. return 0;
  245. }
  246. int
  247. module_finalize(const Elf_Ehdr * hdr,
  248. const Elf_Shdr * sechdrs, struct module *mod)
  249. {
  250. unsigned int i, strindex = 0, symindex = 0;
  251. char *secstrings;
  252. long err = 0;
  253. secstrings = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
  254. for (i = 1; i < hdr->e_shnum; i++) {
  255. /* Internal symbols and strings. */
  256. if (sechdrs[i].sh_type == SHT_SYMTAB) {
  257. symindex = i;
  258. strindex = sechdrs[i].sh_link;
  259. }
  260. }
  261. for (i = 1; i < hdr->e_shnum; i++) {
  262. const char *strtab = (char *)sechdrs[strindex].sh_addr;
  263. unsigned int info = sechdrs[i].sh_info;
  264. const char *shname = secstrings + sechdrs[i].sh_name;
  265. /* Not a valid relocation section? */
  266. if (info >= hdr->e_shnum)
  267. continue;
  268. /* Only support RELA relocation types */
  269. if (sechdrs[i].sh_type != SHT_RELA)
  270. continue;
  271. if (!strcmp(".rela.l2.text", shname) ||
  272. !strcmp(".rela.l1.text", shname) ||
  273. (!strcmp(".rela.text", shname) &&
  274. (hdr->e_flags & (EF_BFIN_CODE_IN_L1 | EF_BFIN_CODE_IN_L2)))) {
  275. err = apply_relocate_add((Elf_Shdr *) sechdrs, strtab,
  276. symindex, i, mod);
  277. if (err < 0)
  278. return -ENOEXEC;
  279. }
  280. }
  281. return 0;
  282. }
  283. void module_arch_cleanup(struct module *mod)
  284. {
  285. l1_inst_sram_free(mod->arch.text_l1);
  286. l1_data_A_sram_free(mod->arch.data_a_l1);
  287. l1_data_A_sram_free(mod->arch.bss_a_l1);
  288. l1_data_B_sram_free(mod->arch.data_b_l1);
  289. l1_data_B_sram_free(mod->arch.bss_b_l1);
  290. l2_sram_free(mod->arch.text_l2);
  291. l2_sram_free(mod->arch.data_l2);
  292. l2_sram_free(mod->arch.bss_l2);
  293. }