Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.5.6.
  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
115#ifndef ELF_ARCH
116
117/* ELF register definitions */
118
119/*
120 * General purpose have the following registers:
121 *	Register	Number
122 *	GPRs		32
123 *	ORIG_A0		1
124 *	ERA		1
125 *	BADVADDR	1
126 *	CRMD		1
127 *	PRMD		1
128 *	EUEN		1
129 *	ECFG		1
130 *	ESTAT		1
131 *	Reserved	5
132 */
133#define ELF_NGREG	45
134
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
144typedef unsigned long elf_greg_t;
145typedef elf_greg_t elf_gregset_t[ELF_NGREG];
146
147typedef double elf_fpreg_t;
148typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
149
150void loongarch_dump_regs64(u64 *uregs, const struct pt_regs *regs);
151
152#ifdef CONFIG_32BIT
153/*
154 * This is used to ensure we don't load something for the wrong architecture.
155 */
156#define elf_check_arch elf32_check_arch
157
158/*
159 * These are used to set parameters in the core dumps.
160 */
161#define ELF_CLASS	ELFCLASS32
162
163#define ELF_CORE_COPY_REGS(dest, regs) \
164	loongarch_dump_regs32((u32 *)&(dest), (regs));
165
166#endif /* CONFIG_32BIT */
167
168#ifdef CONFIG_64BIT
169/*
170 * This is used to ensure we don't load something for the wrong architecture.
171 */
172#define elf_check_arch elf64_check_arch
173
174/*
175 * These are used to set parameters in the core dumps.
176 */
177#define ELF_CLASS	ELFCLASS64
178
179#define ELF_CORE_COPY_REGS(dest, regs) \
180	loongarch_dump_regs64((u64 *)&(dest), (regs));
181
182#endif /* CONFIG_64BIT */
183
184/*
185 * These are used to set parameters in the core dumps.
186 */
187#define ELF_DATA	ELFDATA2LSB
188#define ELF_ARCH	EM_LOONGARCH
189
190#endif /* !defined(ELF_ARCH) */
191
192#define loongarch_elf_check_machine(x) ((x)->e_machine == EM_LOONGARCH)
193
194#define vmcore_elf32_check_arch loongarch_elf_check_machine
195#define vmcore_elf64_check_arch loongarch_elf_check_machine
196
197/*
198 * Return non-zero if HDR identifies an 32bit ELF binary.
199 */
200#define elf32_check_arch(hdr)						\
201({									\
202	int __res = 1;							\
203	struct elfhdr *__h = (hdr);					\
204									\
205	if (!loongarch_elf_check_machine(__h))				\
206		__res = 0;						\
207	if (__h->e_ident[EI_CLASS] != ELFCLASS32)			\
208		__res = 0;						\
209									\
210	__res;								\
211})
212
213/*
214 * Return non-zero if HDR identifies an 64bit ELF binary.
215 */
216#define elf64_check_arch(hdr)						\
217({									\
218	int __res = 1;							\
219	struct elfhdr *__h = (hdr);					\
220									\
221	if (!loongarch_elf_check_machine(__h))				\
222		__res = 0;						\
223	if (__h->e_ident[EI_CLASS] != ELFCLASS64)			\
224		__res = 0;						\
225									\
226	__res;								\
227})
228
229#ifdef CONFIG_32BIT
230
231#define SET_PERSONALITY2(ex, state)					\
232do {									\
233	current->thread.vdso = &vdso_info;				\
234									\
235	loongarch_set_personality_fcsr(state);				\
236									\
237	if (personality(current->personality) != PER_LINUX)		\
238		set_personality(PER_LINUX);				\
239} while (0)
240
241#endif /* CONFIG_32BIT */
242
243#ifdef CONFIG_64BIT
244
245#define SET_PERSONALITY2(ex, state)					\
246do {									\
247	unsigned int p;							\
248									\
249	clear_thread_flag(TIF_32BIT_REGS);				\
250	clear_thread_flag(TIF_32BIT_ADDR);				\
251									\
252	current->thread.vdso = &vdso_info;				\
253	loongarch_set_personality_fcsr(state);				\
254									\
255	p = personality(current->personality);				\
256	if (p != PER_LINUX32 && p != PER_LINUX)				\
257		set_personality(PER_LINUX);				\
258} while (0)
259
260#endif /* CONFIG_64BIT */
261
262#define CORE_DUMP_USE_REGSET
263#define ELF_EXEC_PAGESIZE	PAGE_SIZE
264
265/*
266 * This yields a mask that user programs can use to figure out what
267 * instruction set this cpu supports. This could be done in userspace,
268 * but it's not easy, and we've already done it here.
269 */
270
271#define ELF_HWCAP	(elf_hwcap)
272extern unsigned int elf_hwcap;
273#include <asm/hwcap.h>
274
275/*
276 * This yields a string that ld.so will use to load implementation
277 * specific libraries for optimization.	 This is more specific in
278 * intent than poking at uname or /proc/cpuinfo.
279 */
280
281#define ELF_PLATFORM  __elf_platform
282extern const char *__elf_platform;
283
284#define ELF_PLAT_INIT(_r, load_addr)	do { \
285	_r->regs[1] = _r->regs[2] = _r->regs[3] = _r->regs[4] = 0;	\
286	_r->regs[5] = _r->regs[6] = _r->regs[7] = _r->regs[8] = 0;	\
287	_r->regs[9] = _r->regs[10] = _r->regs[11] = _r->regs[12] = 0;	\
288	_r->regs[13] = _r->regs[14] = _r->regs[15] = _r->regs[16] = 0;	\
289	_r->regs[17] = _r->regs[18] = _r->regs[19] = _r->regs[20] = 0;	\
290	_r->regs[21] = _r->regs[22] = _r->regs[23] = _r->regs[24] = 0;	\
291	_r->regs[25] = _r->regs[26] = _r->regs[27] = _r->regs[28] = 0;	\
292	_r->regs[29] = _r->regs[30] = _r->regs[31] = 0;			\
293} while (0)
294
295/*
296 * This is the location that an ET_DYN program is loaded if exec'ed. Typical
297 * use of this is to invoke "./ld.so someprog" to test out a new version of
298 * the loader. We need to make sure that it is out of the way of the program
299 * that it will "exec", and that there is sufficient room for the brk.
300 */
301
302#define ELF_ET_DYN_BASE		(TASK_SIZE / 3 * 2)
303
304/* update AT_VECTOR_SIZE_ARCH if the number of NEW_AUX_ENT entries changes */
305#define ARCH_DLINFO							\
306do {									\
307	NEW_AUX_ENT(AT_SYSINFO_EHDR,					\
308		    (unsigned long)current->mm->context.vdso);		\
309} while (0)
310
311#define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1
312struct linux_binprm;
313extern int arch_setup_additional_pages(struct linux_binprm *bprm,
314				       int uses_interp);
315
316struct arch_elf_state {
317	int fp_abi;
318	int interp_fp_abi;
319};
320
321#define LOONGARCH_ABI_FP_ANY	(0)
322
323#define INIT_ARCH_ELF_STATE {			\
324	.fp_abi = LOONGARCH_ABI_FP_ANY,		\
325	.interp_fp_abi = LOONGARCH_ABI_FP_ANY,	\
326}
327
328extern int arch_elf_pt_proc(void *ehdr, void *phdr, struct file *elf,
329			    bool is_interp, struct arch_elf_state *state);
330
331extern int arch_check_elf(void *ehdr, bool has_interpreter, void *interp_ehdr,
332			  struct arch_elf_state *state);
333
334extern void loongarch_set_personality_fcsr(struct arch_elf_state *state);
335
336#endif /* _ASM_ELF_H */