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