elf.h 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. /*
  3. * Copyright (C) 2020-2022 Loongson Technology Corporation Limited
  4. */
  5. #ifndef _ASM_ELF_H
  6. #define _ASM_ELF_H
  7. #include <linux/auxvec.h>
  8. #include <linux/fs.h>
  9. #include <uapi/linux/elf.h>
  10. #include <asm/current.h>
  11. #include <asm/vdso.h>
  12. /* The ABI of a file. */
  13. #define EF_LOONGARCH_ABI_LP64_SOFT_FLOAT 0x1
  14. #define EF_LOONGARCH_ABI_LP64_SINGLE_FLOAT 0x2
  15. #define EF_LOONGARCH_ABI_LP64_DOUBLE_FLOAT 0x3
  16. #define EF_LOONGARCH_ABI_ILP32_SOFT_FLOAT 0x5
  17. #define EF_LOONGARCH_ABI_ILP32_SINGLE_FLOAT 0x6
  18. #define EF_LOONGARCH_ABI_ILP32_DOUBLE_FLOAT 0x7
  19. /* LoongArch relocation types used by the dynamic linker */
  20. #define R_LARCH_NONE 0
  21. #define R_LARCH_32 1
  22. #define R_LARCH_64 2
  23. #define R_LARCH_RELATIVE 3
  24. #define R_LARCH_COPY 4
  25. #define R_LARCH_JUMP_SLOT 5
  26. #define R_LARCH_TLS_DTPMOD32 6
  27. #define R_LARCH_TLS_DTPMOD64 7
  28. #define R_LARCH_TLS_DTPREL32 8
  29. #define R_LARCH_TLS_DTPREL64 9
  30. #define R_LARCH_TLS_TPREL32 10
  31. #define R_LARCH_TLS_TPREL64 11
  32. #define R_LARCH_IRELATIVE 12
  33. #define R_LARCH_MARK_LA 20
  34. #define R_LARCH_MARK_PCREL 21
  35. #define R_LARCH_SOP_PUSH_PCREL 22
  36. #define R_LARCH_SOP_PUSH_ABSOLUTE 23
  37. #define R_LARCH_SOP_PUSH_DUP 24
  38. #define R_LARCH_SOP_PUSH_GPREL 25
  39. #define R_LARCH_SOP_PUSH_TLS_TPREL 26
  40. #define R_LARCH_SOP_PUSH_TLS_GOT 27
  41. #define R_LARCH_SOP_PUSH_TLS_GD 28
  42. #define R_LARCH_SOP_PUSH_PLT_PCREL 29
  43. #define R_LARCH_SOP_ASSERT 30
  44. #define R_LARCH_SOP_NOT 31
  45. #define R_LARCH_SOP_SUB 32
  46. #define R_LARCH_SOP_SL 33
  47. #define R_LARCH_SOP_SR 34
  48. #define R_LARCH_SOP_ADD 35
  49. #define R_LARCH_SOP_AND 36
  50. #define R_LARCH_SOP_IF_ELSE 37
  51. #define R_LARCH_SOP_POP_32_S_10_5 38
  52. #define R_LARCH_SOP_POP_32_U_10_12 39
  53. #define R_LARCH_SOP_POP_32_S_10_12 40
  54. #define R_LARCH_SOP_POP_32_S_10_16 41
  55. #define R_LARCH_SOP_POP_32_S_10_16_S2 42
  56. #define R_LARCH_SOP_POP_32_S_5_20 43
  57. #define R_LARCH_SOP_POP_32_S_0_5_10_16_S2 44
  58. #define R_LARCH_SOP_POP_32_S_0_10_10_16_S2 45
  59. #define R_LARCH_SOP_POP_32_U 46
  60. #define R_LARCH_ADD8 47
  61. #define R_LARCH_ADD16 48
  62. #define R_LARCH_ADD24 49
  63. #define R_LARCH_ADD32 50
  64. #define R_LARCH_ADD64 51
  65. #define R_LARCH_SUB8 52
  66. #define R_LARCH_SUB16 53
  67. #define R_LARCH_SUB24 54
  68. #define R_LARCH_SUB32 55
  69. #define R_LARCH_SUB64 56
  70. #define R_LARCH_GNU_VTINHERIT 57
  71. #define R_LARCH_GNU_VTENTRY 58
  72. #define R_LARCH_B16 64
  73. #define R_LARCH_B21 65
  74. #define R_LARCH_B26 66
  75. #define R_LARCH_ABS_HI20 67
  76. #define R_LARCH_ABS_LO12 68
  77. #define R_LARCH_ABS64_LO20 69
  78. #define R_LARCH_ABS64_HI12 70
  79. #define R_LARCH_PCALA_HI20 71
  80. #define R_LARCH_PCALA_LO12 72
  81. #define R_LARCH_PCALA64_LO20 73
  82. #define R_LARCH_PCALA64_HI12 74
  83. #define R_LARCH_GOT_PC_HI20 75
  84. #define R_LARCH_GOT_PC_LO12 76
  85. #define R_LARCH_GOT64_PC_LO20 77
  86. #define R_LARCH_GOT64_PC_HI12 78
  87. #define R_LARCH_GOT_HI20 79
  88. #define R_LARCH_GOT_LO12 80
  89. #define R_LARCH_GOT64_LO20 81
  90. #define R_LARCH_GOT64_HI12 82
  91. #define R_LARCH_TLS_LE_HI20 83
  92. #define R_LARCH_TLS_LE_LO12 84
  93. #define R_LARCH_TLS_LE64_LO20 85
  94. #define R_LARCH_TLS_LE64_HI12 86
  95. #define R_LARCH_TLS_IE_PC_HI20 87
  96. #define R_LARCH_TLS_IE_PC_LO12 88
  97. #define R_LARCH_TLS_IE64_PC_LO20 89
  98. #define R_LARCH_TLS_IE64_PC_HI12 90
  99. #define R_LARCH_TLS_IE_HI20 91
  100. #define R_LARCH_TLS_IE_LO12 92
  101. #define R_LARCH_TLS_IE64_LO20 93
  102. #define R_LARCH_TLS_IE64_HI12 94
  103. #define R_LARCH_TLS_LD_PC_HI20 95
  104. #define R_LARCH_TLS_LD_HI20 96
  105. #define R_LARCH_TLS_GD_PC_HI20 97
  106. #define R_LARCH_TLS_GD_HI20 98
  107. #define R_LARCH_32_PCREL 99
  108. #define R_LARCH_RELAX 100
  109. #define R_LARCH_DELETE 101
  110. #define R_LARCH_ALIGN 102
  111. #define R_LARCH_PCREL20_S2 103
  112. #define R_LARCH_CFA 104
  113. #define R_LARCH_ADD6 105
  114. #define R_LARCH_SUB6 106
  115. #define R_LARCH_ADD_ULEB128 107
  116. #define R_LARCH_SUB_ULEB128 108
  117. #define R_LARCH_64_PCREL 109
  118. #ifndef ELF_ARCH
  119. /* ELF register definitions */
  120. /*
  121. * General purpose have the following registers:
  122. * Register Number
  123. * GPRs 32
  124. * ORIG_A0 1
  125. * ERA 1
  126. * BADVADDR 1
  127. * CRMD 1
  128. * PRMD 1
  129. * EUEN 1
  130. * ECFG 1
  131. * ESTAT 1
  132. * Reserved 5
  133. */
  134. #define ELF_NGREG 45
  135. /*
  136. * Floating point have the following registers:
  137. * Register Number
  138. * FPR 32
  139. * FCC 1
  140. * FCSR 1
  141. */
  142. #define ELF_NFPREG 34
  143. typedef unsigned long elf_greg_t;
  144. typedef elf_greg_t elf_gregset_t[ELF_NGREG];
  145. typedef double elf_fpreg_t;
  146. typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
  147. void loongarch_dump_regs64(u64 *uregs, const struct pt_regs *regs);
  148. #ifdef CONFIG_32BIT
  149. /*
  150. * This is used to ensure we don't load something for the wrong architecture.
  151. */
  152. #define elf_check_arch elf32_check_arch
  153. /*
  154. * These are used to set parameters in the core dumps.
  155. */
  156. #define ELF_CLASS ELFCLASS32
  157. #define ELF_CORE_COPY_REGS(dest, regs) \
  158. loongarch_dump_regs32((u32 *)&(dest), (regs));
  159. #endif /* CONFIG_32BIT */
  160. #ifdef CONFIG_64BIT
  161. /*
  162. * This is used to ensure we don't load something for the wrong architecture.
  163. */
  164. #define elf_check_arch elf64_check_arch
  165. /*
  166. * These are used to set parameters in the core dumps.
  167. */
  168. #define ELF_CLASS ELFCLASS64
  169. #define ELF_CORE_COPY_REGS(dest, regs) \
  170. loongarch_dump_regs64((u64 *)&(dest), (regs));
  171. #endif /* CONFIG_64BIT */
  172. /*
  173. * These are used to set parameters in the core dumps.
  174. */
  175. #define ELF_DATA ELFDATA2LSB
  176. #define ELF_ARCH EM_LOONGARCH
  177. #endif /* !defined(ELF_ARCH) */
  178. #define loongarch_elf_check_machine(x) ((x)->e_machine == EM_LOONGARCH)
  179. #define vmcore_elf32_check_arch loongarch_elf_check_machine
  180. #define vmcore_elf64_check_arch loongarch_elf_check_machine
  181. /*
  182. * Return non-zero if HDR identifies an 32bit ELF binary.
  183. */
  184. #define elf32_check_arch(hdr) \
  185. ({ \
  186. int __res = 1; \
  187. struct elfhdr *__h = (hdr); \
  188. \
  189. if (!loongarch_elf_check_machine(__h)) \
  190. __res = 0; \
  191. if (__h->e_ident[EI_CLASS] != ELFCLASS32) \
  192. __res = 0; \
  193. \
  194. __res; \
  195. })
  196. /*
  197. * Return non-zero if HDR identifies an 64bit ELF binary.
  198. */
  199. #define elf64_check_arch(hdr) \
  200. ({ \
  201. int __res = 1; \
  202. struct elfhdr *__h = (hdr); \
  203. \
  204. if (!loongarch_elf_check_machine(__h)) \
  205. __res = 0; \
  206. if (__h->e_ident[EI_CLASS] != ELFCLASS64) \
  207. __res = 0; \
  208. \
  209. __res; \
  210. })
  211. #ifdef CONFIG_32BIT
  212. #define SET_PERSONALITY2(ex, state) \
  213. do { \
  214. current->thread.vdso = &vdso_info; \
  215. \
  216. loongarch_set_personality_fcsr(state); \
  217. \
  218. if (personality(current->personality) != PER_LINUX) \
  219. set_personality(PER_LINUX); \
  220. } while (0)
  221. #endif /* CONFIG_32BIT */
  222. #ifdef CONFIG_64BIT
  223. #define SET_PERSONALITY2(ex, state) \
  224. do { \
  225. unsigned int p; \
  226. \
  227. clear_thread_flag(TIF_32BIT_REGS); \
  228. clear_thread_flag(TIF_32BIT_ADDR); \
  229. \
  230. current->thread.vdso = &vdso_info; \
  231. loongarch_set_personality_fcsr(state); \
  232. \
  233. p = personality(current->personality); \
  234. if (p != PER_LINUX32 && p != PER_LINUX) \
  235. set_personality(PER_LINUX); \
  236. } while (0)
  237. #endif /* CONFIG_64BIT */
  238. #define CORE_DUMP_USE_REGSET
  239. #define ELF_EXEC_PAGESIZE PAGE_SIZE
  240. /*
  241. * This yields a mask that user programs can use to figure out what
  242. * instruction set this cpu supports. This could be done in userspace,
  243. * but it's not easy, and we've already done it here.
  244. */
  245. #define ELF_HWCAP (elf_hwcap)
  246. extern unsigned int elf_hwcap;
  247. #include <asm/hwcap.h>
  248. /*
  249. * This yields a string that ld.so will use to load implementation
  250. * specific libraries for optimization. This is more specific in
  251. * intent than poking at uname or /proc/cpuinfo.
  252. */
  253. #define ELF_PLATFORM __elf_platform
  254. extern const char *__elf_platform;
  255. #define ELF_PLAT_INIT(_r, load_addr) do { \
  256. _r->regs[1] = _r->regs[2] = _r->regs[3] = _r->regs[4] = 0; \
  257. _r->regs[5] = _r->regs[6] = _r->regs[7] = _r->regs[8] = 0; \
  258. _r->regs[9] = _r->regs[10] = _r->regs[11] = _r->regs[12] = 0; \
  259. _r->regs[13] = _r->regs[14] = _r->regs[15] = _r->regs[16] = 0; \
  260. _r->regs[17] = _r->regs[18] = _r->regs[19] = _r->regs[20] = 0; \
  261. _r->regs[21] = _r->regs[22] = _r->regs[23] = _r->regs[24] = 0; \
  262. _r->regs[25] = _r->regs[26] = _r->regs[27] = _r->regs[28] = 0; \
  263. _r->regs[29] = _r->regs[30] = _r->regs[31] = 0; \
  264. } while (0)
  265. /*
  266. * This is the location that an ET_DYN program is loaded if exec'ed. Typical
  267. * use of this is to invoke "./ld.so someprog" to test out a new version of
  268. * the loader. We need to make sure that it is out of the way of the program
  269. * that it will "exec", and that there is sufficient room for the brk.
  270. */
  271. #define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
  272. /* update AT_VECTOR_SIZE_ARCH if the number of NEW_AUX_ENT entries changes */
  273. #define ARCH_DLINFO \
  274. do { \
  275. NEW_AUX_ENT(AT_SYSINFO_EHDR, \
  276. (unsigned long)current->mm->context.vdso); \
  277. } while (0)
  278. #define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1
  279. struct linux_binprm;
  280. extern int arch_setup_additional_pages(struct linux_binprm *bprm,
  281. int uses_interp);
  282. struct arch_elf_state {
  283. int fp_abi;
  284. int interp_fp_abi;
  285. };
  286. #define LOONGARCH_ABI_FP_ANY (0)
  287. #define INIT_ARCH_ELF_STATE { \
  288. .fp_abi = LOONGARCH_ABI_FP_ANY, \
  289. .interp_fp_abi = LOONGARCH_ABI_FP_ANY, \
  290. }
  291. extern int arch_elf_pt_proc(void *ehdr, void *phdr, struct file *elf,
  292. bool is_interp, struct arch_elf_state *state);
  293. extern int arch_check_elf(void *ehdr, bool has_interpreter, void *interp_ehdr,
  294. struct arch_elf_state *state);
  295. extern void loongarch_set_personality_fcsr(struct arch_elf_state *state);
  296. #endif /* _ASM_ELF_H */