module.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456
  1. /*
  2. * AArch64 loadable module support.
  3. *
  4. * Copyright (C) 2012 ARM Limited
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License version 2 as
  8. * published by the Free Software Foundation.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. *
  18. * Author: Will Deacon <will.deacon@arm.com>
  19. */
  20. #include <linux/bitops.h>
  21. #include <linux/elf.h>
  22. #include <linux/gfp.h>
  23. #include <linux/kernel.h>
  24. #include <linux/mm.h>
  25. #include <linux/moduleloader.h>
  26. #include <linux/vmalloc.h>
  27. void *module_alloc(unsigned long size)
  28. {
  29. return __vmalloc_node_range(size, 1, MODULES_VADDR, MODULES_END,
  30. GFP_KERNEL, PAGE_KERNEL_EXEC, -1,
  31. __builtin_return_address(0));
  32. }
  33. enum aarch64_reloc_op {
  34. RELOC_OP_NONE,
  35. RELOC_OP_ABS,
  36. RELOC_OP_PREL,
  37. RELOC_OP_PAGE,
  38. };
  39. static u64 do_reloc(enum aarch64_reloc_op reloc_op, void *place, u64 val)
  40. {
  41. switch (reloc_op) {
  42. case RELOC_OP_ABS:
  43. return val;
  44. case RELOC_OP_PREL:
  45. return val - (u64)place;
  46. case RELOC_OP_PAGE:
  47. return (val & ~0xfff) - ((u64)place & ~0xfff);
  48. case RELOC_OP_NONE:
  49. return 0;
  50. }
  51. pr_err("do_reloc: unknown relocation operation %d\n", reloc_op);
  52. return 0;
  53. }
  54. static int reloc_data(enum aarch64_reloc_op op, void *place, u64 val, int len)
  55. {
  56. u64 imm_mask = (1 << len) - 1;
  57. s64 sval = do_reloc(op, place, val);
  58. switch (len) {
  59. case 16:
  60. *(s16 *)place = sval;
  61. break;
  62. case 32:
  63. *(s32 *)place = sval;
  64. break;
  65. case 64:
  66. *(s64 *)place = sval;
  67. break;
  68. default:
  69. pr_err("Invalid length (%d) for data relocation\n", len);
  70. return 0;
  71. }
  72. /*
  73. * Extract the upper value bits (including the sign bit) and
  74. * shift them to bit 0.
  75. */
  76. sval = (s64)(sval & ~(imm_mask >> 1)) >> (len - 1);
  77. /*
  78. * Overflow has occurred if the value is not representable in
  79. * len bits (i.e the bottom len bits are not sign-extended and
  80. * the top bits are not all zero).
  81. */
  82. if ((u64)(sval + 1) > 2)
  83. return -ERANGE;
  84. return 0;
  85. }
  86. enum aarch64_imm_type {
  87. INSN_IMM_MOVNZ,
  88. INSN_IMM_MOVK,
  89. INSN_IMM_ADR,
  90. INSN_IMM_26,
  91. INSN_IMM_19,
  92. INSN_IMM_16,
  93. INSN_IMM_14,
  94. INSN_IMM_12,
  95. INSN_IMM_9,
  96. };
  97. static u32 encode_insn_immediate(enum aarch64_imm_type type, u32 insn, u64 imm)
  98. {
  99. u32 immlo, immhi, lomask, himask, mask;
  100. int shift;
  101. switch (type) {
  102. case INSN_IMM_MOVNZ:
  103. /*
  104. * For signed MOVW relocations, we have to manipulate the
  105. * instruction encoding depending on whether or not the
  106. * immediate is less than zero.
  107. */
  108. insn &= ~(3 << 29);
  109. if ((s64)imm >= 0) {
  110. /* >=0: Set the instruction to MOVZ (opcode 10b). */
  111. insn |= 2 << 29;
  112. } else {
  113. /*
  114. * <0: Set the instruction to MOVN (opcode 00b).
  115. * Since we've masked the opcode already, we
  116. * don't need to do anything other than
  117. * inverting the new immediate field.
  118. */
  119. imm = ~imm;
  120. }
  121. case INSN_IMM_MOVK:
  122. mask = BIT(16) - 1;
  123. shift = 5;
  124. break;
  125. case INSN_IMM_ADR:
  126. lomask = 0x3;
  127. himask = 0x7ffff;
  128. immlo = imm & lomask;
  129. imm >>= 2;
  130. immhi = imm & himask;
  131. imm = (immlo << 24) | (immhi);
  132. mask = (lomask << 24) | (himask);
  133. shift = 5;
  134. break;
  135. case INSN_IMM_26:
  136. mask = BIT(26) - 1;
  137. shift = 0;
  138. break;
  139. case INSN_IMM_19:
  140. mask = BIT(19) - 1;
  141. shift = 5;
  142. break;
  143. case INSN_IMM_16:
  144. mask = BIT(16) - 1;
  145. shift = 5;
  146. break;
  147. case INSN_IMM_14:
  148. mask = BIT(14) - 1;
  149. shift = 5;
  150. break;
  151. case INSN_IMM_12:
  152. mask = BIT(12) - 1;
  153. shift = 10;
  154. break;
  155. case INSN_IMM_9:
  156. mask = BIT(9) - 1;
  157. shift = 12;
  158. break;
  159. default:
  160. pr_err("encode_insn_immediate: unknown immediate encoding %d\n",
  161. type);
  162. return 0;
  163. }
  164. /* Update the immediate field. */
  165. insn &= ~(mask << shift);
  166. insn |= (imm & mask) << shift;
  167. return insn;
  168. }
  169. static int reloc_insn_movw(enum aarch64_reloc_op op, void *place, u64 val,
  170. int lsb, enum aarch64_imm_type imm_type)
  171. {
  172. u64 imm, limit = 0;
  173. s64 sval;
  174. u32 insn = *(u32 *)place;
  175. sval = do_reloc(op, place, val);
  176. sval >>= lsb;
  177. imm = sval & 0xffff;
  178. /* Update the instruction with the new encoding. */
  179. *(u32 *)place = encode_insn_immediate(imm_type, insn, imm);
  180. /* Shift out the immediate field. */
  181. sval >>= 16;
  182. /*
  183. * For unsigned immediates, the overflow check is straightforward.
  184. * For signed immediates, the sign bit is actually the bit past the
  185. * most significant bit of the field.
  186. * The INSN_IMM_16 immediate type is unsigned.
  187. */
  188. if (imm_type != INSN_IMM_16) {
  189. sval++;
  190. limit++;
  191. }
  192. /* Check the upper bits depending on the sign of the immediate. */
  193. if ((u64)sval > limit)
  194. return -ERANGE;
  195. return 0;
  196. }
  197. static int reloc_insn_imm(enum aarch64_reloc_op op, void *place, u64 val,
  198. int lsb, int len, enum aarch64_imm_type imm_type)
  199. {
  200. u64 imm, imm_mask;
  201. s64 sval;
  202. u32 insn = *(u32 *)place;
  203. /* Calculate the relocation value. */
  204. sval = do_reloc(op, place, val);
  205. sval >>= lsb;
  206. /* Extract the value bits and shift them to bit 0. */
  207. imm_mask = (BIT(lsb + len) - 1) >> lsb;
  208. imm = sval & imm_mask;
  209. /* Update the instruction's immediate field. */
  210. *(u32 *)place = encode_insn_immediate(imm_type, insn, imm);
  211. /*
  212. * Extract the upper value bits (including the sign bit) and
  213. * shift them to bit 0.
  214. */
  215. sval = (s64)(sval & ~(imm_mask >> 1)) >> (len - 1);
  216. /*
  217. * Overflow has occurred if the upper bits are not all equal to
  218. * the sign bit of the value.
  219. */
  220. if ((u64)(sval + 1) >= 2)
  221. return -ERANGE;
  222. return 0;
  223. }
  224. int apply_relocate_add(Elf64_Shdr *sechdrs,
  225. const char *strtab,
  226. unsigned int symindex,
  227. unsigned int relsec,
  228. struct module *me)
  229. {
  230. unsigned int i;
  231. int ovf;
  232. bool overflow_check;
  233. Elf64_Sym *sym;
  234. void *loc;
  235. u64 val;
  236. Elf64_Rela *rel = (void *)sechdrs[relsec].sh_addr;
  237. for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
  238. /* loc corresponds to P in the AArch64 ELF document. */
  239. loc = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
  240. + rel[i].r_offset;
  241. /* sym is the ELF symbol we're referring to. */
  242. sym = (Elf64_Sym *)sechdrs[symindex].sh_addr
  243. + ELF64_R_SYM(rel[i].r_info);
  244. /* val corresponds to (S + A) in the AArch64 ELF document. */
  245. val = sym->st_value + rel[i].r_addend;
  246. /* Check for overflow by default. */
  247. overflow_check = true;
  248. /* Perform the static relocation. */
  249. switch (ELF64_R_TYPE(rel[i].r_info)) {
  250. /* Null relocations. */
  251. case R_ARM_NONE:
  252. case R_AARCH64_NONE:
  253. ovf = 0;
  254. break;
  255. /* Data relocations. */
  256. case R_AARCH64_ABS64:
  257. overflow_check = false;
  258. ovf = reloc_data(RELOC_OP_ABS, loc, val, 64);
  259. break;
  260. case R_AARCH64_ABS32:
  261. ovf = reloc_data(RELOC_OP_ABS, loc, val, 32);
  262. break;
  263. case R_AARCH64_ABS16:
  264. ovf = reloc_data(RELOC_OP_ABS, loc, val, 16);
  265. break;
  266. case R_AARCH64_PREL64:
  267. overflow_check = false;
  268. ovf = reloc_data(RELOC_OP_PREL, loc, val, 64);
  269. break;
  270. case R_AARCH64_PREL32:
  271. ovf = reloc_data(RELOC_OP_PREL, loc, val, 32);
  272. break;
  273. case R_AARCH64_PREL16:
  274. ovf = reloc_data(RELOC_OP_PREL, loc, val, 16);
  275. break;
  276. /* MOVW instruction relocations. */
  277. case R_AARCH64_MOVW_UABS_G0_NC:
  278. overflow_check = false;
  279. case R_AARCH64_MOVW_UABS_G0:
  280. ovf = reloc_insn_movw(RELOC_OP_ABS, loc, val, 0,
  281. INSN_IMM_16);
  282. break;
  283. case R_AARCH64_MOVW_UABS_G1_NC:
  284. overflow_check = false;
  285. case R_AARCH64_MOVW_UABS_G1:
  286. ovf = reloc_insn_movw(RELOC_OP_ABS, loc, val, 16,
  287. INSN_IMM_16);
  288. break;
  289. case R_AARCH64_MOVW_UABS_G2_NC:
  290. overflow_check = false;
  291. case R_AARCH64_MOVW_UABS_G2:
  292. ovf = reloc_insn_movw(RELOC_OP_ABS, loc, val, 32,
  293. INSN_IMM_16);
  294. break;
  295. case R_AARCH64_MOVW_UABS_G3:
  296. /* We're using the top bits so we can't overflow. */
  297. overflow_check = false;
  298. ovf = reloc_insn_movw(RELOC_OP_ABS, loc, val, 48,
  299. INSN_IMM_16);
  300. break;
  301. case R_AARCH64_MOVW_SABS_G0:
  302. ovf = reloc_insn_movw(RELOC_OP_ABS, loc, val, 0,
  303. INSN_IMM_MOVNZ);
  304. break;
  305. case R_AARCH64_MOVW_SABS_G1:
  306. ovf = reloc_insn_movw(RELOC_OP_ABS, loc, val, 16,
  307. INSN_IMM_MOVNZ);
  308. break;
  309. case R_AARCH64_MOVW_SABS_G2:
  310. ovf = reloc_insn_movw(RELOC_OP_ABS, loc, val, 32,
  311. INSN_IMM_MOVNZ);
  312. break;
  313. case R_AARCH64_MOVW_PREL_G0_NC:
  314. overflow_check = false;
  315. ovf = reloc_insn_movw(RELOC_OP_PREL, loc, val, 0,
  316. INSN_IMM_MOVK);
  317. break;
  318. case R_AARCH64_MOVW_PREL_G0:
  319. ovf = reloc_insn_movw(RELOC_OP_PREL, loc, val, 0,
  320. INSN_IMM_MOVNZ);
  321. break;
  322. case R_AARCH64_MOVW_PREL_G1_NC:
  323. overflow_check = false;
  324. ovf = reloc_insn_movw(RELOC_OP_PREL, loc, val, 16,
  325. INSN_IMM_MOVK);
  326. break;
  327. case R_AARCH64_MOVW_PREL_G1:
  328. ovf = reloc_insn_movw(RELOC_OP_PREL, loc, val, 16,
  329. INSN_IMM_MOVNZ);
  330. break;
  331. case R_AARCH64_MOVW_PREL_G2_NC:
  332. overflow_check = false;
  333. ovf = reloc_insn_movw(RELOC_OP_PREL, loc, val, 32,
  334. INSN_IMM_MOVK);
  335. break;
  336. case R_AARCH64_MOVW_PREL_G2:
  337. ovf = reloc_insn_movw(RELOC_OP_PREL, loc, val, 32,
  338. INSN_IMM_MOVNZ);
  339. break;
  340. case R_AARCH64_MOVW_PREL_G3:
  341. /* We're using the top bits so we can't overflow. */
  342. overflow_check = false;
  343. ovf = reloc_insn_movw(RELOC_OP_PREL, loc, val, 48,
  344. INSN_IMM_MOVNZ);
  345. break;
  346. /* Immediate instruction relocations. */
  347. case R_AARCH64_LD_PREL_LO19:
  348. ovf = reloc_insn_imm(RELOC_OP_PREL, loc, val, 2, 19,
  349. INSN_IMM_19);
  350. break;
  351. case R_AARCH64_ADR_PREL_LO21:
  352. ovf = reloc_insn_imm(RELOC_OP_PREL, loc, val, 0, 21,
  353. INSN_IMM_ADR);
  354. break;
  355. case R_AARCH64_ADR_PREL_PG_HI21_NC:
  356. overflow_check = false;
  357. case R_AARCH64_ADR_PREL_PG_HI21:
  358. ovf = reloc_insn_imm(RELOC_OP_PAGE, loc, val, 12, 21,
  359. INSN_IMM_ADR);
  360. break;
  361. case R_AARCH64_ADD_ABS_LO12_NC:
  362. case R_AARCH64_LDST8_ABS_LO12_NC:
  363. overflow_check = false;
  364. ovf = reloc_insn_imm(RELOC_OP_ABS, loc, val, 0, 12,
  365. INSN_IMM_12);
  366. break;
  367. case R_AARCH64_LDST16_ABS_LO12_NC:
  368. overflow_check = false;
  369. ovf = reloc_insn_imm(RELOC_OP_ABS, loc, val, 1, 11,
  370. INSN_IMM_12);
  371. break;
  372. case R_AARCH64_LDST32_ABS_LO12_NC:
  373. overflow_check = false;
  374. ovf = reloc_insn_imm(RELOC_OP_ABS, loc, val, 2, 10,
  375. INSN_IMM_12);
  376. break;
  377. case R_AARCH64_LDST64_ABS_LO12_NC:
  378. overflow_check = false;
  379. ovf = reloc_insn_imm(RELOC_OP_ABS, loc, val, 3, 9,
  380. INSN_IMM_12);
  381. break;
  382. case R_AARCH64_LDST128_ABS_LO12_NC:
  383. overflow_check = false;
  384. ovf = reloc_insn_imm(RELOC_OP_ABS, loc, val, 4, 8,
  385. INSN_IMM_12);
  386. break;
  387. case R_AARCH64_TSTBR14:
  388. ovf = reloc_insn_imm(RELOC_OP_PREL, loc, val, 2, 14,
  389. INSN_IMM_14);
  390. break;
  391. case R_AARCH64_CONDBR19:
  392. ovf = reloc_insn_imm(RELOC_OP_PREL, loc, val, 2, 19,
  393. INSN_IMM_19);
  394. break;
  395. case R_AARCH64_JUMP26:
  396. case R_AARCH64_CALL26:
  397. ovf = reloc_insn_imm(RELOC_OP_PREL, loc, val, 2, 26,
  398. INSN_IMM_26);
  399. break;
  400. default:
  401. pr_err("module %s: unsupported RELA relocation: %llu\n",
  402. me->name, ELF64_R_TYPE(rel[i].r_info));
  403. return -ENOEXEC;
  404. }
  405. if (overflow_check && ovf == -ERANGE)
  406. goto overflow;
  407. }
  408. return 0;
  409. overflow:
  410. pr_err("module %s: overflow in relocation type %d val %Lx\n",
  411. me->name, (int)ELF64_R_TYPE(rel[i].r_info), val);
  412. return -ENOEXEC;
  413. }