xref: /openbmc/linux/arch/riscv/include/asm/elf.h (revision d57cc3b9)
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 } while (0)
103 #define ARCH_HAS_SETUP_ADDITIONAL_PAGES
104 struct linux_binprm;
105 extern int arch_setup_additional_pages(struct linux_binprm *bprm,
106 	int uses_interp);
107 #endif /* CONFIG_MMU */
108 
109 #define ELF_CORE_COPY_REGS(dest, regs)			\
110 do {							\
111 	*(struct user_regs_struct *)&(dest) =		\
112 		*(struct user_regs_struct *)regs;	\
113 } while (0);
114 
115 #ifdef CONFIG_COMPAT
116 
117 #define SET_PERSONALITY(ex)					\
118 do {    if ((ex).e_ident[EI_CLASS] == ELFCLASS32)		\
119 		set_thread_flag(TIF_32BIT);			\
120 	else							\
121 		clear_thread_flag(TIF_32BIT);			\
122 	if (personality(current->personality) != PER_LINUX32)	\
123 		set_personality(PER_LINUX |			\
124 			(current->personality & (~PER_MASK)));	\
125 } while (0)
126 
127 #define COMPAT_ELF_ET_DYN_BASE		((TASK_SIZE_32 / 3) * 2)
128 
129 /* rv32 registers */
130 typedef compat_ulong_t			compat_elf_greg_t;
131 typedef compat_elf_greg_t		compat_elf_gregset_t[ELF_NGREG];
132 
133 extern int compat_arch_setup_additional_pages(struct linux_binprm *bprm,
134 					      int uses_interp);
135 #define compat_arch_setup_additional_pages \
136 				compat_arch_setup_additional_pages
137 
138 #endif /* CONFIG_COMPAT */
139 #endif /* _ASM_RISCV_ELF_H */
140