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