aot_reloc_arc.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419
  1. /*
  2. * Copyright (C) 2019 Intel Corporation. All rights reserved.
  3. * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. */
  5. #include "aot_reloc.h"
  6. #define R_ARC_S21H_PCREL 14
  7. #define R_ARC_S21W_PCREL 15
  8. #define R_ARC_S25H_PCREL 16
  9. #define R_ARC_S25W_PCREL 17
  10. #define R_ARC_32 4
  11. #define R_ARC_32_ME 27
  12. /* clang-format off */
  13. #ifndef __CCAC__
  14. void __st_r13_to_r15();
  15. void __st_r13_to_r16();
  16. void __st_r13_to_r17();
  17. void __st_r13_to_r18();
  18. void __st_r13_to_r19();
  19. void __st_r13_to_r20();
  20. void __st_r13_to_r21();
  21. void __st_r13_to_r22();
  22. void __st_r13_to_r23();
  23. void __st_r13_to_r24();
  24. void __st_r13_to_r25();
  25. void __ld_r13_to_r15();
  26. void __ld_r13_to_r16();
  27. void __ld_r13_to_r17();
  28. void __ld_r13_to_r18();
  29. void __ld_r13_to_r19();
  30. void __ld_r13_to_r20();
  31. void __ld_r13_to_r21();
  32. void __ld_r13_to_r22();
  33. void __ld_r13_to_r23();
  34. void __ld_r13_to_r24();
  35. void __ld_r13_to_r25();
  36. void __adddf3();
  37. void __addsf3();
  38. void __divdf3();
  39. void __divdi3();
  40. void __divsf3();
  41. void __divsi3();
  42. void __extendsfdf2();
  43. void __fixdfsi();
  44. void __floatsidf();
  45. void __floatsisf();
  46. void __muldf3();
  47. void __mulsf3();
  48. void __subdf3();
  49. void __subsf3();
  50. void __truncdfsf2();
  51. void __floatunsisf();
  52. void __fixunsdfsi();
  53. void __floatdisf();
  54. void __floatdidf();
  55. void __fixdfdi();
  56. void __ltsf2();
  57. void __gesf2();
  58. void __eqdf2();
  59. void __nedf2();
  60. void __ltsf2();
  61. void __nesf2();
  62. void __unordsf2();
  63. void __fixunssfsi();
  64. #else
  65. void __ac_push_13_to_13();
  66. void __ac_push_13_to_14();
  67. void __ac_push_13_to_15();
  68. void __ac_push_13_to_16();
  69. void __ac_push_13_to_17();
  70. void __ac_push_13_to_18();
  71. void __ac_push_13_to_19();
  72. void __ac_push_13_to_20();
  73. void __ac_push_13_to_21();
  74. void __ac_push_13_to_22();
  75. void __ac_push_13_to_23();
  76. void __ac_push_13_to_24();
  77. void __ac_push_13_to_25();
  78. void __ac_push_13_to_26();
  79. void __ac_push_none();
  80. void __ac_pop_13_to_26();
  81. void __ac_pop_13_to_26v();
  82. void __ac_pop_13_to_25();
  83. void __ac_pop_13_to_25v();
  84. void __ac_pop_13_to_24();
  85. void __ac_pop_13_to_24v();
  86. void __ac_pop_13_to_23();
  87. void __ac_pop_13_to_23v();
  88. void __ac_pop_13_to_22();
  89. void __ac_pop_13_to_22v();
  90. void __ac_pop_13_to_21();
  91. void __ac_pop_13_to_21v();
  92. void __ac_pop_13_to_20();
  93. void __ac_pop_13_to_20v();
  94. void __ac_pop_13_to_19();
  95. void __ac_pop_13_to_19v();
  96. void __ac_pop_13_to_18();
  97. void __ac_pop_13_to_18v();
  98. void __ac_pop_13_to_17();
  99. void __ac_pop_13_to_17v();
  100. void __ac_pop_13_to_16();
  101. void __ac_pop_13_to_16v();
  102. void __ac_pop_13_to_15();
  103. void __ac_pop_13_to_15v();
  104. void __ac_pop_13_to_14();
  105. void __ac_pop_13_to_14v();
  106. void __ac_pop_13_to_13();
  107. void __ac_pop_13_to_13v();
  108. void __ac_pop_none();
  109. void __ac_pop_nonev();
  110. void __eqdf2();
  111. void __nedf2();
  112. void __ltsf2();
  113. void __nesf2();
  114. void __gesf2();
  115. void __gtsf2();
  116. void __unordsf2();
  117. void __truncdfhf2();
  118. void __truncsfhf2();
  119. #endif /* end of __CCAC__ */
  120. void __ledf2();
  121. void __ltdf2();
  122. void __gedf2();
  123. void __gtdf2();
  124. void __eqsf2();
  125. void __lesf2();
  126. void __unorddf2();
  127. /* clang-format on */
  128. static SymbolMap target_sym_map[] = {
  129. /* clang-format off */
  130. REG_COMMON_SYMBOLS
  131. #ifndef __CCAC__
  132. REG_SYM(__st_r13_to_r15),
  133. REG_SYM(__st_r13_to_r16),
  134. REG_SYM(__st_r13_to_r17),
  135. REG_SYM(__st_r13_to_r18),
  136. REG_SYM(__st_r13_to_r19),
  137. REG_SYM(__st_r13_to_r20),
  138. REG_SYM(__st_r13_to_r21),
  139. REG_SYM(__st_r13_to_r22),
  140. REG_SYM(__st_r13_to_r23),
  141. REG_SYM(__st_r13_to_r24),
  142. REG_SYM(__st_r13_to_r25),
  143. REG_SYM(__ld_r13_to_r15),
  144. REG_SYM(__ld_r13_to_r16),
  145. REG_SYM(__ld_r13_to_r17),
  146. REG_SYM(__ld_r13_to_r18),
  147. REG_SYM(__ld_r13_to_r19),
  148. REG_SYM(__ld_r13_to_r20),
  149. REG_SYM(__ld_r13_to_r21),
  150. REG_SYM(__ld_r13_to_r22),
  151. REG_SYM(__ld_r13_to_r23),
  152. REG_SYM(__ld_r13_to_r24),
  153. REG_SYM(__ld_r13_to_r25),
  154. REG_SYM(__adddf3),
  155. REG_SYM(__addsf3),
  156. REG_SYM(__divdf3),
  157. REG_SYM(__divdi3),
  158. REG_SYM(__divsf3),
  159. REG_SYM(__divsi3),
  160. REG_SYM(__extendsfdf2),
  161. REG_SYM(__fixdfsi),
  162. REG_SYM(__floatsidf),
  163. REG_SYM(__floatsisf),
  164. REG_SYM(__muldf3),
  165. REG_SYM(__mulsf3),
  166. REG_SYM(__subdf3),
  167. REG_SYM(__subsf3),
  168. REG_SYM(__truncdfsf2),
  169. REG_SYM(__floatunsisf),
  170. REG_SYM(__fixunsdfsi),
  171. REG_SYM(__floatdisf),
  172. REG_SYM(__floatdidf),
  173. REG_SYM(__fixdfdi),
  174. REG_SYM(__ltsf2),
  175. REG_SYM(__gesf2),
  176. REG_SYM(__eqdf2),
  177. REG_SYM(__nedf2),
  178. REG_SYM(__ltsf2),
  179. REG_SYM(__nesf2),
  180. REG_SYM(__unordsf2),
  181. REG_SYM(__fixunssfsi),
  182. #else
  183. REG_SYM(__ac_push_13_to_13),
  184. REG_SYM(__ac_push_13_to_14),
  185. REG_SYM(__ac_push_13_to_15),
  186. REG_SYM(__ac_push_13_to_16),
  187. REG_SYM(__ac_push_13_to_17),
  188. REG_SYM(__ac_push_13_to_18),
  189. REG_SYM(__ac_push_13_to_19),
  190. REG_SYM(__ac_push_13_to_20),
  191. REG_SYM(__ac_push_13_to_21),
  192. REG_SYM(__ac_push_13_to_22),
  193. REG_SYM(__ac_push_13_to_23),
  194. REG_SYM(__ac_push_13_to_24),
  195. REG_SYM(__ac_push_13_to_25),
  196. REG_SYM(__ac_push_13_to_26),
  197. REG_SYM(__ac_push_none),
  198. REG_SYM(__ac_pop_13_to_26),
  199. REG_SYM(__ac_pop_13_to_26v),
  200. REG_SYM(__ac_pop_13_to_25),
  201. REG_SYM(__ac_pop_13_to_25v),
  202. REG_SYM(__ac_pop_13_to_24),
  203. REG_SYM(__ac_pop_13_to_24v),
  204. REG_SYM(__ac_pop_13_to_23),
  205. REG_SYM(__ac_pop_13_to_23v),
  206. REG_SYM(__ac_pop_13_to_22),
  207. REG_SYM(__ac_pop_13_to_22v),
  208. REG_SYM(__ac_pop_13_to_21),
  209. REG_SYM(__ac_pop_13_to_21v),
  210. REG_SYM(__ac_pop_13_to_20),
  211. REG_SYM(__ac_pop_13_to_20v),
  212. REG_SYM(__ac_pop_13_to_19),
  213. REG_SYM(__ac_pop_13_to_19v),
  214. REG_SYM(__ac_pop_13_to_18),
  215. REG_SYM(__ac_pop_13_to_18v),
  216. REG_SYM(__ac_pop_13_to_17),
  217. REG_SYM(__ac_pop_13_to_17v),
  218. REG_SYM(__ac_pop_13_to_16),
  219. REG_SYM(__ac_pop_13_to_16v),
  220. REG_SYM(__ac_pop_13_to_15),
  221. REG_SYM(__ac_pop_13_to_15v),
  222. REG_SYM(__ac_pop_13_to_14),
  223. REG_SYM(__ac_pop_13_to_14v),
  224. REG_SYM(__ac_pop_13_to_13),
  225. REG_SYM(__ac_pop_13_to_13v),
  226. REG_SYM(__ac_pop_none),
  227. REG_SYM(__ac_pop_nonev),
  228. REG_SYM(__eqdf2),
  229. REG_SYM(__nedf2),
  230. REG_SYM(__ltsf2),
  231. REG_SYM(__nesf2),
  232. REG_SYM(__gesf2),
  233. REG_SYM(__gtsf2),
  234. REG_SYM(__unordsf2),
  235. REG_SYM(__truncdfhf2),
  236. REG_SYM(__truncsfhf2),
  237. #endif /* end of __CCAC__ */
  238. REG_SYM(__ledf2),
  239. REG_SYM(__ltdf2),
  240. REG_SYM(__gedf2),
  241. REG_SYM(__gtdf2),
  242. REG_SYM(__eqsf2),
  243. REG_SYM(__lesf2),
  244. REG_SYM(__unorddf2),
  245. /* clang-format on */
  246. };
  247. static void
  248. set_error_buf(char *error_buf, uint32 error_buf_size, const char *string)
  249. {
  250. if (error_buf != NULL)
  251. snprintf(error_buf, error_buf_size, "%s", string);
  252. }
  253. SymbolMap *
  254. get_target_symbol_map(uint32 *sym_num)
  255. {
  256. *sym_num = sizeof(target_sym_map) / sizeof(SymbolMap);
  257. return target_sym_map;
  258. }
  259. void
  260. get_current_target(char *target_buf, uint32 target_buf_size)
  261. {
  262. snprintf(target_buf, target_buf_size, "arc");
  263. }
  264. uint32
  265. get_plt_table_size()
  266. {
  267. return 0;
  268. }
  269. void
  270. init_plt_table(uint8 *plt)
  271. {
  272. (void)plt;
  273. }
  274. static bool
  275. check_reloc_offset(uint32 target_section_size, uint64 reloc_offset,
  276. uint32 reloc_data_size, char *error_buf,
  277. uint32 error_buf_size)
  278. {
  279. if (!(reloc_offset < (uint64)target_section_size
  280. && reloc_offset + reloc_data_size <= (uint64)target_section_size)) {
  281. set_error_buf(error_buf, error_buf_size,
  282. "AOT module load failed: invalid relocation offset.");
  283. return false;
  284. }
  285. return true;
  286. }
  287. static uint32
  288. middle_endian_convert(uint32 insn)
  289. {
  290. return ((insn & 0xFFFF0000) >> 16) | ((insn & 0x0000FFFF) << 16);
  291. }
  292. bool
  293. apply_relocation(AOTModule *module, uint8 *target_section_addr,
  294. uint32 target_section_size, uint64 reloc_offset,
  295. int64 reloc_addend, uint32 reloc_type, void *symbol_addr,
  296. int32 symbol_index, char *error_buf, uint32 error_buf_size)
  297. {
  298. switch (reloc_type) {
  299. case R_ARC_S25H_PCREL:
  300. {
  301. uint32 insn = LOAD_I32(target_section_addr + reloc_offset);
  302. int32 addend, value;
  303. uintptr_t S, P;
  304. intptr_t A;
  305. CHECK_RELOC_OFFSET(sizeof(void *));
  306. /* Convert from middle endian */
  307. insn = middle_endian_convert(insn);
  308. addend = ((insn << 28) >> 28) << 10;
  309. /* Extract the next 10 bits from Position 6 to 15 in insn */
  310. addend |= ((insn << 16) >> 22);
  311. addend = addend << 10;
  312. /* Extract the remaining 10 bits from Position 17 to 26 in insn */
  313. addend |= ((insn << 5) >> 22);
  314. /* Fill in 1 bits to get the 25 bit Offset Value */
  315. addend = addend << 1;
  316. /* (S + A) - P */
  317. S = (uintptr_t)(uint8 *)symbol_addr;
  318. A = (intptr_t)reloc_addend;
  319. P = (uintptr_t)(target_section_addr + reloc_offset);
  320. P &= (uintptr_t)~1;
  321. value = (int32)(S + A + addend - P);
  322. insn = insn & 0xf8010030;
  323. insn |= ((((value >> 1) & 0x3ff) << 17)
  324. | (((value >> 1) & 0xffc00) >> 3)
  325. | (((value >> 1) & 0xf00000) >> 19));
  326. /* Convert to middle endian */
  327. insn = middle_endian_convert(insn);
  328. STORE_U32(target_section_addr + reloc_offset, insn);
  329. break;
  330. }
  331. case R_ARC_S25W_PCREL:
  332. {
  333. uint32 insn = LOAD_I32(target_section_addr + reloc_offset);
  334. int32 addend, value;
  335. uintptr_t S, P;
  336. intptr_t A;
  337. CHECK_RELOC_OFFSET(sizeof(void *));
  338. /* Convert from middle endian */
  339. insn = middle_endian_convert(insn);
  340. addend = ((insn << 28) >> 28) << 10;
  341. /* Extract the next 10 bits from Position 6 to 15 in insn */
  342. addend |= ((insn << 16) >> 22);
  343. addend = addend << 9;
  344. /* Extract the remaining 9 bits from Position 18 to 26 in insn */
  345. addend |= ((insn << 5) >> 23);
  346. /* Fill in 2 bits to get the 25 bit Offset Value */
  347. addend = addend << 2;
  348. /* (S + A) - P */
  349. S = (uintptr_t)(uint8 *)symbol_addr;
  350. A = (intptr_t)reloc_addend;
  351. P = (uintptr_t)(target_section_addr + reloc_offset);
  352. P &= (uintptr_t)~3;
  353. value = (int32)(S + A + addend - P);
  354. insn = insn & 0xf8030030;
  355. insn |= ((((value >> 2) & 0x1ff) << 18)
  356. | (((value >> 2) & 0x7fe00) >> 3)
  357. | (((value >> 2) & 0x780000) >> 19));
  358. /* Convert to middle endian */
  359. insn = middle_endian_convert(insn);
  360. STORE_U32(target_section_addr + reloc_offset, insn);
  361. break;
  362. }
  363. case R_ARC_32:
  364. case R_ARC_32_ME:
  365. {
  366. uint32 insn;
  367. CHECK_RELOC_OFFSET(sizeof(void *));
  368. /* (S + A) */
  369. insn = (uint32)((uintptr_t)symbol_addr + (intptr_t)reloc_addend);
  370. if (reloc_type == R_ARC_32_ME)
  371. /* Convert to middle endian */
  372. insn = middle_endian_convert(insn);
  373. STORE_U32(target_section_addr + reloc_offset, insn);
  374. break;
  375. }
  376. default:
  377. {
  378. if (error_buf != NULL)
  379. snprintf(error_buf, error_buf_size,
  380. "Load relocation section failed: "
  381. "invalid relocation type %d.",
  382. reloc_type);
  383. return false;
  384. }
  385. }
  386. return true;
  387. }