xref: /OK3568_Linux_fs/kernel/arch/powerpc/include/asm/elf.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0-or-later */
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * ELF register definitions..
4*4882a593Smuzhiyun  */
5*4882a593Smuzhiyun #ifndef _ASM_POWERPC_ELF_H
6*4882a593Smuzhiyun #define _ASM_POWERPC_ELF_H
7*4882a593Smuzhiyun 
8*4882a593Smuzhiyun #include <linux/sched.h>	/* for task_struct */
9*4882a593Smuzhiyun #include <asm/page.h>
10*4882a593Smuzhiyun #include <asm/string.h>
11*4882a593Smuzhiyun #include <uapi/asm/elf.h>
12*4882a593Smuzhiyun 
13*4882a593Smuzhiyun /*
14*4882a593Smuzhiyun  * This is used to ensure we don't load something for the wrong architecture.
15*4882a593Smuzhiyun  */
16*4882a593Smuzhiyun #define elf_check_arch(x) ((x)->e_machine == ELF_ARCH)
17*4882a593Smuzhiyun #define compat_elf_check_arch(x)	((x)->e_machine == EM_PPC)
18*4882a593Smuzhiyun 
19*4882a593Smuzhiyun #define CORE_DUMP_USE_REGSET
20*4882a593Smuzhiyun #define ELF_EXEC_PAGESIZE	PAGE_SIZE
21*4882a593Smuzhiyun 
22*4882a593Smuzhiyun /*
23*4882a593Smuzhiyun  * This is the base location for PIE (ET_DYN with INTERP) loads. On
24*4882a593Smuzhiyun  * 64-bit, this is raised to 4GB to leave the entire 32-bit address
25*4882a593Smuzhiyun  * space open for things that want to use the area for 32-bit pointers.
26*4882a593Smuzhiyun  */
27*4882a593Smuzhiyun #define ELF_ET_DYN_BASE		(is_32bit_task() ? 0x000400000UL : \
28*4882a593Smuzhiyun 						   0x100000000UL)
29*4882a593Smuzhiyun 
30*4882a593Smuzhiyun #define ELF_CORE_EFLAGS (is_elf2_task() ? 2 : 0)
31*4882a593Smuzhiyun 
32*4882a593Smuzhiyun /*
33*4882a593Smuzhiyun  * Our registers are always unsigned longs, whether we're a 32 bit
34*4882a593Smuzhiyun  * process or 64 bit, on either a 64 bit or 32 bit kernel.
35*4882a593Smuzhiyun  *
36*4882a593Smuzhiyun  * This macro relies on elf_regs[i] having the right type to truncate to,
37*4882a593Smuzhiyun  * either u32 or u64.  It defines the body of the elf_core_copy_regs
38*4882a593Smuzhiyun  * function, either the native one with elf_gregset_t elf_regs or
39*4882a593Smuzhiyun  * the 32-bit one with elf_gregset_t32 elf_regs.
40*4882a593Smuzhiyun  */
41*4882a593Smuzhiyun #define PPC_ELF_CORE_COPY_REGS(elf_regs, regs) \
42*4882a593Smuzhiyun 	int i, nregs = min(sizeof(*regs) / sizeof(unsigned long), \
43*4882a593Smuzhiyun 			   (size_t)ELF_NGREG);			  \
44*4882a593Smuzhiyun 	for (i = 0; i < nregs; i++) \
45*4882a593Smuzhiyun 		elf_regs[i] = ((unsigned long *) regs)[i]; \
46*4882a593Smuzhiyun 	memset(&elf_regs[i], 0, (ELF_NGREG - i) * sizeof(elf_regs[0]))
47*4882a593Smuzhiyun 
48*4882a593Smuzhiyun /* Common routine for both 32-bit and 64-bit native processes */
ppc_elf_core_copy_regs(elf_gregset_t elf_regs,struct pt_regs * regs)49*4882a593Smuzhiyun static inline void ppc_elf_core_copy_regs(elf_gregset_t elf_regs,
50*4882a593Smuzhiyun 					  struct pt_regs *regs)
51*4882a593Smuzhiyun {
52*4882a593Smuzhiyun 	PPC_ELF_CORE_COPY_REGS(elf_regs, regs);
53*4882a593Smuzhiyun }
54*4882a593Smuzhiyun #define ELF_CORE_COPY_REGS(gregs, regs) ppc_elf_core_copy_regs(gregs, regs);
55*4882a593Smuzhiyun 
56*4882a593Smuzhiyun /* ELF_HWCAP yields a mask that user programs can use to figure out what
57*4882a593Smuzhiyun    instruction set this cpu supports.  This could be done in userspace,
58*4882a593Smuzhiyun    but it's not easy, and we've already done it here.  */
59*4882a593Smuzhiyun # define ELF_HWCAP	(cur_cpu_spec->cpu_user_features)
60*4882a593Smuzhiyun # define ELF_HWCAP2	(cur_cpu_spec->cpu_user_features2)
61*4882a593Smuzhiyun 
62*4882a593Smuzhiyun /* This yields a string that ld.so will use to load implementation
63*4882a593Smuzhiyun    specific libraries for optimization.  This is more specific in
64*4882a593Smuzhiyun    intent than poking at uname or /proc/cpuinfo.  */
65*4882a593Smuzhiyun 
66*4882a593Smuzhiyun #define ELF_PLATFORM	(cur_cpu_spec->platform)
67*4882a593Smuzhiyun 
68*4882a593Smuzhiyun /* While ELF_PLATFORM indicates the ISA supported by the platform, it
69*4882a593Smuzhiyun  * may not accurately reflect the underlying behavior of the hardware
70*4882a593Smuzhiyun  * (as in the case of running in Power5+ compatibility mode on a
71*4882a593Smuzhiyun  * Power6 machine).  ELF_BASE_PLATFORM allows ld.so to load libraries
72*4882a593Smuzhiyun  * that are tuned for the real hardware.
73*4882a593Smuzhiyun  */
74*4882a593Smuzhiyun #define ELF_BASE_PLATFORM (powerpc_base_platform)
75*4882a593Smuzhiyun 
76*4882a593Smuzhiyun #ifdef __powerpc64__
77*4882a593Smuzhiyun # define ELF_PLAT_INIT(_r, load_addr)	do {	\
78*4882a593Smuzhiyun 	_r->gpr[2] = load_addr; 		\
79*4882a593Smuzhiyun } while (0)
80*4882a593Smuzhiyun #endif /* __powerpc64__ */
81*4882a593Smuzhiyun 
82*4882a593Smuzhiyun #ifdef __powerpc64__
83*4882a593Smuzhiyun # define SET_PERSONALITY(ex)					\
84*4882a593Smuzhiyun do {								\
85*4882a593Smuzhiyun 	if (((ex).e_flags & 0x3) == 2)				\
86*4882a593Smuzhiyun 		set_thread_flag(TIF_ELF2ABI);			\
87*4882a593Smuzhiyun 	else							\
88*4882a593Smuzhiyun 		clear_thread_flag(TIF_ELF2ABI);			\
89*4882a593Smuzhiyun 	if ((ex).e_ident[EI_CLASS] == ELFCLASS32)		\
90*4882a593Smuzhiyun 		set_thread_flag(TIF_32BIT);			\
91*4882a593Smuzhiyun 	else							\
92*4882a593Smuzhiyun 		clear_thread_flag(TIF_32BIT);			\
93*4882a593Smuzhiyun 	if (personality(current->personality) != PER_LINUX32)	\
94*4882a593Smuzhiyun 		set_personality(PER_LINUX |			\
95*4882a593Smuzhiyun 			(current->personality & (~PER_MASK)));	\
96*4882a593Smuzhiyun } while (0)
97*4882a593Smuzhiyun /*
98*4882a593Smuzhiyun  * An executable for which elf_read_implies_exec() returns TRUE will
99*4882a593Smuzhiyun  * have the READ_IMPLIES_EXEC personality flag set automatically. This
100*4882a593Smuzhiyun  * is only required to work around bugs in old 32bit toolchains. Since
101*4882a593Smuzhiyun  * the 64bit ABI has never had these issues dont enable the workaround
102*4882a593Smuzhiyun  * even if we have an executable stack.
103*4882a593Smuzhiyun  */
104*4882a593Smuzhiyun # define elf_read_implies_exec(ex, exec_stk) (is_32bit_task() ? \
105*4882a593Smuzhiyun 		(exec_stk == EXSTACK_DEFAULT) : 0)
106*4882a593Smuzhiyun #else
107*4882a593Smuzhiyun # define elf_read_implies_exec(ex, exec_stk) (exec_stk == EXSTACK_DEFAULT)
108*4882a593Smuzhiyun #endif /* __powerpc64__ */
109*4882a593Smuzhiyun 
110*4882a593Smuzhiyun extern int dcache_bsize;
111*4882a593Smuzhiyun extern int icache_bsize;
112*4882a593Smuzhiyun extern int ucache_bsize;
113*4882a593Smuzhiyun 
114*4882a593Smuzhiyun /* vDSO has arch_setup_additional_pages */
115*4882a593Smuzhiyun #define ARCH_HAS_SETUP_ADDITIONAL_PAGES
116*4882a593Smuzhiyun struct linux_binprm;
117*4882a593Smuzhiyun extern int arch_setup_additional_pages(struct linux_binprm *bprm,
118*4882a593Smuzhiyun 				       int uses_interp);
119*4882a593Smuzhiyun #define VDSO_AUX_ENT(a,b) NEW_AUX_ENT(a,b)
120*4882a593Smuzhiyun 
121*4882a593Smuzhiyun /* 1GB for 64bit, 8MB for 32bit */
122*4882a593Smuzhiyun #define STACK_RND_MASK (is_32bit_task() ? \
123*4882a593Smuzhiyun 	(0x7ff >> (PAGE_SHIFT - 12)) : \
124*4882a593Smuzhiyun 	(0x3ffff >> (PAGE_SHIFT - 12)))
125*4882a593Smuzhiyun 
126*4882a593Smuzhiyun #ifdef CONFIG_SPU_BASE
127*4882a593Smuzhiyun /* Notes used in ET_CORE. Note name is "SPU/<fd>/<filename>". */
128*4882a593Smuzhiyun #define NT_SPU		1
129*4882a593Smuzhiyun 
130*4882a593Smuzhiyun #define ARCH_HAVE_EXTRA_ELF_NOTES
131*4882a593Smuzhiyun 
132*4882a593Smuzhiyun #endif /* CONFIG_SPU_BASE */
133*4882a593Smuzhiyun 
134*4882a593Smuzhiyun #ifdef CONFIG_PPC64
135*4882a593Smuzhiyun 
136*4882a593Smuzhiyun #define get_cache_geometry(level) \
137*4882a593Smuzhiyun 	(ppc64_caches.level.assoc << 16 | ppc64_caches.level.line_size)
138*4882a593Smuzhiyun 
139*4882a593Smuzhiyun #define ARCH_DLINFO_CACHE_GEOMETRY					\
140*4882a593Smuzhiyun 	NEW_AUX_ENT(AT_L1I_CACHESIZE, ppc64_caches.l1i.size);		\
141*4882a593Smuzhiyun 	NEW_AUX_ENT(AT_L1I_CACHEGEOMETRY, get_cache_geometry(l1i));	\
142*4882a593Smuzhiyun 	NEW_AUX_ENT(AT_L1D_CACHESIZE, ppc64_caches.l1d.size);		\
143*4882a593Smuzhiyun 	NEW_AUX_ENT(AT_L1D_CACHEGEOMETRY, get_cache_geometry(l1d));	\
144*4882a593Smuzhiyun 	NEW_AUX_ENT(AT_L2_CACHESIZE, ppc64_caches.l2.size);		\
145*4882a593Smuzhiyun 	NEW_AUX_ENT(AT_L2_CACHEGEOMETRY, get_cache_geometry(l2));	\
146*4882a593Smuzhiyun 	NEW_AUX_ENT(AT_L3_CACHESIZE, ppc64_caches.l3.size);		\
147*4882a593Smuzhiyun 	NEW_AUX_ENT(AT_L3_CACHEGEOMETRY, get_cache_geometry(l3))
148*4882a593Smuzhiyun 
149*4882a593Smuzhiyun #else
150*4882a593Smuzhiyun #define ARCH_DLINFO_CACHE_GEOMETRY
151*4882a593Smuzhiyun #endif
152*4882a593Smuzhiyun 
153*4882a593Smuzhiyun /*
154*4882a593Smuzhiyun  * The requirements here are:
155*4882a593Smuzhiyun  * - keep the final alignment of sp (sp & 0xf)
156*4882a593Smuzhiyun  * - make sure the 32-bit value at the first 16 byte aligned position of
157*4882a593Smuzhiyun  *   AUXV is greater than 16 for glibc compatibility.
158*4882a593Smuzhiyun  *   AT_IGNOREPPC is used for that.
159*4882a593Smuzhiyun  * - for compatibility with glibc ARCH_DLINFO must always be defined on PPC,
160*4882a593Smuzhiyun  *   even if DLINFO_ARCH_ITEMS goes to zero or is undefined.
161*4882a593Smuzhiyun  * update AT_VECTOR_SIZE_ARCH if the number of NEW_AUX_ENT entries changes
162*4882a593Smuzhiyun  */
163*4882a593Smuzhiyun #define ARCH_DLINFO							\
164*4882a593Smuzhiyun do {									\
165*4882a593Smuzhiyun 	/* Handle glibc compatibility. */				\
166*4882a593Smuzhiyun 	NEW_AUX_ENT(AT_IGNOREPPC, AT_IGNOREPPC);			\
167*4882a593Smuzhiyun 	NEW_AUX_ENT(AT_IGNOREPPC, AT_IGNOREPPC);			\
168*4882a593Smuzhiyun 	/* Cache size items */						\
169*4882a593Smuzhiyun 	NEW_AUX_ENT(AT_DCACHEBSIZE, dcache_bsize);			\
170*4882a593Smuzhiyun 	NEW_AUX_ENT(AT_ICACHEBSIZE, icache_bsize);			\
171*4882a593Smuzhiyun 	NEW_AUX_ENT(AT_UCACHEBSIZE, ucache_bsize);			\
172*4882a593Smuzhiyun 	VDSO_AUX_ENT(AT_SYSINFO_EHDR, current->mm->context.vdso_base);	\
173*4882a593Smuzhiyun 	ARCH_DLINFO_CACHE_GEOMETRY;					\
174*4882a593Smuzhiyun } while (0)
175*4882a593Smuzhiyun 
176*4882a593Smuzhiyun /* Relocate the kernel image to @final_address */
177*4882a593Smuzhiyun void relocate(unsigned long final_address);
178*4882a593Smuzhiyun 
179*4882a593Smuzhiyun #endif /* _ASM_POWERPC_ELF_H */
180