xref: /linux/arch/riscv/include/asm/elf.h (revision 31354121bf03dac6498a4236928a38490745d601)
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 /*
3  * Copyright (C) 2003 Matjaz Breskvar <phoenix@bsemi.com>
4  * Copyright (C) 2010-2011 Jonas Bonn <jonas@southpole.se>
5  * Copyright (C) 2012 Regents of the University of California
6  */
7 
8 #ifndef _ASM_RISCV_ELF_H
9 #define _ASM_RISCV_ELF_H
10 
11 #include <uapi/linux/elf.h>
12 #include <linux/compat.h>
13 #include <uapi/asm/elf.h>
14 #include <asm/auxvec.h>
15 #include <asm/byteorder.h>
16 #include <asm/cacheinfo.h>
17 
18 /*
19  * These are used to set parameters in the core dumps.
20  */
21 #define ELF_ARCH	EM_RISCV
22 
23 #ifndef ELF_CLASS
24 #ifdef CONFIG_64BIT
25 #define ELF_CLASS	ELFCLASS64
26 #else
27 #define ELF_CLASS	ELFCLASS32
28 #endif
29 #endif
30 
31 #define ELF_DATA	ELFDATA2LSB
32 
33 /*
34  * This is used to ensure we don't load something for the wrong architecture.
35  */
36 #define elf_check_arch(x) (((x)->e_machine == EM_RISCV) && \
37 			   ((x)->e_ident[EI_CLASS] == ELF_CLASS))
38 
39 extern bool compat_elf_check_arch(Elf32_Ehdr *hdr);
40 #define compat_elf_check_arch	compat_elf_check_arch
41 
42 #define CORE_DUMP_USE_REGSET
43 #define ELF_EXEC_PAGESIZE	(PAGE_SIZE)
44 
45 /*
46  * This is the location that an ET_DYN program is loaded if exec'ed.  Typical
47  * use of this is to invoke "./ld.so someprog" to test out a new version of
48  * the loader.  We need to make sure that it is out of the way of the program
49  * that it will "exec", and that there is sufficient room for the brk.
50  */
51 #define ELF_ET_DYN_BASE		((TASK_SIZE / 3) * 2)
52 
53 #ifdef CONFIG_64BIT
54 #ifdef CONFIG_COMPAT
55 #define STACK_RND_MASK		(test_thread_flag(TIF_32BIT) ? \
56 				 0x7ff >> (PAGE_SHIFT - 12) : \
57 				 0x3ffff >> (PAGE_SHIFT - 12))
58 #else
59 #define STACK_RND_MASK		(0x3ffff >> (PAGE_SHIFT - 12))
60 #endif
61 #endif
62 /*
63  * This yields a mask that user programs can use to figure out what
64  * instruction set this CPU supports.  This could be done in user space,
65  * but it's not easy, and we've already done it here.
66  */
67 #define ELF_HWCAP	(elf_hwcap)
68 extern unsigned long elf_hwcap;
69 
70 /*
71  * This yields a string that ld.so will use to load implementation
72  * specific libraries for optimization.  This is more specific in
73  * intent than poking at uname or /proc/cpuinfo.
74  */
75 #define ELF_PLATFORM	(NULL)
76 
77 #define COMPAT_ELF_PLATFORM	(NULL)
78 
79 #ifdef CONFIG_MMU
80 #define ARCH_DLINFO						\
81 do {								\
82 	/*							\
83 	 * Note that we add ulong after elf_addr_t because	\
84 	 * casting current->mm->context.vdso triggers a cast	\
85 	 * warning of cast from pointer to integer for		\
86 	 * COMPAT ELFCLASS32.					\
87 	 */							\
88 	NEW_AUX_ENT(AT_SYSINFO_EHDR,				\
89 		(elf_addr_t)(ulong)current->mm->context.vdso);	\
90 	NEW_AUX_ENT(AT_L1I_CACHESIZE,				\
91 		get_cache_size(1, CACHE_TYPE_INST));		\
92 	NEW_AUX_ENT(AT_L1I_CACHEGEOMETRY,			\
93 		get_cache_geometry(1, CACHE_TYPE_INST));	\
94 	NEW_AUX_ENT(AT_L1D_CACHESIZE,				\
95 		get_cache_size(1, CACHE_TYPE_DATA));		\
96 	NEW_AUX_ENT(AT_L1D_CACHEGEOMETRY,			\
97 		get_cache_geometry(1, CACHE_TYPE_DATA));	\
98 	NEW_AUX_ENT(AT_L2_CACHESIZE,				\
99 		get_cache_size(2, CACHE_TYPE_UNIFIED));		\
100 	NEW_AUX_ENT(AT_L2_CACHEGEOMETRY,			\
101 		get_cache_geometry(2, CACHE_TYPE_UNIFIED));	\
102 	NEW_AUX_ENT(AT_L3_CACHESIZE,				\
103 		get_cache_size(3, CACHE_TYPE_UNIFIED));		\
104 	NEW_AUX_ENT(AT_L3_CACHEGEOMETRY,			\
105 		get_cache_geometry(3, CACHE_TYPE_UNIFIED));	\
106 } while (0)
107 #define ARCH_HAS_SETUP_ADDITIONAL_PAGES
108 struct linux_binprm;
109 extern int arch_setup_additional_pages(struct linux_binprm *bprm,
110 	int uses_interp);
111 #endif /* CONFIG_MMU */
112 
113 #define ELF_CORE_COPY_REGS(dest, regs)			\
114 do {							\
115 	*(struct user_regs_struct *)&(dest) =		\
116 		*(struct user_regs_struct *)regs;	\
117 } while (0);
118 
119 #ifdef CONFIG_COMPAT
120 
121 #define SET_PERSONALITY(ex)					\
122 do {    if ((ex).e_ident[EI_CLASS] == ELFCLASS32)		\
123 		set_thread_flag(TIF_32BIT);			\
124 	else							\
125 		clear_thread_flag(TIF_32BIT);			\
126 	if (personality(current->personality) != PER_LINUX32)	\
127 		set_personality(PER_LINUX |			\
128 			(current->personality & (~PER_MASK)));	\
129 } while (0)
130 
131 #define COMPAT_ELF_ET_DYN_BASE		((TASK_SIZE_32 / 3) * 2)
132 
133 /* rv32 registers */
134 typedef compat_ulong_t			compat_elf_greg_t;
135 typedef compat_elf_greg_t		compat_elf_gregset_t[ELF_NGREG];
136 
137 extern int compat_arch_setup_additional_pages(struct linux_binprm *bprm,
138 					      int uses_interp);
139 #define compat_arch_setup_additional_pages \
140 				compat_arch_setup_additional_pages
141 
142 #endif /* CONFIG_COMPAT */
143 #endif /* _ASM_RISCV_ELF_H */
144