elf.h 6.2 KB
Newer Older
1
/* SPDX-License-Identifier: GPL-2.0-or-later */
L
Linus Torvalds 已提交
2 3 4
/*
 * ELF register definitions..
 */
5 6
#ifndef _ASM_POWERPC_ELF_H
#define _ASM_POWERPC_ELF_H
L
Linus Torvalds 已提交
7

8 9 10 11
#include <linux/sched.h>	/* for task_struct */
#include <asm/page.h>
#include <asm/string.h>
#include <uapi/asm/elf.h>
L
Linus Torvalds 已提交
12 13 14 15 16

/*
 * This is used to ensure we don't load something for the wrong architecture.
 */
#define elf_check_arch(x) ((x)->e_machine == ELF_ARCH)
17
#define compat_elf_check_arch(x)	((x)->e_machine == EM_PPC)
L
Linus Torvalds 已提交
18

19
#define CORE_DUMP_USE_REGSET
20
#define ELF_EXEC_PAGESIZE	PAGE_SIZE
L
Linus Torvalds 已提交
21

22 23 24 25 26 27 28
/*
 * This is the base location for PIE (ET_DYN with INTERP) loads. On
 * 64-bit, this is raised to 4GB to leave the entire 32-bit address
 * space open for things that want to use the area for 32-bit pointers.
 */
#define ELF_ET_DYN_BASE		(is_32bit_task() ? 0x000400000UL : \
						   0x100000000UL)
L
Linus Torvalds 已提交
29

30 31
#define ELF_CORE_EFLAGS (is_elf2_task() ? 2 : 0)

32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
/*
 * Our registers are always unsigned longs, whether we're a 32 bit
 * process or 64 bit, on either a 64 bit or 32 bit kernel.
 *
 * This macro relies on elf_regs[i] having the right type to truncate to,
 * either u32 or u64.  It defines the body of the elf_core_copy_regs
 * function, either the native one with elf_gregset_t elf_regs or
 * the 32-bit one with elf_gregset_t32 elf_regs.
 */
#define PPC_ELF_CORE_COPY_REGS(elf_regs, regs) \
	int i, nregs = min(sizeof(*regs) / sizeof(unsigned long), \
			   (size_t)ELF_NGREG);			  \
	for (i = 0; i < nregs; i++) \
		elf_regs[i] = ((unsigned long *) regs)[i]; \
	memset(&elf_regs[i], 0, (ELF_NGREG - i) * sizeof(elf_regs[0]))

/* Common routine for both 32-bit and 64-bit native processes */
B
Becky Bruce 已提交
49
static inline void ppc_elf_core_copy_regs(elf_gregset_t elf_regs,
50
					  struct pt_regs *regs)
L
Linus Torvalds 已提交
51
{
52
	PPC_ELF_CORE_COPY_REGS(elf_regs, regs);
L
Linus Torvalds 已提交
53
}
B
Becky Bruce 已提交
54
#define ELF_CORE_COPY_REGS(gregs, regs) ppc_elf_core_copy_regs(gregs, regs);
L
Linus Torvalds 已提交
55

56 57
typedef elf_vrregset_t elf_fpxregset_t;

B
Becky Bruce 已提交
58
/* ELF_HWCAP yields a mask that user programs can use to figure out what
L
Linus Torvalds 已提交
59 60
   instruction set this cpu supports.  This could be done in userspace,
   but it's not easy, and we've already done it here.  */
B
Becky Bruce 已提交
61
# define ELF_HWCAP	(cur_cpu_spec->cpu_user_features)
M
Michael Neuling 已提交
62
# define ELF_HWCAP2	(cur_cpu_spec->cpu_user_features2)
L
Linus Torvalds 已提交
63 64 65

/* This yields a string that ld.so will use to load implementation
   specific libraries for optimization.  This is more specific in
66
   intent than poking at uname or /proc/cpuinfo.  */
L
Linus Torvalds 已提交
67

68
#define ELF_PLATFORM	(cur_cpu_spec->platform)
69 70 71 72 73 74 75 76

/* While ELF_PLATFORM indicates the ISA supported by the platform, it
 * may not accurately reflect the underlying behavior of the hardware
 * (as in the case of running in Power5+ compatibility mode on a
 * Power6 machine).  ELF_BASE_PLATFORM allows ld.so to load libraries
 * that are tuned for the real hardware.
 */
#define ELF_BASE_PLATFORM (powerpc_base_platform)
L
Linus Torvalds 已提交
77

78 79 80 81 82
#ifdef __powerpc64__
# define ELF_PLAT_INIT(_r, load_addr)	do {	\
	_r->gpr[2] = load_addr; 		\
} while (0)
#endif /* __powerpc64__ */
L
Linus Torvalds 已提交
83

B
Becky Bruce 已提交
84
#ifdef __powerpc64__
85
# define SET_PERSONALITY(ex)					\
L
Linus Torvalds 已提交
86
do {								\
R
Rusty Russell 已提交
87 88
	if (((ex).e_flags & 0x3) == 2)				\
		set_thread_flag(TIF_ELF2ABI);			\
89 90
	else							\
		clear_thread_flag(TIF_ELF2ABI);			\
L
Linus Torvalds 已提交
91
	if ((ex).e_ident[EI_CLASS] == ELFCLASS32)		\
92
		set_thread_flag(TIF_32BIT);			\
L
Linus Torvalds 已提交
93
	else							\
94
		clear_thread_flag(TIF_32BIT);			\
95
	if (personality(current->personality) != PER_LINUX32)	\
96 97
		set_personality(PER_LINUX |			\
			(current->personality & (~PER_MASK)));	\
L
Linus Torvalds 已提交
98 99 100
} while (0)
/*
 * An executable for which elf_read_implies_exec() returns TRUE will
A
Anton Blanchard 已提交
101 102 103 104
 * have the READ_IMPLIES_EXEC personality flag set automatically. This
 * is only required to work around bugs in old 32bit toolchains. Since
 * the 64bit ABI has never had these issues dont enable the workaround
 * even if we have an executable stack.
L
Linus Torvalds 已提交
105
 */
106
# define elf_read_implies_exec(ex, exec_stk) (is_32bit_task() ? \
107
		(exec_stk == EXSTACK_DEFAULT) : 0)
B
Becky Bruce 已提交
108
#else 
109
# define elf_read_implies_exec(ex, exec_stk) (exec_stk == EXSTACK_DEFAULT)
B
Becky Bruce 已提交
110
#endif /* __powerpc64__ */
L
Linus Torvalds 已提交
111 112 113 114 115

extern int dcache_bsize;
extern int icache_bsize;
extern int ucache_bsize;

116 117
/* vDSO has arch_setup_additional_pages */
#define ARCH_HAS_SETUP_ADDITIONAL_PAGES
L
Linus Torvalds 已提交
118
struct linux_binprm;
119
extern int arch_setup_additional_pages(struct linux_binprm *bprm,
120
				       int uses_interp);
121
#define VDSO_AUX_ENT(a,b) NEW_AUX_ENT(a,b)
L
Linus Torvalds 已提交
122

123 124 125 126 127
/* 1GB for 64bit, 8MB for 32bit */
#define STACK_RND_MASK (is_32bit_task() ? \
	(0x7ff >> (PAGE_SHIFT - 12)) : \
	(0x3ffff >> (PAGE_SHIFT - 12)))

128
#ifdef CONFIG_SPU_BASE
129 130 131 132
/* Notes used in ET_CORE. Note name is "SPU/<fd>/<filename>". */
#define NT_SPU		1

#define ARCH_HAVE_EXTRA_ELF_NOTES
133 134

#endif /* CONFIG_SPU_BASE */
135

136 137 138 139 140 141 142 143
#ifdef CONFIG_PPC64

#define get_cache_geometry(level) \
	(ppc64_caches.level.assoc << 16 | ppc64_caches.level.line_size)

#define ARCH_DLINFO_CACHE_GEOMETRY					\
	NEW_AUX_ENT(AT_L1I_CACHESIZE, ppc64_caches.l1i.size);		\
	NEW_AUX_ENT(AT_L1I_CACHEGEOMETRY, get_cache_geometry(l1i));	\
144 145
	NEW_AUX_ENT(AT_L1D_CACHESIZE, ppc64_caches.l1d.size);		\
	NEW_AUX_ENT(AT_L1D_CACHEGEOMETRY, get_cache_geometry(l1d));	\
146 147 148 149 150 151 152 153 154
	NEW_AUX_ENT(AT_L2_CACHESIZE, ppc64_caches.l2.size);		\
	NEW_AUX_ENT(AT_L2_CACHEGEOMETRY, get_cache_geometry(l2));	\
	NEW_AUX_ENT(AT_L3_CACHESIZE, ppc64_caches.l3.size);		\
	NEW_AUX_ENT(AT_L3_CACHEGEOMETRY, get_cache_geometry(l3))

#else
#define ARCH_DLINFO_CACHE_GEOMETRY
#endif

155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174
/*
 * The requirements here are:
 * - keep the final alignment of sp (sp & 0xf)
 * - make sure the 32-bit value at the first 16 byte aligned position of
 *   AUXV is greater than 16 for glibc compatibility.
 *   AT_IGNOREPPC is used for that.
 * - for compatibility with glibc ARCH_DLINFO must always be defined on PPC,
 *   even if DLINFO_ARCH_ITEMS goes to zero or is undefined.
 * update AT_VECTOR_SIZE_ARCH if the number of NEW_AUX_ENT entries changes
 */
#define ARCH_DLINFO							\
do {									\
	/* Handle glibc compatibility. */				\
	NEW_AUX_ENT(AT_IGNOREPPC, AT_IGNOREPPC);			\
	NEW_AUX_ENT(AT_IGNOREPPC, AT_IGNOREPPC);			\
	/* Cache size items */						\
	NEW_AUX_ENT(AT_DCACHEBSIZE, dcache_bsize);			\
	NEW_AUX_ENT(AT_ICACHEBSIZE, icache_bsize);			\
	NEW_AUX_ENT(AT_UCACHEBSIZE, ucache_bsize);			\
	VDSO_AUX_ENT(AT_SYSINFO_EHDR, current->mm->context.vdso_base);	\
175
	ARCH_DLINFO_CACHE_GEOMETRY;					\
176 177
} while (0)

178 179 180
/* Relocate the kernel image to @final_address */
void relocate(unsigned long final_address);

B
Becky Bruce 已提交
181
#endif /* _ASM_POWERPC_ELF_H */