18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
28c2ecf20Sopenharmony_ci#ifndef _ASM_X86_ELF_H
38c2ecf20Sopenharmony_ci#define _ASM_X86_ELF_H
48c2ecf20Sopenharmony_ci
58c2ecf20Sopenharmony_ci/*
68c2ecf20Sopenharmony_ci * ELF register definitions..
78c2ecf20Sopenharmony_ci */
88c2ecf20Sopenharmony_ci#include <linux/thread_info.h>
98c2ecf20Sopenharmony_ci
108c2ecf20Sopenharmony_ci#include <asm/ptrace.h>
118c2ecf20Sopenharmony_ci#include <asm/user.h>
128c2ecf20Sopenharmony_ci#include <asm/auxvec.h>
138c2ecf20Sopenharmony_ci#include <asm/fsgsbase.h>
148c2ecf20Sopenharmony_ci
158c2ecf20Sopenharmony_citypedef unsigned long elf_greg_t;
168c2ecf20Sopenharmony_ci
178c2ecf20Sopenharmony_ci#define ELF_NGREG (sizeof(struct user_regs_struct) / sizeof(elf_greg_t))
188c2ecf20Sopenharmony_citypedef elf_greg_t elf_gregset_t[ELF_NGREG];
198c2ecf20Sopenharmony_ci
208c2ecf20Sopenharmony_citypedef struct user_i387_struct elf_fpregset_t;
218c2ecf20Sopenharmony_ci
228c2ecf20Sopenharmony_ci#ifdef __i386__
238c2ecf20Sopenharmony_ci
248c2ecf20Sopenharmony_ci#define R_386_NONE	0
258c2ecf20Sopenharmony_ci#define R_386_32	1
268c2ecf20Sopenharmony_ci#define R_386_PC32	2
278c2ecf20Sopenharmony_ci#define R_386_GOT32	3
288c2ecf20Sopenharmony_ci#define R_386_PLT32	4
298c2ecf20Sopenharmony_ci#define R_386_COPY	5
308c2ecf20Sopenharmony_ci#define R_386_GLOB_DAT	6
318c2ecf20Sopenharmony_ci#define R_386_JMP_SLOT	7
328c2ecf20Sopenharmony_ci#define R_386_RELATIVE	8
338c2ecf20Sopenharmony_ci#define R_386_GOTOFF	9
348c2ecf20Sopenharmony_ci#define R_386_GOTPC	10
358c2ecf20Sopenharmony_ci#define R_386_NUM	11
368c2ecf20Sopenharmony_ci
378c2ecf20Sopenharmony_ci/*
388c2ecf20Sopenharmony_ci * These are used to set parameters in the core dumps.
398c2ecf20Sopenharmony_ci */
408c2ecf20Sopenharmony_ci#define ELF_CLASS	ELFCLASS32
418c2ecf20Sopenharmony_ci#define ELF_DATA	ELFDATA2LSB
428c2ecf20Sopenharmony_ci#define ELF_ARCH	EM_386
438c2ecf20Sopenharmony_ci
448c2ecf20Sopenharmony_ci#else
458c2ecf20Sopenharmony_ci
468c2ecf20Sopenharmony_ci/* x86-64 relocation types */
478c2ecf20Sopenharmony_ci#define R_X86_64_NONE		0	/* No reloc */
488c2ecf20Sopenharmony_ci#define R_X86_64_64		1	/* Direct 64 bit  */
498c2ecf20Sopenharmony_ci#define R_X86_64_PC32		2	/* PC relative 32 bit signed */
508c2ecf20Sopenharmony_ci#define R_X86_64_GOT32		3	/* 32 bit GOT entry */
518c2ecf20Sopenharmony_ci#define R_X86_64_PLT32		4	/* 32 bit PLT address */
528c2ecf20Sopenharmony_ci#define R_X86_64_COPY		5	/* Copy symbol at runtime */
538c2ecf20Sopenharmony_ci#define R_X86_64_GLOB_DAT	6	/* Create GOT entry */
548c2ecf20Sopenharmony_ci#define R_X86_64_JUMP_SLOT	7	/* Create PLT entry */
558c2ecf20Sopenharmony_ci#define R_X86_64_RELATIVE	8	/* Adjust by program base */
568c2ecf20Sopenharmony_ci#define R_X86_64_GOTPCREL	9	/* 32 bit signed pc relative
578c2ecf20Sopenharmony_ci					   offset to GOT */
588c2ecf20Sopenharmony_ci#define R_X86_64_32		10	/* Direct 32 bit zero extended */
598c2ecf20Sopenharmony_ci#define R_X86_64_32S		11	/* Direct 32 bit sign extended */
608c2ecf20Sopenharmony_ci#define R_X86_64_16		12	/* Direct 16 bit zero extended */
618c2ecf20Sopenharmony_ci#define R_X86_64_PC16		13	/* 16 bit sign extended pc relative */
628c2ecf20Sopenharmony_ci#define R_X86_64_8		14	/* Direct 8 bit sign extended  */
638c2ecf20Sopenharmony_ci#define R_X86_64_PC8		15	/* 8 bit sign extended pc relative */
648c2ecf20Sopenharmony_ci#define R_X86_64_PC64		24	/* Place relative 64-bit signed */
658c2ecf20Sopenharmony_ci
668c2ecf20Sopenharmony_ci/*
678c2ecf20Sopenharmony_ci * These are used to set parameters in the core dumps.
688c2ecf20Sopenharmony_ci */
698c2ecf20Sopenharmony_ci#define ELF_CLASS	ELFCLASS64
708c2ecf20Sopenharmony_ci#define ELF_DATA	ELFDATA2LSB
718c2ecf20Sopenharmony_ci#define ELF_ARCH	EM_X86_64
728c2ecf20Sopenharmony_ci
738c2ecf20Sopenharmony_ci#endif
748c2ecf20Sopenharmony_ci
758c2ecf20Sopenharmony_ci#include <asm/vdso.h>
768c2ecf20Sopenharmony_ci
778c2ecf20Sopenharmony_ci#ifdef CONFIG_X86_64
788c2ecf20Sopenharmony_ciextern unsigned int vdso64_enabled;
798c2ecf20Sopenharmony_ci#endif
808c2ecf20Sopenharmony_ci#if defined(CONFIG_X86_32) || defined(CONFIG_IA32_EMULATION)
818c2ecf20Sopenharmony_ciextern unsigned int vdso32_enabled;
828c2ecf20Sopenharmony_ci#endif
838c2ecf20Sopenharmony_ci
848c2ecf20Sopenharmony_ci/*
858c2ecf20Sopenharmony_ci * This is used to ensure we don't load something for the wrong architecture.
868c2ecf20Sopenharmony_ci */
878c2ecf20Sopenharmony_ci#define elf_check_arch_ia32(x) \
888c2ecf20Sopenharmony_ci	(((x)->e_machine == EM_386) || ((x)->e_machine == EM_486))
898c2ecf20Sopenharmony_ci
908c2ecf20Sopenharmony_ci#include <asm/processor.h>
918c2ecf20Sopenharmony_ci
928c2ecf20Sopenharmony_ci#ifdef CONFIG_X86_32
938c2ecf20Sopenharmony_ci#include <asm/desc.h>
948c2ecf20Sopenharmony_ci
958c2ecf20Sopenharmony_ci#define elf_check_arch(x)	elf_check_arch_ia32(x)
968c2ecf20Sopenharmony_ci
978c2ecf20Sopenharmony_ci/* SVR4/i386 ABI (pages 3-31, 3-32) says that when the program starts %edx
988c2ecf20Sopenharmony_ci   contains a pointer to a function which might be registered using `atexit'.
998c2ecf20Sopenharmony_ci   This provides a mean for the dynamic linker to call DT_FINI functions for
1008c2ecf20Sopenharmony_ci   shared libraries that have been loaded before the code runs.
1018c2ecf20Sopenharmony_ci
1028c2ecf20Sopenharmony_ci   A value of 0 tells we have no such handler.
1038c2ecf20Sopenharmony_ci
1048c2ecf20Sopenharmony_ci   We might as well make sure everything else is cleared too (except for %esp),
1058c2ecf20Sopenharmony_ci   just to make things more deterministic.
1068c2ecf20Sopenharmony_ci */
1078c2ecf20Sopenharmony_ci#define ELF_PLAT_INIT(_r, load_addr)		\
1088c2ecf20Sopenharmony_ci	do {					\
1098c2ecf20Sopenharmony_ci	_r->bx = 0; _r->cx = 0; _r->dx = 0;	\
1108c2ecf20Sopenharmony_ci	_r->si = 0; _r->di = 0; _r->bp = 0;	\
1118c2ecf20Sopenharmony_ci	_r->ax = 0;				\
1128c2ecf20Sopenharmony_ci} while (0)
1138c2ecf20Sopenharmony_ci
1148c2ecf20Sopenharmony_ci/*
1158c2ecf20Sopenharmony_ci * regs is struct pt_regs, pr_reg is elf_gregset_t (which is
1168c2ecf20Sopenharmony_ci * now struct_user_regs, they are different)
1178c2ecf20Sopenharmony_ci */
1188c2ecf20Sopenharmony_ci
1198c2ecf20Sopenharmony_ci#define ELF_CORE_COPY_REGS_COMMON(pr_reg, regs)	\
1208c2ecf20Sopenharmony_cido {						\
1218c2ecf20Sopenharmony_ci	pr_reg[0] = regs->bx;			\
1228c2ecf20Sopenharmony_ci	pr_reg[1] = regs->cx;			\
1238c2ecf20Sopenharmony_ci	pr_reg[2] = regs->dx;			\
1248c2ecf20Sopenharmony_ci	pr_reg[3] = regs->si;			\
1258c2ecf20Sopenharmony_ci	pr_reg[4] = regs->di;			\
1268c2ecf20Sopenharmony_ci	pr_reg[5] = regs->bp;			\
1278c2ecf20Sopenharmony_ci	pr_reg[6] = regs->ax;			\
1288c2ecf20Sopenharmony_ci	pr_reg[7] = regs->ds;			\
1298c2ecf20Sopenharmony_ci	pr_reg[8] = regs->es;			\
1308c2ecf20Sopenharmony_ci	pr_reg[9] = regs->fs;			\
1318c2ecf20Sopenharmony_ci	pr_reg[11] = regs->orig_ax;		\
1328c2ecf20Sopenharmony_ci	pr_reg[12] = regs->ip;			\
1338c2ecf20Sopenharmony_ci	pr_reg[13] = regs->cs;			\
1348c2ecf20Sopenharmony_ci	pr_reg[14] = regs->flags;		\
1358c2ecf20Sopenharmony_ci	pr_reg[15] = regs->sp;			\
1368c2ecf20Sopenharmony_ci	pr_reg[16] = regs->ss;			\
1378c2ecf20Sopenharmony_ci} while (0);
1388c2ecf20Sopenharmony_ci
1398c2ecf20Sopenharmony_ci#define ELF_CORE_COPY_REGS(pr_reg, regs)	\
1408c2ecf20Sopenharmony_cido {						\
1418c2ecf20Sopenharmony_ci	ELF_CORE_COPY_REGS_COMMON(pr_reg, regs);\
1428c2ecf20Sopenharmony_ci	pr_reg[10] = get_user_gs(regs);		\
1438c2ecf20Sopenharmony_ci} while (0);
1448c2ecf20Sopenharmony_ci
1458c2ecf20Sopenharmony_ci#define ELF_CORE_COPY_KERNEL_REGS(pr_reg, regs)	\
1468c2ecf20Sopenharmony_cido {						\
1478c2ecf20Sopenharmony_ci	ELF_CORE_COPY_REGS_COMMON(pr_reg, regs);\
1488c2ecf20Sopenharmony_ci	savesegment(gs, pr_reg[10]);		\
1498c2ecf20Sopenharmony_ci} while (0);
1508c2ecf20Sopenharmony_ci
1518c2ecf20Sopenharmony_ci#define ELF_PLATFORM	(utsname()->machine)
1528c2ecf20Sopenharmony_ci#define set_personality_64bit()	do { } while (0)
1538c2ecf20Sopenharmony_ci
1548c2ecf20Sopenharmony_ci#else /* CONFIG_X86_32 */
1558c2ecf20Sopenharmony_ci
1568c2ecf20Sopenharmony_ci/*
1578c2ecf20Sopenharmony_ci * This is used to ensure we don't load something for the wrong architecture.
1588c2ecf20Sopenharmony_ci */
1598c2ecf20Sopenharmony_ci#define elf_check_arch(x)			\
1608c2ecf20Sopenharmony_ci	((x)->e_machine == EM_X86_64)
1618c2ecf20Sopenharmony_ci
1628c2ecf20Sopenharmony_ci#define compat_elf_check_arch(x)					\
1638c2ecf20Sopenharmony_ci	(elf_check_arch_ia32(x) ||					\
1648c2ecf20Sopenharmony_ci	 (IS_ENABLED(CONFIG_X86_X32_ABI) && (x)->e_machine == EM_X86_64))
1658c2ecf20Sopenharmony_ci
1668c2ecf20Sopenharmony_ci#if __USER32_DS != __USER_DS
1678c2ecf20Sopenharmony_ci# error "The following code assumes __USER32_DS == __USER_DS"
1688c2ecf20Sopenharmony_ci#endif
1698c2ecf20Sopenharmony_ci
1708c2ecf20Sopenharmony_cistatic inline void elf_common_init(struct thread_struct *t,
1718c2ecf20Sopenharmony_ci				   struct pt_regs *regs, const u16 ds)
1728c2ecf20Sopenharmony_ci{
1738c2ecf20Sopenharmony_ci	/* ax gets execve's return value. */
1748c2ecf20Sopenharmony_ci	/*regs->ax = */ regs->bx = regs->cx = regs->dx = 0;
1758c2ecf20Sopenharmony_ci	regs->si = regs->di = regs->bp = 0;
1768c2ecf20Sopenharmony_ci	regs->r8 = regs->r9 = regs->r10 = regs->r11 = 0;
1778c2ecf20Sopenharmony_ci	regs->r12 = regs->r13 = regs->r14 = regs->r15 = 0;
1788c2ecf20Sopenharmony_ci	t->fsbase = t->gsbase = 0;
1798c2ecf20Sopenharmony_ci	t->fsindex = t->gsindex = 0;
1808c2ecf20Sopenharmony_ci	t->ds = t->es = ds;
1818c2ecf20Sopenharmony_ci}
1828c2ecf20Sopenharmony_ci
1838c2ecf20Sopenharmony_ci#define ELF_PLAT_INIT(_r, load_addr)			\
1848c2ecf20Sopenharmony_ci	elf_common_init(&current->thread, _r, 0)
1858c2ecf20Sopenharmony_ci
1868c2ecf20Sopenharmony_ci#define	COMPAT_ELF_PLAT_INIT(regs, load_addr)		\
1878c2ecf20Sopenharmony_ci	elf_common_init(&current->thread, regs, __USER_DS)
1888c2ecf20Sopenharmony_ci
1898c2ecf20Sopenharmony_civoid compat_start_thread(struct pt_regs *regs, u32 new_ip, u32 new_sp);
1908c2ecf20Sopenharmony_ci#define compat_start_thread compat_start_thread
1918c2ecf20Sopenharmony_ci
1928c2ecf20Sopenharmony_civoid set_personality_ia32(bool);
1938c2ecf20Sopenharmony_ci#define COMPAT_SET_PERSONALITY(ex)			\
1948c2ecf20Sopenharmony_ci	set_personality_ia32((ex).e_machine == EM_X86_64)
1958c2ecf20Sopenharmony_ci
1968c2ecf20Sopenharmony_ci#define COMPAT_ELF_PLATFORM			("i686")
1978c2ecf20Sopenharmony_ci
1988c2ecf20Sopenharmony_ci/*
1998c2ecf20Sopenharmony_ci * regs is struct pt_regs, pr_reg is elf_gregset_t (which is
2008c2ecf20Sopenharmony_ci * now struct_user_regs, they are different). Assumes current is the process
2018c2ecf20Sopenharmony_ci * getting dumped.
2028c2ecf20Sopenharmony_ci */
2038c2ecf20Sopenharmony_ci
2048c2ecf20Sopenharmony_ci#define ELF_CORE_COPY_REGS(pr_reg, regs)			\
2058c2ecf20Sopenharmony_cido {								\
2068c2ecf20Sopenharmony_ci	unsigned v;						\
2078c2ecf20Sopenharmony_ci	(pr_reg)[0] = (regs)->r15;				\
2088c2ecf20Sopenharmony_ci	(pr_reg)[1] = (regs)->r14;				\
2098c2ecf20Sopenharmony_ci	(pr_reg)[2] = (regs)->r13;				\
2108c2ecf20Sopenharmony_ci	(pr_reg)[3] = (regs)->r12;				\
2118c2ecf20Sopenharmony_ci	(pr_reg)[4] = (regs)->bp;				\
2128c2ecf20Sopenharmony_ci	(pr_reg)[5] = (regs)->bx;				\
2138c2ecf20Sopenharmony_ci	(pr_reg)[6] = (regs)->r11;				\
2148c2ecf20Sopenharmony_ci	(pr_reg)[7] = (regs)->r10;				\
2158c2ecf20Sopenharmony_ci	(pr_reg)[8] = (regs)->r9;				\
2168c2ecf20Sopenharmony_ci	(pr_reg)[9] = (regs)->r8;				\
2178c2ecf20Sopenharmony_ci	(pr_reg)[10] = (regs)->ax;				\
2188c2ecf20Sopenharmony_ci	(pr_reg)[11] = (regs)->cx;				\
2198c2ecf20Sopenharmony_ci	(pr_reg)[12] = (regs)->dx;				\
2208c2ecf20Sopenharmony_ci	(pr_reg)[13] = (regs)->si;				\
2218c2ecf20Sopenharmony_ci	(pr_reg)[14] = (regs)->di;				\
2228c2ecf20Sopenharmony_ci	(pr_reg)[15] = (regs)->orig_ax;				\
2238c2ecf20Sopenharmony_ci	(pr_reg)[16] = (regs)->ip;				\
2248c2ecf20Sopenharmony_ci	(pr_reg)[17] = (regs)->cs;				\
2258c2ecf20Sopenharmony_ci	(pr_reg)[18] = (regs)->flags;				\
2268c2ecf20Sopenharmony_ci	(pr_reg)[19] = (regs)->sp;				\
2278c2ecf20Sopenharmony_ci	(pr_reg)[20] = (regs)->ss;				\
2288c2ecf20Sopenharmony_ci	(pr_reg)[21] = x86_fsbase_read_cpu();			\
2298c2ecf20Sopenharmony_ci	(pr_reg)[22] = x86_gsbase_read_cpu_inactive();		\
2308c2ecf20Sopenharmony_ci	asm("movl %%ds,%0" : "=r" (v)); (pr_reg)[23] = v;	\
2318c2ecf20Sopenharmony_ci	asm("movl %%es,%0" : "=r" (v)); (pr_reg)[24] = v;	\
2328c2ecf20Sopenharmony_ci	asm("movl %%fs,%0" : "=r" (v)); (pr_reg)[25] = v;	\
2338c2ecf20Sopenharmony_ci	asm("movl %%gs,%0" : "=r" (v)); (pr_reg)[26] = v;	\
2348c2ecf20Sopenharmony_ci} while (0);
2358c2ecf20Sopenharmony_ci
2368c2ecf20Sopenharmony_ci/* I'm not sure if we can use '-' here */
2378c2ecf20Sopenharmony_ci#define ELF_PLATFORM       ("x86_64")
2388c2ecf20Sopenharmony_ciextern void set_personality_64bit(void);
2398c2ecf20Sopenharmony_ciextern unsigned int sysctl_vsyscall32;
2408c2ecf20Sopenharmony_ciextern int force_personality32;
2418c2ecf20Sopenharmony_ci
2428c2ecf20Sopenharmony_ci#endif /* !CONFIG_X86_32 */
2438c2ecf20Sopenharmony_ci
2448c2ecf20Sopenharmony_ci#define CORE_DUMP_USE_REGSET
2458c2ecf20Sopenharmony_ci#define ELF_EXEC_PAGESIZE	4096
2468c2ecf20Sopenharmony_ci
2478c2ecf20Sopenharmony_ci/*
2488c2ecf20Sopenharmony_ci * This is the base location for PIE (ET_DYN with INTERP) loads. On
2498c2ecf20Sopenharmony_ci * 64-bit, this is above 4GB to leave the entire 32-bit address
2508c2ecf20Sopenharmony_ci * space open for things that want to use the area for 32-bit pointers.
2518c2ecf20Sopenharmony_ci */
2528c2ecf20Sopenharmony_ci#define ELF_ET_DYN_BASE		(mmap_is_ia32() ? 0x000400000UL : \
2538c2ecf20Sopenharmony_ci						  (DEFAULT_MAP_WINDOW / 3 * 2))
2548c2ecf20Sopenharmony_ci
2558c2ecf20Sopenharmony_ci/* This yields a mask that user programs can use to figure out what
2568c2ecf20Sopenharmony_ci   instruction set this CPU supports.  This could be done in user space,
2578c2ecf20Sopenharmony_ci   but it's not easy, and we've already done it here.  */
2588c2ecf20Sopenharmony_ci
2598c2ecf20Sopenharmony_ci#define ELF_HWCAP		(boot_cpu_data.x86_capability[CPUID_1_EDX])
2608c2ecf20Sopenharmony_ci
2618c2ecf20Sopenharmony_ciextern u32 elf_hwcap2;
2628c2ecf20Sopenharmony_ci
2638c2ecf20Sopenharmony_ci/*
2648c2ecf20Sopenharmony_ci * HWCAP2 supplies mask with kernel enabled CPU features, so that
2658c2ecf20Sopenharmony_ci * the application can discover that it can safely use them.
2668c2ecf20Sopenharmony_ci * The bits are defined in uapi/asm/hwcap2.h.
2678c2ecf20Sopenharmony_ci */
2688c2ecf20Sopenharmony_ci#define ELF_HWCAP2		(elf_hwcap2)
2698c2ecf20Sopenharmony_ci
2708c2ecf20Sopenharmony_ci/* This yields a string that ld.so will use to load implementation
2718c2ecf20Sopenharmony_ci   specific libraries for optimization.  This is more specific in
2728c2ecf20Sopenharmony_ci   intent than poking at uname or /proc/cpuinfo.
2738c2ecf20Sopenharmony_ci
2748c2ecf20Sopenharmony_ci   For the moment, we have only optimizations for the Intel generations,
2758c2ecf20Sopenharmony_ci   but that could change... */
2768c2ecf20Sopenharmony_ci
2778c2ecf20Sopenharmony_ci#define SET_PERSONALITY(ex) set_personality_64bit()
2788c2ecf20Sopenharmony_ci
2798c2ecf20Sopenharmony_ci/*
2808c2ecf20Sopenharmony_ci * An executable for which elf_read_implies_exec() returns TRUE will
2818c2ecf20Sopenharmony_ci * have the READ_IMPLIES_EXEC personality flag set automatically.
2828c2ecf20Sopenharmony_ci *
2838c2ecf20Sopenharmony_ci * The decision process for determining the results are:
2848c2ecf20Sopenharmony_ci *
2858c2ecf20Sopenharmony_ci *                 CPU: | lacks NX*  | has NX, ia32     | has NX, x86_64 |
2868c2ecf20Sopenharmony_ci * ELF:                 |            |                  |                |
2878c2ecf20Sopenharmony_ci * ---------------------|------------|------------------|----------------|
2888c2ecf20Sopenharmony_ci * missing PT_GNU_STACK | exec-all   | exec-all         | exec-none      |
2898c2ecf20Sopenharmony_ci * PT_GNU_STACK == RWX  | exec-stack | exec-stack       | exec-stack     |
2908c2ecf20Sopenharmony_ci * PT_GNU_STACK == RW   | exec-none  | exec-none        | exec-none      |
2918c2ecf20Sopenharmony_ci *
2928c2ecf20Sopenharmony_ci *  exec-all  : all PROT_READ user mappings are executable, except when
2938c2ecf20Sopenharmony_ci *              backed by files on a noexec-filesystem.
2948c2ecf20Sopenharmony_ci *  exec-none : only PROT_EXEC user mappings are executable.
2958c2ecf20Sopenharmony_ci *  exec-stack: only the stack and PROT_EXEC user mappings are executable.
2968c2ecf20Sopenharmony_ci *
2978c2ecf20Sopenharmony_ci *  *this column has no architectural effect: NX markings are ignored by
2988c2ecf20Sopenharmony_ci *   hardware, but may have behavioral effects when "wants X" collides with
2998c2ecf20Sopenharmony_ci *   "cannot be X" constraints in memory permission flags, as in
3008c2ecf20Sopenharmony_ci *   https://lkml.kernel.org/r/20190418055759.GA3155@mellanox.com
3018c2ecf20Sopenharmony_ci *
3028c2ecf20Sopenharmony_ci */
3038c2ecf20Sopenharmony_ci#define elf_read_implies_exec(ex, executable_stack)	\
3048c2ecf20Sopenharmony_ci	(mmap_is_ia32() && executable_stack == EXSTACK_DEFAULT)
3058c2ecf20Sopenharmony_ci
3068c2ecf20Sopenharmony_cistruct task_struct;
3078c2ecf20Sopenharmony_ci
3088c2ecf20Sopenharmony_ci#define	ARCH_DLINFO_IA32						\
3098c2ecf20Sopenharmony_cido {									\
3108c2ecf20Sopenharmony_ci	if (VDSO_CURRENT_BASE) {					\
3118c2ecf20Sopenharmony_ci		NEW_AUX_ENT(AT_SYSINFO,	VDSO_ENTRY);			\
3128c2ecf20Sopenharmony_ci		NEW_AUX_ENT(AT_SYSINFO_EHDR, VDSO_CURRENT_BASE);	\
3138c2ecf20Sopenharmony_ci	}								\
3148c2ecf20Sopenharmony_ci} while (0)
3158c2ecf20Sopenharmony_ci
3168c2ecf20Sopenharmony_ci/*
3178c2ecf20Sopenharmony_ci * True on X86_32 or when emulating IA32 on X86_64
3188c2ecf20Sopenharmony_ci */
3198c2ecf20Sopenharmony_cistatic inline int mmap_is_ia32(void)
3208c2ecf20Sopenharmony_ci{
3218c2ecf20Sopenharmony_ci	return IS_ENABLED(CONFIG_X86_32) ||
3228c2ecf20Sopenharmony_ci	       (IS_ENABLED(CONFIG_COMPAT) &&
3238c2ecf20Sopenharmony_ci		test_thread_flag(TIF_ADDR32));
3248c2ecf20Sopenharmony_ci}
3258c2ecf20Sopenharmony_ci
3268c2ecf20Sopenharmony_ciextern unsigned long task_size_32bit(void);
3278c2ecf20Sopenharmony_ciextern unsigned long task_size_64bit(int full_addr_space);
3288c2ecf20Sopenharmony_ciextern unsigned long get_mmap_base(int is_legacy);
3298c2ecf20Sopenharmony_ciextern bool mmap_address_hint_valid(unsigned long addr, unsigned long len);
3308c2ecf20Sopenharmony_ci
3318c2ecf20Sopenharmony_ci#ifdef CONFIG_X86_32
3328c2ecf20Sopenharmony_ci
3338c2ecf20Sopenharmony_ci#define __STACK_RND_MASK(is32bit) (0x7ff)
3348c2ecf20Sopenharmony_ci#define STACK_RND_MASK (0x7ff)
3358c2ecf20Sopenharmony_ci
3368c2ecf20Sopenharmony_ci#define ARCH_DLINFO		ARCH_DLINFO_IA32
3378c2ecf20Sopenharmony_ci
3388c2ecf20Sopenharmony_ci/* update AT_VECTOR_SIZE_ARCH if the number of NEW_AUX_ENT entries changes */
3398c2ecf20Sopenharmony_ci
3408c2ecf20Sopenharmony_ci#else /* CONFIG_X86_32 */
3418c2ecf20Sopenharmony_ci
3428c2ecf20Sopenharmony_ci/* 1GB for 64bit, 8MB for 32bit */
3438c2ecf20Sopenharmony_ci#define __STACK_RND_MASK(is32bit) ((is32bit) ? 0x7ff : 0x3fffff)
3448c2ecf20Sopenharmony_ci#define STACK_RND_MASK __STACK_RND_MASK(mmap_is_ia32())
3458c2ecf20Sopenharmony_ci
3468c2ecf20Sopenharmony_ci#define ARCH_DLINFO							\
3478c2ecf20Sopenharmony_cido {									\
3488c2ecf20Sopenharmony_ci	if (vdso64_enabled)						\
3498c2ecf20Sopenharmony_ci		NEW_AUX_ENT(AT_SYSINFO_EHDR,				\
3508c2ecf20Sopenharmony_ci			    (unsigned long __force)current->mm->context.vdso); \
3518c2ecf20Sopenharmony_ci} while (0)
3528c2ecf20Sopenharmony_ci
3538c2ecf20Sopenharmony_ci/* As a historical oddity, the x32 and x86_64 vDSOs are controlled together. */
3548c2ecf20Sopenharmony_ci#define ARCH_DLINFO_X32							\
3558c2ecf20Sopenharmony_cido {									\
3568c2ecf20Sopenharmony_ci	if (vdso64_enabled)						\
3578c2ecf20Sopenharmony_ci		NEW_AUX_ENT(AT_SYSINFO_EHDR,				\
3588c2ecf20Sopenharmony_ci			    (unsigned long __force)current->mm->context.vdso); \
3598c2ecf20Sopenharmony_ci} while (0)
3608c2ecf20Sopenharmony_ci
3618c2ecf20Sopenharmony_ci#define AT_SYSINFO		32
3628c2ecf20Sopenharmony_ci
3638c2ecf20Sopenharmony_ci#define COMPAT_ARCH_DLINFO						\
3648c2ecf20Sopenharmony_ciif (test_thread_flag(TIF_X32))						\
3658c2ecf20Sopenharmony_ci	ARCH_DLINFO_X32;						\
3668c2ecf20Sopenharmony_cielse									\
3678c2ecf20Sopenharmony_ci	ARCH_DLINFO_IA32
3688c2ecf20Sopenharmony_ci
3698c2ecf20Sopenharmony_ci#define COMPAT_ELF_ET_DYN_BASE	(TASK_UNMAPPED_BASE + 0x1000000)
3708c2ecf20Sopenharmony_ci
3718c2ecf20Sopenharmony_ci#endif /* !CONFIG_X86_32 */
3728c2ecf20Sopenharmony_ci
3738c2ecf20Sopenharmony_ci#define VDSO_CURRENT_BASE	((unsigned long)current->mm->context.vdso)
3748c2ecf20Sopenharmony_ci
3758c2ecf20Sopenharmony_ci#define VDSO_ENTRY							\
3768c2ecf20Sopenharmony_ci	((unsigned long)current->mm->context.vdso +			\
3778c2ecf20Sopenharmony_ci	 vdso_image_32.sym___kernel_vsyscall)
3788c2ecf20Sopenharmony_ci
3798c2ecf20Sopenharmony_cistruct linux_binprm;
3808c2ecf20Sopenharmony_ci
3818c2ecf20Sopenharmony_ci#define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1
3828c2ecf20Sopenharmony_ciextern int arch_setup_additional_pages(struct linux_binprm *bprm,
3838c2ecf20Sopenharmony_ci				       int uses_interp);
3848c2ecf20Sopenharmony_ciextern int compat_arch_setup_additional_pages(struct linux_binprm *bprm,
3858c2ecf20Sopenharmony_ci					      int uses_interp);
3868c2ecf20Sopenharmony_ci#define compat_arch_setup_additional_pages compat_arch_setup_additional_pages
3878c2ecf20Sopenharmony_ci
3888c2ecf20Sopenharmony_ci/* Do not change the values. See get_align_mask() */
3898c2ecf20Sopenharmony_cienum align_flags {
3908c2ecf20Sopenharmony_ci	ALIGN_VA_32	= BIT(0),
3918c2ecf20Sopenharmony_ci	ALIGN_VA_64	= BIT(1),
3928c2ecf20Sopenharmony_ci};
3938c2ecf20Sopenharmony_ci
3948c2ecf20Sopenharmony_cistruct va_alignment {
3958c2ecf20Sopenharmony_ci	int flags;
3968c2ecf20Sopenharmony_ci	unsigned long mask;
3978c2ecf20Sopenharmony_ci	unsigned long bits;
3988c2ecf20Sopenharmony_ci} ____cacheline_aligned;
3998c2ecf20Sopenharmony_ci
4008c2ecf20Sopenharmony_ciextern struct va_alignment va_align;
4018c2ecf20Sopenharmony_ciextern unsigned long align_vdso_addr(unsigned long);
4028c2ecf20Sopenharmony_ci#endif /* _ASM_X86_ELF_H */
403