xref: /openbmc/linux/arch/powerpc/include/asm/elf.h (revision c900529f3d9161bfde5cca0754f83b4d3c3e0220)
12874c5fdSThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-or-later */
2b8b572e1SStephen Rothwell /*
3b8b572e1SStephen Rothwell  * ELF register definitions..
4b8b572e1SStephen Rothwell  */
5c3617f72SDavid Howells #ifndef _ASM_POWERPC_ELF_H
6c3617f72SDavid Howells #define _ASM_POWERPC_ELF_H
7b8b572e1SStephen Rothwell 
8c3617f72SDavid Howells #include <linux/sched.h>	/* for task_struct */
9c3617f72SDavid Howells #include <asm/page.h>
10c3617f72SDavid Howells #include <asm/string.h>
11c3617f72SDavid Howells #include <uapi/asm/elf.h>
12b8b572e1SStephen Rothwell 
13b8b572e1SStephen Rothwell /*
14b8b572e1SStephen Rothwell  * This is used to ensure we don't load something for the wrong architecture.
15b8b572e1SStephen Rothwell  */
16b8b572e1SStephen Rothwell #define elf_check_arch(x) ((x)->e_machine == ELF_ARCH)
17b8b572e1SStephen Rothwell #define compat_elf_check_arch(x)	((x)->e_machine == EM_PPC)
18b8b572e1SStephen Rothwell 
19b8b572e1SStephen Rothwell #define CORE_DUMP_USE_REGSET
20b8b572e1SStephen Rothwell #define ELF_EXEC_PAGESIZE	PAGE_SIZE
21b8b572e1SStephen Rothwell 
2247ebb09dSKees Cook /*
2347ebb09dSKees Cook  * This is the base location for PIE (ET_DYN with INTERP) loads. On
2447ebb09dSKees Cook  * 64-bit, this is raised to 4GB to leave the entire 32-bit address
2547ebb09dSKees Cook  * space open for things that want to use the area for 32-bit pointers.
2647ebb09dSKees Cook  */
2747ebb09dSKees Cook #define ELF_ET_DYN_BASE		(is_32bit_task() ? 0x000400000UL : \
2847ebb09dSKees Cook 						   0x100000000UL)
29b8b572e1SStephen Rothwell 
30918d0355SRusty Russell #define ELF_CORE_EFLAGS (is_elf2_task() ? 2 : 0)
31918d0355SRusty Russell 
32b8b572e1SStephen Rothwell /*
33b8b572e1SStephen Rothwell  * Our registers are always unsigned longs, whether we're a 32 bit
34b8b572e1SStephen Rothwell  * process or 64 bit, on either a 64 bit or 32 bit kernel.
35b8b572e1SStephen Rothwell  *
36b8b572e1SStephen Rothwell  * This macro relies on elf_regs[i] having the right type to truncate to,
37b8b572e1SStephen Rothwell  * either u32 or u64.  It defines the body of the elf_core_copy_regs
38b8b572e1SStephen Rothwell  * function, either the native one with elf_gregset_t elf_regs or
39b8b572e1SStephen Rothwell  * the 32-bit one with elf_gregset_t32 elf_regs.
40b8b572e1SStephen Rothwell  */
41b8b572e1SStephen Rothwell #define PPC_ELF_CORE_COPY_REGS(elf_regs, regs) \
42b8b572e1SStephen Rothwell 	int i, nregs = min(sizeof(*regs) / sizeof(unsigned long), \
43b8b572e1SStephen Rothwell 			   (size_t)ELF_NGREG);			  \
44b8b572e1SStephen Rothwell 	for (i = 0; i < nregs; i++) \
45b8b572e1SStephen Rothwell 		elf_regs[i] = ((unsigned long *) regs)[i]; \
46b8b572e1SStephen Rothwell 	memset(&elf_regs[i], 0, (ELF_NGREG - i) * sizeof(elf_regs[0]))
47b8b572e1SStephen Rothwell 
48b8b572e1SStephen Rothwell /* 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)49b8b572e1SStephen Rothwell static inline void ppc_elf_core_copy_regs(elf_gregset_t elf_regs,
50b8b572e1SStephen Rothwell 					  struct pt_regs *regs)
51b8b572e1SStephen Rothwell {
52b8b572e1SStephen Rothwell 	PPC_ELF_CORE_COPY_REGS(elf_regs, regs);
53b8b572e1SStephen Rothwell }
54b8b572e1SStephen Rothwell #define ELF_CORE_COPY_REGS(gregs, regs) ppc_elf_core_copy_regs(gregs, regs);
55b8b572e1SStephen Rothwell 
56b8b572e1SStephen Rothwell /* ELF_HWCAP yields a mask that user programs can use to figure out what
57b8b572e1SStephen Rothwell    instruction set this cpu supports.  This could be done in userspace,
58b8b572e1SStephen Rothwell    but it's not easy, and we've already done it here.  */
59b8b572e1SStephen Rothwell # define ELF_HWCAP	(cur_cpu_spec->cpu_user_features)
602171364dSMichael Neuling # define ELF_HWCAP2	(cur_cpu_spec->cpu_user_features2)
61b8b572e1SStephen Rothwell 
62b8b572e1SStephen Rothwell /* This yields a string that ld.so will use to load implementation
63b8b572e1SStephen Rothwell    specific libraries for optimization.  This is more specific in
64b8b572e1SStephen Rothwell    intent than poking at uname or /proc/cpuinfo.  */
65b8b572e1SStephen Rothwell 
66b8b572e1SStephen Rothwell #define ELF_PLATFORM	(cur_cpu_spec->platform)
67b8b572e1SStephen Rothwell 
68b8b572e1SStephen Rothwell /* While ELF_PLATFORM indicates the ISA supported by the platform, it
69b8b572e1SStephen Rothwell  * may not accurately reflect the underlying behavior of the hardware
70b8b572e1SStephen Rothwell  * (as in the case of running in Power5+ compatibility mode on a
71b8b572e1SStephen Rothwell  * Power6 machine).  ELF_BASE_PLATFORM allows ld.so to load libraries
72b8b572e1SStephen Rothwell  * that are tuned for the real hardware.
73b8b572e1SStephen Rothwell  */
74b8b572e1SStephen Rothwell #define ELF_BASE_PLATFORM (powerpc_base_platform)
75b8b572e1SStephen Rothwell 
76b8b572e1SStephen Rothwell #ifdef __powerpc64__
77b8b572e1SStephen Rothwell # define ELF_PLAT_INIT(_r, load_addr)	do {	\
78b8b572e1SStephen Rothwell 	_r->gpr[2] = load_addr; 		\
79b8b572e1SStephen Rothwell } while (0)
80b8b572e1SStephen Rothwell #endif /* __powerpc64__ */
81b8b572e1SStephen Rothwell 
82b8b572e1SStephen Rothwell #ifdef __powerpc64__
830b592682SMartin Schwidefsky # define SET_PERSONALITY(ex)					\
84b8b572e1SStephen Rothwell do {								\
85373c76d6SRusty Russell 	if (((ex).e_flags & 0x3) == 2)				\
86373c76d6SRusty Russell 		set_thread_flag(TIF_ELF2ABI);			\
871efc5638SJeff Bailey 	else							\
881efc5638SJeff Bailey 		clear_thread_flag(TIF_ELF2ABI);			\
89b8b572e1SStephen Rothwell 	if ((ex).e_ident[EI_CLASS] == ELFCLASS32)		\
9094f28da8SAndreas Schwab 		set_thread_flag(TIF_32BIT);			\
91b8b572e1SStephen Rothwell 	else							\
9294f28da8SAndreas Schwab 		clear_thread_flag(TIF_32BIT);			\
93b8b572e1SStephen Rothwell 	if (personality(current->personality) != PER_LINUX32)	\
94b8b572e1SStephen Rothwell 		set_personality(PER_LINUX |			\
95b8b572e1SStephen Rothwell 			(current->personality & (~PER_MASK)));	\
96b8b572e1SStephen Rothwell } while (0)
97b8b572e1SStephen Rothwell /*
98b8b572e1SStephen Rothwell  * An executable for which elf_read_implies_exec() returns TRUE will
99b8b572e1SStephen Rothwell  * have the READ_IMPLIES_EXEC personality flag set automatically. This
100b8b572e1SStephen Rothwell  * is only required to work around bugs in old 32bit toolchains. Since
101b8b572e1SStephen Rothwell  * the 64bit ABI has never had these issues dont enable the workaround
102b8b572e1SStephen Rothwell  * even if we have an executable stack.
103b8b572e1SStephen Rothwell  */
104cab175f9SDenis Kirjanov # define elf_read_implies_exec(ex, exec_stk) (is_32bit_task() ? \
105d89ebca2SKumar Gala 		(exec_stk == EXSTACK_DEFAULT) : 0)
106b8b572e1SStephen Rothwell #else
107d89ebca2SKumar Gala # define elf_read_implies_exec(ex, exec_stk) (exec_stk == EXSTACK_DEFAULT)
108b8b572e1SStephen Rothwell #endif /* __powerpc64__ */
109b8b572e1SStephen Rothwell 
110b8b572e1SStephen Rothwell extern int dcache_bsize;
111b8b572e1SStephen Rothwell extern int icache_bsize;
112b8b572e1SStephen Rothwell extern int ucache_bsize;
113b8b572e1SStephen Rothwell 
114b8b572e1SStephen Rothwell /* vDSO has arch_setup_additional_pages */
115b8b572e1SStephen Rothwell #define ARCH_HAS_SETUP_ADDITIONAL_PAGES
116b8b572e1SStephen Rothwell struct linux_binprm;
117b8b572e1SStephen Rothwell extern int arch_setup_additional_pages(struct linux_binprm *bprm,
118fc5243d9SMartin Schwidefsky 				       int uses_interp);
119497888cfSPhil Carmody #define VDSO_AUX_ENT(a,b) NEW_AUX_ENT(a,b)
120b8b572e1SStephen Rothwell 
1212dadb987SAnton Blanchard /* 1GB for 64bit, 8MB for 32bit */
1222dadb987SAnton Blanchard #define STACK_RND_MASK (is_32bit_task() ? \
1232dadb987SAnton Blanchard 	(0x7ff >> (PAGE_SHIFT - 12)) : \
1242dadb987SAnton Blanchard 	(0x3ffff >> (PAGE_SHIFT - 12)))
1252dadb987SAnton Blanchard 
126b8b572e1SStephen Rothwell #ifdef CONFIG_SPU_BASE
127b8b572e1SStephen Rothwell /* Notes used in ET_CORE. Note name is "SPU/<fd>/<filename>". */
128b8b572e1SStephen Rothwell #define NT_SPU		1
129b8b572e1SStephen Rothwell 
130b8b572e1SStephen Rothwell #define ARCH_HAVE_EXTRA_ELF_NOTES
131b8b572e1SStephen Rothwell 
132b8b572e1SStephen Rothwell #endif /* CONFIG_SPU_BASE */
133b8b572e1SStephen Rothwell 
13498a5f361SBenjamin Herrenschmidt #ifdef CONFIG_PPC64
13598a5f361SBenjamin Herrenschmidt 
13698a5f361SBenjamin Herrenschmidt #define get_cache_geometry(level) \
13798a5f361SBenjamin Herrenschmidt 	(ppc64_caches.level.assoc << 16 | ppc64_caches.level.line_size)
13898a5f361SBenjamin Herrenschmidt 
13998a5f361SBenjamin Herrenschmidt #define ARCH_DLINFO_CACHE_GEOMETRY					\
14098a5f361SBenjamin Herrenschmidt 	NEW_AUX_ENT(AT_L1I_CACHESIZE, ppc64_caches.l1i.size);		\
14198a5f361SBenjamin Herrenschmidt 	NEW_AUX_ENT(AT_L1I_CACHEGEOMETRY, get_cache_geometry(l1i));	\
1429c7a0086SMichael Ellerman 	NEW_AUX_ENT(AT_L1D_CACHESIZE, ppc64_caches.l1d.size);		\
1439c7a0086SMichael Ellerman 	NEW_AUX_ENT(AT_L1D_CACHEGEOMETRY, get_cache_geometry(l1d));	\
14498a5f361SBenjamin Herrenschmidt 	NEW_AUX_ENT(AT_L2_CACHESIZE, ppc64_caches.l2.size);		\
14598a5f361SBenjamin Herrenschmidt 	NEW_AUX_ENT(AT_L2_CACHEGEOMETRY, get_cache_geometry(l2));	\
14698a5f361SBenjamin Herrenschmidt 	NEW_AUX_ENT(AT_L3_CACHESIZE, ppc64_caches.l3.size);		\
14798a5f361SBenjamin Herrenschmidt 	NEW_AUX_ENT(AT_L3_CACHEGEOMETRY, get_cache_geometry(l3))
14898a5f361SBenjamin Herrenschmidt 
14998a5f361SBenjamin Herrenschmidt #else
15098a5f361SBenjamin Herrenschmidt #define ARCH_DLINFO_CACHE_GEOMETRY
15198a5f361SBenjamin Herrenschmidt #endif
15298a5f361SBenjamin Herrenschmidt 
1532a196e24SBenjamin Herrenschmidt /*
1542a196e24SBenjamin Herrenschmidt  * The requirements here are:
1552a196e24SBenjamin Herrenschmidt  * - keep the final alignment of sp (sp & 0xf)
1562a196e24SBenjamin Herrenschmidt  * - make sure the 32-bit value at the first 16 byte aligned position of
1572a196e24SBenjamin Herrenschmidt  *   AUXV is greater than 16 for glibc compatibility.
1582a196e24SBenjamin Herrenschmidt  *   AT_IGNOREPPC is used for that.
1592a196e24SBenjamin Herrenschmidt  * - for compatibility with glibc ARCH_DLINFO must always be defined on PPC,
1602a196e24SBenjamin Herrenschmidt  *   even if DLINFO_ARCH_ITEMS goes to zero or is undefined.
1612a196e24SBenjamin Herrenschmidt  * update AT_VECTOR_SIZE_ARCH if the number of NEW_AUX_ENT entries changes
1622a196e24SBenjamin Herrenschmidt  */
163*2896b2dfSNicholas Piggin #define COMMON_ARCH_DLINFO						\
1642a196e24SBenjamin Herrenschmidt do {									\
1652a196e24SBenjamin Herrenschmidt 	/* Handle glibc compatibility. */				\
1662a196e24SBenjamin Herrenschmidt 	NEW_AUX_ENT(AT_IGNOREPPC, AT_IGNOREPPC);			\
1672a196e24SBenjamin Herrenschmidt 	NEW_AUX_ENT(AT_IGNOREPPC, AT_IGNOREPPC);			\
1682a196e24SBenjamin Herrenschmidt 	/* Cache size items */						\
1692a196e24SBenjamin Herrenschmidt 	NEW_AUX_ENT(AT_DCACHEBSIZE, dcache_bsize);			\
1702a196e24SBenjamin Herrenschmidt 	NEW_AUX_ENT(AT_ICACHEBSIZE, icache_bsize);			\
1718817aabbSChristophe Leroy 	NEW_AUX_ENT(AT_UCACHEBSIZE, 0);					\
172c102f076SChristophe Leroy 	VDSO_AUX_ENT(AT_SYSINFO_EHDR, (unsigned long)current->mm->context.vdso);\
17398a5f361SBenjamin Herrenschmidt 	ARCH_DLINFO_CACHE_GEOMETRY;					\
1742a196e24SBenjamin Herrenschmidt } while (0)
1752a196e24SBenjamin Herrenschmidt 
176*2896b2dfSNicholas Piggin #define ARCH_DLINFO							\
177*2896b2dfSNicholas Piggin do {									\
178*2896b2dfSNicholas Piggin 	COMMON_ARCH_DLINFO;						\
179*2896b2dfSNicholas Piggin 	NEW_AUX_ENT(AT_MINSIGSTKSZ, get_min_sigframe_size());		\
180*2896b2dfSNicholas Piggin } while (0)
181*2896b2dfSNicholas Piggin 
182*2896b2dfSNicholas Piggin #define COMPAT_ARCH_DLINFO						\
183*2896b2dfSNicholas Piggin do {									\
184*2896b2dfSNicholas Piggin 	COMMON_ARCH_DLINFO;						\
185*2896b2dfSNicholas Piggin 	NEW_AUX_ENT(AT_MINSIGSTKSZ, get_min_sigframe_size_compat());	\
186*2896b2dfSNicholas Piggin } while (0)
187*2896b2dfSNicholas Piggin 
18805d9a952SThiago Jung Bauermann /* Relocate the kernel image to @final_address */
18905d9a952SThiago Jung Bauermann void relocate(unsigned long final_address);
19005d9a952SThiago Jung Bauermann 
1915b23cb8cSChristophe Leroy struct func_desc {
1925b23cb8cSChristophe Leroy 	unsigned long addr;
1935b23cb8cSChristophe Leroy 	unsigned long toc;
1945b23cb8cSChristophe Leroy 	unsigned long env;
1955b23cb8cSChristophe Leroy };
1965b23cb8cSChristophe Leroy 
197b8b572e1SStephen Rothwell #endif /* _ASM_POWERPC_ELF_H */
198