module.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364
  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. #include <linux/moduleloader.h>
  30. #include <linux/elf.h>
  31. #include <linux/vmalloc.h>
  32. #include <linux/fs.h>
  33. #include <linux/string.h>
  34. #include <linux/kernel.h>
  35. #include <asm/dma.h>
  36. #include <asm/cacheflush.h>
  37. void *module_alloc(unsigned long size)
  38. {
  39. if (size == 0)
  40. return NULL;
  41. return vmalloc(size);
  42. }
  43. /* Free memory returned from module_alloc */
  44. void module_free(struct module *mod, void *module_region)
  45. {
  46. vfree(module_region);
  47. }
  48. /* Transfer the section to the L1 memory */
  49. int
  50. module_frob_arch_sections(Elf_Ehdr * hdr, Elf_Shdr * sechdrs,
  51. char *secstrings, struct module *mod)
  52. {
  53. /*
  54. * XXX: sechdrs are vmalloced in kernel/module.c
  55. * and would be vfreed just after module is loaded,
  56. * so we hack to keep the only information we needed
  57. * in mod->arch to correctly free L1 I/D sram later.
  58. * NOTE: this breaks the semantic of mod->arch structure.
  59. */
  60. Elf_Shdr *s, *sechdrs_end = sechdrs + hdr->e_shnum;
  61. void *dest = NULL;
  62. for (s = sechdrs; s < sechdrs_end; ++s) {
  63. if ((strcmp(".l1.text", secstrings + s->sh_name) == 0) ||
  64. ((strcmp(".text", secstrings + s->sh_name) == 0) &&
  65. (hdr->e_flags & EF_BFIN_CODE_IN_L1) && (s->sh_size > 0))) {
  66. dest = l1_inst_sram_alloc(s->sh_size);
  67. mod->arch.text_l1 = dest;
  68. if (dest == NULL) {
  69. printk(KERN_ERR
  70. "module %s: L1 instruction memory allocation failed\n",
  71. mod->name);
  72. return -1;
  73. }
  74. dma_memcpy(dest, (void *)s->sh_addr, s->sh_size);
  75. s->sh_flags &= ~SHF_ALLOC;
  76. s->sh_addr = (unsigned long)dest;
  77. }
  78. if ((strcmp(".l1.data", secstrings + s->sh_name) == 0) ||
  79. ((strcmp(".data", secstrings + s->sh_name) == 0) &&
  80. (hdr->e_flags & EF_BFIN_DATA_IN_L1) && (s->sh_size > 0))) {
  81. dest = l1_data_sram_alloc(s->sh_size);
  82. mod->arch.data_a_l1 = dest;
  83. if (dest == NULL) {
  84. printk(KERN_ERR
  85. "module %s: L1 data memory allocation failed\n",
  86. mod->name);
  87. return -1;
  88. }
  89. memcpy(dest, (void *)s->sh_addr, s->sh_size);
  90. s->sh_flags &= ~SHF_ALLOC;
  91. s->sh_addr = (unsigned long)dest;
  92. }
  93. if (strcmp(".l1.bss", secstrings + s->sh_name) == 0 ||
  94. ((strcmp(".bss", secstrings + s->sh_name) == 0) &&
  95. (hdr->e_flags & EF_BFIN_DATA_IN_L1) && (s->sh_size > 0))) {
  96. dest = l1_data_sram_alloc(s->sh_size);
  97. mod->arch.bss_a_l1 = dest;
  98. if (dest == NULL) {
  99. printk(KERN_ERR
  100. "module %s: L1 data memory allocation failed\n",
  101. mod->name);
  102. return -1;
  103. }
  104. memset(dest, 0, s->sh_size);
  105. s->sh_flags &= ~SHF_ALLOC;
  106. s->sh_addr = (unsigned long)dest;
  107. }
  108. if (strcmp(".l1.data.B", secstrings + s->sh_name) == 0) {
  109. dest = l1_data_B_sram_alloc(s->sh_size);
  110. mod->arch.data_b_l1 = dest;
  111. if (dest == NULL) {
  112. printk(KERN_ERR
  113. "module %s: L1 data memory allocation failed\n",
  114. mod->name);
  115. return -1;
  116. }
  117. memcpy(dest, (void *)s->sh_addr, s->sh_size);
  118. s->sh_flags &= ~SHF_ALLOC;
  119. s->sh_addr = (unsigned long)dest;
  120. }
  121. if (strcmp(".l1.bss.B", secstrings + s->sh_name) == 0) {
  122. dest = l1_data_B_sram_alloc(s->sh_size);
  123. mod->arch.bss_b_l1 = dest;
  124. if (dest == NULL) {
  125. printk(KERN_ERR
  126. "module %s: L1 data memory allocation failed\n",
  127. mod->name);
  128. return -1;
  129. }
  130. memset(dest, 0, s->sh_size);
  131. s->sh_flags &= ~SHF_ALLOC;
  132. s->sh_addr = (unsigned long)dest;
  133. }
  134. if ((strcmp(".l2.text", secstrings + s->sh_name) == 0) ||
  135. ((strcmp(".text", secstrings + s->sh_name) == 0) &&
  136. (hdr->e_flags & EF_BFIN_CODE_IN_L2) && (s->sh_size > 0))) {
  137. dest = l2_sram_alloc(s->sh_size);
  138. mod->arch.text_l2 = dest;
  139. if (dest == NULL) {
  140. printk(KERN_ERR
  141. "module %s: L2 SRAM allocation failed\n",
  142. mod->name);
  143. return -1;
  144. }
  145. memcpy(dest, (void *)s->sh_addr, s->sh_size);
  146. s->sh_flags &= ~SHF_ALLOC;
  147. s->sh_addr = (unsigned long)dest;
  148. }
  149. if ((strcmp(".l2.data", secstrings + s->sh_name) == 0) ||
  150. ((strcmp(".data", secstrings + s->sh_name) == 0) &&
  151. (hdr->e_flags & EF_BFIN_DATA_IN_L2) && (s->sh_size > 0))) {
  152. dest = l2_sram_alloc(s->sh_size);
  153. mod->arch.data_l2 = dest;
  154. if (dest == NULL) {
  155. printk(KERN_ERR
  156. "module %s: L2 SRAM allocation failed\n",
  157. mod->name);
  158. return -1;
  159. }
  160. memcpy(dest, (void *)s->sh_addr, s->sh_size);
  161. s->sh_flags &= ~SHF_ALLOC;
  162. s->sh_addr = (unsigned long)dest;
  163. }
  164. if (strcmp(".l2.bss", secstrings + s->sh_name) == 0 ||
  165. ((strcmp(".bss", secstrings + s->sh_name) == 0) &&
  166. (hdr->e_flags & EF_BFIN_DATA_IN_L2) && (s->sh_size > 0))) {
  167. dest = l2_sram_alloc(s->sh_size);
  168. mod->arch.bss_l2 = dest;
  169. if (dest == NULL) {
  170. printk(KERN_ERR
  171. "module %s: L2 SRAM allocation failed\n",
  172. mod->name);
  173. return -1;
  174. }
  175. memset(dest, 0, s->sh_size);
  176. s->sh_flags &= ~SHF_ALLOC;
  177. s->sh_addr = (unsigned long)dest;
  178. }
  179. }
  180. return 0;
  181. }
  182. int
  183. apply_relocate(Elf_Shdr * sechdrs, const char *strtab,
  184. unsigned int symindex, unsigned int relsec, struct module *me)
  185. {
  186. printk(KERN_ERR "module %s: .rel unsupported\n", me->name);
  187. return -ENOEXEC;
  188. }
  189. /*************************************************************************/
  190. /* FUNCTION : apply_relocate_add */
  191. /* ABSTRACT : Blackfin specific relocation handling for the loadable */
  192. /* modules. Modules are expected to be .o files. */
  193. /* Arithmetic relocations are handled. */
  194. /* We do not expect LSETUP to be split and hence is not */
  195. /* handled. */
  196. /* R_BFIN_BYTE and R_BFIN_BYTE2 are also not handled as the */
  197. /* gas does not generate it. */
  198. /*************************************************************************/
  199. int
  200. apply_relocate_add(Elf_Shdr * sechdrs, const char *strtab,
  201. unsigned int symindex, unsigned int relsec,
  202. struct module *mod)
  203. {
  204. unsigned int i;
  205. unsigned short tmp;
  206. Elf32_Rela *rel = (void *)sechdrs[relsec].sh_addr;
  207. Elf32_Sym *sym;
  208. uint32_t *location32;
  209. uint16_t *location16;
  210. uint32_t value;
  211. pr_debug("Applying relocate section %u to %u\n", relsec,
  212. sechdrs[relsec].sh_info);
  213. for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
  214. /* This is where to make the change */
  215. location16 =
  216. (uint16_t *) (sechdrs[sechdrs[relsec].sh_info].sh_addr +
  217. rel[i].r_offset);
  218. location32 = (uint32_t *) location16;
  219. /* This is the symbol it is referring to. Note that all
  220. undefined symbols have been resolved. */
  221. sym = (Elf32_Sym *) sechdrs[symindex].sh_addr
  222. + ELF32_R_SYM(rel[i].r_info);
  223. value = sym->st_value;
  224. value += rel[i].r_addend;
  225. pr_debug("location is %x, value is %x type is %d \n",
  226. (unsigned int) location32, value,
  227. ELF32_R_TYPE(rel[i].r_info));
  228. #ifdef CONFIG_SMP
  229. if ((unsigned long)location16 >= COREB_L1_DATA_A_START) {
  230. printk(KERN_ERR "module %s: cannot relocate in L1: %u (SMP kernel)",
  231. mod->name, ELF32_R_TYPE(rel[i].r_info));
  232. return -ENOEXEC;
  233. }
  234. #endif
  235. switch (ELF32_R_TYPE(rel[i].r_info)) {
  236. case R_BFIN_PCREL24:
  237. case R_BFIN_PCREL24_JUMP_L:
  238. /* Add the value, subtract its postition */
  239. location16 =
  240. (uint16_t *) (sechdrs[sechdrs[relsec].sh_info].
  241. sh_addr + rel[i].r_offset - 2);
  242. location32 = (uint32_t *) location16;
  243. value -= (uint32_t) location32;
  244. value >>= 1;
  245. if ((value & 0xFF000000) != 0 &&
  246. (value & 0xFF000000) != 0xFF000000) {
  247. printk(KERN_ERR "module %s: relocation overflow\n",
  248. mod->name);
  249. return -ENOEXEC;
  250. }
  251. pr_debug("value is %x, before %x-%x after %x-%x\n", value,
  252. *location16, *(location16 + 1),
  253. (*location16 & 0xff00) | (value >> 16 & 0x00ff),
  254. value & 0xffff);
  255. *location16 =
  256. (*location16 & 0xff00) | (value >> 16 & 0x00ff);
  257. *(location16 + 1) = value & 0xffff;
  258. break;
  259. case R_BFIN_PCREL12_JUMP:
  260. case R_BFIN_PCREL12_JUMP_S:
  261. value -= (uint32_t) location32;
  262. value >>= 1;
  263. *location16 = (value & 0xfff);
  264. break;
  265. case R_BFIN_PCREL10:
  266. value -= (uint32_t) location32;
  267. value >>= 1;
  268. *location16 = (value & 0x3ff);
  269. break;
  270. case R_BFIN_LUIMM16:
  271. pr_debug("before %x after %x\n", *location16,
  272. (value & 0xffff));
  273. tmp = (value & 0xffff);
  274. if ((unsigned long)location16 >= L1_CODE_START) {
  275. dma_memcpy(location16, &tmp, 2);
  276. } else
  277. *location16 = tmp;
  278. break;
  279. case R_BFIN_HUIMM16:
  280. pr_debug("before %x after %x\n", *location16,
  281. ((value >> 16) & 0xffff));
  282. tmp = ((value >> 16) & 0xffff);
  283. if ((unsigned long)location16 >= L1_CODE_START) {
  284. dma_memcpy(location16, &tmp, 2);
  285. } else
  286. *location16 = tmp;
  287. break;
  288. case R_BFIN_RIMM16:
  289. *location16 = (value & 0xffff);
  290. break;
  291. case R_BFIN_BYTE4_DATA:
  292. pr_debug("before %x after %x\n", *location32, value);
  293. *location32 = value;
  294. break;
  295. default:
  296. printk(KERN_ERR "module %s: Unknown relocation: %u\n",
  297. mod->name, ELF32_R_TYPE(rel[i].r_info));
  298. return -ENOEXEC;
  299. }
  300. }
  301. return 0;
  302. }
  303. int
  304. module_finalize(const Elf_Ehdr * hdr,
  305. const Elf_Shdr * sechdrs, struct module *mod)
  306. {
  307. unsigned int i, strindex = 0, symindex = 0;
  308. char *secstrings;
  309. long err = 0;
  310. secstrings = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
  311. for (i = 1; i < hdr->e_shnum; i++) {
  312. /* Internal symbols and strings. */
  313. if (sechdrs[i].sh_type == SHT_SYMTAB) {
  314. symindex = i;
  315. strindex = sechdrs[i].sh_link;
  316. }
  317. }
  318. for (i = 1; i < hdr->e_shnum; i++) {
  319. const char *strtab = (char *)sechdrs[strindex].sh_addr;
  320. unsigned int info = sechdrs[i].sh_info;
  321. /* Not a valid relocation section? */
  322. if (info >= hdr->e_shnum)
  323. continue;
  324. if ((sechdrs[i].sh_type == SHT_RELA) &&
  325. ((strcmp(".rela.l2.text", secstrings + sechdrs[i].sh_name) == 0) ||
  326. (strcmp(".rela.l1.text", secstrings + sechdrs[i].sh_name) == 0) ||
  327. ((strcmp(".rela.text", secstrings + sechdrs[i].sh_name) == 0) &&
  328. (hdr->e_flags & (EF_BFIN_CODE_IN_L1|EF_BFIN_CODE_IN_L2))))) {
  329. err = apply_relocate_add((Elf_Shdr *) sechdrs, strtab,
  330. symindex, i, mod);
  331. if (err < 0)
  332. return -ENOEXEC;
  333. }
  334. }
  335. return 0;
  336. }
  337. void module_arch_cleanup(struct module *mod)
  338. {
  339. l1_inst_sram_free(mod->arch.text_l1);
  340. l1_data_A_sram_free(mod->arch.data_a_l1);
  341. l1_data_A_sram_free(mod->arch.bss_a_l1);
  342. l1_data_B_sram_free(mod->arch.data_b_l1);
  343. l1_data_B_sram_free(mod->arch.bss_b_l1);
  344. l2_sram_free(mod->arch.text_l2);
  345. l2_sram_free(mod->arch.data_l2);
  346. l2_sram_free(mod->arch.bss_l2);
  347. }