162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
262306a36Sopenharmony_ci#ifndef _ASM_X86_ELF_H
362306a36Sopenharmony_ci#define _ASM_X86_ELF_H
462306a36Sopenharmony_ci
562306a36Sopenharmony_ci/*
662306a36Sopenharmony_ci * ELF register definitions..
762306a36Sopenharmony_ci */
862306a36Sopenharmony_ci#include <linux/thread_info.h>
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ci#include <asm/ptrace.h>
1162306a36Sopenharmony_ci#include <asm/user.h>
1262306a36Sopenharmony_ci#include <asm/auxvec.h>
1362306a36Sopenharmony_ci#include <asm/fsgsbase.h>
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_citypedef unsigned long elf_greg_t;
1662306a36Sopenharmony_ci
1762306a36Sopenharmony_ci#define ELF_NGREG (sizeof(struct user_regs_struct) / sizeof(elf_greg_t))
1862306a36Sopenharmony_citypedef elf_greg_t elf_gregset_t[ELF_NGREG];
1962306a36Sopenharmony_ci
2062306a36Sopenharmony_citypedef struct user_i387_struct elf_fpregset_t;
2162306a36Sopenharmony_ci
2262306a36Sopenharmony_ci#ifdef __i386__
2362306a36Sopenharmony_ci
2462306a36Sopenharmony_ci#define R_386_NONE	0
2562306a36Sopenharmony_ci#define R_386_32	1
2662306a36Sopenharmony_ci#define R_386_PC32	2
2762306a36Sopenharmony_ci#define R_386_GOT32	3
2862306a36Sopenharmony_ci#define R_386_PLT32	4
2962306a36Sopenharmony_ci#define R_386_COPY	5
3062306a36Sopenharmony_ci#define R_386_GLOB_DAT	6
3162306a36Sopenharmony_ci#define R_386_JMP_SLOT	7
3262306a36Sopenharmony_ci#define R_386_RELATIVE	8
3362306a36Sopenharmony_ci#define R_386_GOTOFF	9
3462306a36Sopenharmony_ci#define R_386_GOTPC	10
3562306a36Sopenharmony_ci#define R_386_NUM	11
3662306a36Sopenharmony_ci
3762306a36Sopenharmony_ci/*
3862306a36Sopenharmony_ci * These are used to set parameters in the core dumps.
3962306a36Sopenharmony_ci */
4062306a36Sopenharmony_ci#define ELF_CLASS	ELFCLASS32
4162306a36Sopenharmony_ci#define ELF_DATA	ELFDATA2LSB
4262306a36Sopenharmony_ci#define ELF_ARCH	EM_386
4362306a36Sopenharmony_ci
4462306a36Sopenharmony_ci#else
4562306a36Sopenharmony_ci
4662306a36Sopenharmony_ci/* x86-64 relocation types */
4762306a36Sopenharmony_ci#define R_X86_64_NONE		0	/* No reloc */
4862306a36Sopenharmony_ci#define R_X86_64_64		1	/* Direct 64 bit  */
4962306a36Sopenharmony_ci#define R_X86_64_PC32		2	/* PC relative 32 bit signed */
5062306a36Sopenharmony_ci#define R_X86_64_GOT32		3	/* 32 bit GOT entry */
5162306a36Sopenharmony_ci#define R_X86_64_PLT32		4	/* 32 bit PLT address */
5262306a36Sopenharmony_ci#define R_X86_64_COPY		5	/* Copy symbol at runtime */
5362306a36Sopenharmony_ci#define R_X86_64_GLOB_DAT	6	/* Create GOT entry */
5462306a36Sopenharmony_ci#define R_X86_64_JUMP_SLOT	7	/* Create PLT entry */
5562306a36Sopenharmony_ci#define R_X86_64_RELATIVE	8	/* Adjust by program base */
5662306a36Sopenharmony_ci#define R_X86_64_GOTPCREL	9	/* 32 bit signed pc relative
5762306a36Sopenharmony_ci					   offset to GOT */
5862306a36Sopenharmony_ci#define R_X86_64_32		10	/* Direct 32 bit zero extended */
5962306a36Sopenharmony_ci#define R_X86_64_32S		11	/* Direct 32 bit sign extended */
6062306a36Sopenharmony_ci#define R_X86_64_16		12	/* Direct 16 bit zero extended */
6162306a36Sopenharmony_ci#define R_X86_64_PC16		13	/* 16 bit sign extended pc relative */
6262306a36Sopenharmony_ci#define R_X86_64_8		14	/* Direct 8 bit sign extended  */
6362306a36Sopenharmony_ci#define R_X86_64_PC8		15	/* 8 bit sign extended pc relative */
6462306a36Sopenharmony_ci#define R_X86_64_PC64		24	/* Place relative 64-bit signed */
6562306a36Sopenharmony_ci
6662306a36Sopenharmony_ci/*
6762306a36Sopenharmony_ci * These are used to set parameters in the core dumps.
6862306a36Sopenharmony_ci */
6962306a36Sopenharmony_ci#define ELF_CLASS	ELFCLASS64
7062306a36Sopenharmony_ci#define ELF_DATA	ELFDATA2LSB
7162306a36Sopenharmony_ci#define ELF_ARCH	EM_X86_64
7262306a36Sopenharmony_ci
7362306a36Sopenharmony_ci#endif
7462306a36Sopenharmony_ci
7562306a36Sopenharmony_ci#include <asm/vdso.h>
7662306a36Sopenharmony_ci
7762306a36Sopenharmony_ci#ifdef CONFIG_X86_64
7862306a36Sopenharmony_ciextern unsigned int vdso64_enabled;
7962306a36Sopenharmony_ci#endif
8062306a36Sopenharmony_ci#if defined(CONFIG_X86_32) || defined(CONFIG_IA32_EMULATION)
8162306a36Sopenharmony_ciextern unsigned int vdso32_enabled;
8262306a36Sopenharmony_ci#endif
8362306a36Sopenharmony_ci
8462306a36Sopenharmony_ci/*
8562306a36Sopenharmony_ci * This is used to ensure we don't load something for the wrong architecture.
8662306a36Sopenharmony_ci */
8762306a36Sopenharmony_ci#define elf_check_arch_ia32(x) \
8862306a36Sopenharmony_ci	(((x)->e_machine == EM_386) || ((x)->e_machine == EM_486))
8962306a36Sopenharmony_ci
9062306a36Sopenharmony_ci#include <asm/processor.h>
9162306a36Sopenharmony_ci
9262306a36Sopenharmony_ci#ifdef CONFIG_X86_32
9362306a36Sopenharmony_ci#include <asm/desc.h>
9462306a36Sopenharmony_ci
9562306a36Sopenharmony_ci#define elf_check_arch(x)	elf_check_arch_ia32(x)
9662306a36Sopenharmony_ci
9762306a36Sopenharmony_ci/* SVR4/i386 ABI (pages 3-31, 3-32) says that when the program starts %edx
9862306a36Sopenharmony_ci   contains a pointer to a function which might be registered using `atexit'.
9962306a36Sopenharmony_ci   This provides a mean for the dynamic linker to call DT_FINI functions for
10062306a36Sopenharmony_ci   shared libraries that have been loaded before the code runs.
10162306a36Sopenharmony_ci
10262306a36Sopenharmony_ci   A value of 0 tells we have no such handler.
10362306a36Sopenharmony_ci
10462306a36Sopenharmony_ci   We might as well make sure everything else is cleared too (except for %esp),
10562306a36Sopenharmony_ci   just to make things more deterministic.
10662306a36Sopenharmony_ci */
10762306a36Sopenharmony_ci#define ELF_PLAT_INIT(_r, load_addr)		\
10862306a36Sopenharmony_ci	do {					\
10962306a36Sopenharmony_ci	_r->bx = 0; _r->cx = 0; _r->dx = 0;	\
11062306a36Sopenharmony_ci	_r->si = 0; _r->di = 0; _r->bp = 0;	\
11162306a36Sopenharmony_ci	_r->ax = 0;				\
11262306a36Sopenharmony_ci} while (0)
11362306a36Sopenharmony_ci
11462306a36Sopenharmony_ci/*
11562306a36Sopenharmony_ci * regs is struct pt_regs, pr_reg is elf_gregset_t (which is
11662306a36Sopenharmony_ci * now struct_user_regs, they are different)
11762306a36Sopenharmony_ci */
11862306a36Sopenharmony_ci
11962306a36Sopenharmony_ci#define ELF_CORE_COPY_REGS(pr_reg, regs)	\
12062306a36Sopenharmony_cido {						\
12162306a36Sopenharmony_ci	pr_reg[0] = regs->bx;			\
12262306a36Sopenharmony_ci	pr_reg[1] = regs->cx;			\
12362306a36Sopenharmony_ci	pr_reg[2] = regs->dx;			\
12462306a36Sopenharmony_ci	pr_reg[3] = regs->si;			\
12562306a36Sopenharmony_ci	pr_reg[4] = regs->di;			\
12662306a36Sopenharmony_ci	pr_reg[5] = regs->bp;			\
12762306a36Sopenharmony_ci	pr_reg[6] = regs->ax;			\
12862306a36Sopenharmony_ci	pr_reg[7] = regs->ds;			\
12962306a36Sopenharmony_ci	pr_reg[8] = regs->es;			\
13062306a36Sopenharmony_ci	pr_reg[9] = regs->fs;			\
13162306a36Sopenharmony_ci	savesegment(gs, pr_reg[10]);		\
13262306a36Sopenharmony_ci	pr_reg[11] = regs->orig_ax;		\
13362306a36Sopenharmony_ci	pr_reg[12] = regs->ip;			\
13462306a36Sopenharmony_ci	pr_reg[13] = regs->cs;			\
13562306a36Sopenharmony_ci	pr_reg[14] = regs->flags;		\
13662306a36Sopenharmony_ci	pr_reg[15] = regs->sp;			\
13762306a36Sopenharmony_ci	pr_reg[16] = regs->ss;			\
13862306a36Sopenharmony_ci} while (0);
13962306a36Sopenharmony_ci
14062306a36Sopenharmony_ci#define ELF_PLATFORM	(utsname()->machine)
14162306a36Sopenharmony_ci#define set_personality_64bit()	do { } while (0)
14262306a36Sopenharmony_ci
14362306a36Sopenharmony_ci#else /* CONFIG_X86_32 */
14462306a36Sopenharmony_ci
14562306a36Sopenharmony_ci/*
14662306a36Sopenharmony_ci * This is used to ensure we don't load something for the wrong architecture.
14762306a36Sopenharmony_ci */
14862306a36Sopenharmony_ci#define elf_check_arch(x)			\
14962306a36Sopenharmony_ci	((x)->e_machine == EM_X86_64)
15062306a36Sopenharmony_ci
15162306a36Sopenharmony_ci#define compat_elf_check_arch(x)					\
15262306a36Sopenharmony_ci	(elf_check_arch_ia32(x) ||					\
15362306a36Sopenharmony_ci	 (IS_ENABLED(CONFIG_X86_X32_ABI) && (x)->e_machine == EM_X86_64))
15462306a36Sopenharmony_ci
15562306a36Sopenharmony_cistatic inline void elf_common_init(struct thread_struct *t,
15662306a36Sopenharmony_ci				   struct pt_regs *regs, const u16 ds)
15762306a36Sopenharmony_ci{
15862306a36Sopenharmony_ci	/* ax gets execve's return value. */
15962306a36Sopenharmony_ci	/*regs->ax = */ regs->bx = regs->cx = regs->dx = 0;
16062306a36Sopenharmony_ci	regs->si = regs->di = regs->bp = 0;
16162306a36Sopenharmony_ci	regs->r8 = regs->r9 = regs->r10 = regs->r11 = 0;
16262306a36Sopenharmony_ci	regs->r12 = regs->r13 = regs->r14 = regs->r15 = 0;
16362306a36Sopenharmony_ci	t->fsbase = t->gsbase = 0;
16462306a36Sopenharmony_ci	t->fsindex = t->gsindex = 0;
16562306a36Sopenharmony_ci	t->ds = t->es = ds;
16662306a36Sopenharmony_ci}
16762306a36Sopenharmony_ci
16862306a36Sopenharmony_ci#define ELF_PLAT_INIT(_r, load_addr)			\
16962306a36Sopenharmony_ci	elf_common_init(&current->thread, _r, 0)
17062306a36Sopenharmony_ci
17162306a36Sopenharmony_ci#define	COMPAT_ELF_PLAT_INIT(regs, load_addr)		\
17262306a36Sopenharmony_ci	elf_common_init(&current->thread, regs, __USER_DS)
17362306a36Sopenharmony_ci
17462306a36Sopenharmony_civoid compat_start_thread(struct pt_regs *regs, u32 new_ip, u32 new_sp, bool x32);
17562306a36Sopenharmony_ci#define COMPAT_START_THREAD(ex, regs, new_ip, new_sp)	\
17662306a36Sopenharmony_ci	compat_start_thread(regs, new_ip, new_sp, ex->e_machine == EM_X86_64)
17762306a36Sopenharmony_ci
17862306a36Sopenharmony_civoid set_personality_ia32(bool);
17962306a36Sopenharmony_ci#define COMPAT_SET_PERSONALITY(ex)			\
18062306a36Sopenharmony_ci	set_personality_ia32((ex).e_machine == EM_X86_64)
18162306a36Sopenharmony_ci
18262306a36Sopenharmony_ci#define COMPAT_ELF_PLATFORM			("i686")
18362306a36Sopenharmony_ci
18462306a36Sopenharmony_ci/*
18562306a36Sopenharmony_ci * regs is struct pt_regs, pr_reg is elf_gregset_t (which is
18662306a36Sopenharmony_ci * now struct_user_regs, they are different). Assumes current is the process
18762306a36Sopenharmony_ci * getting dumped.
18862306a36Sopenharmony_ci */
18962306a36Sopenharmony_ci
19062306a36Sopenharmony_ci#define ELF_CORE_COPY_REGS(pr_reg, regs)			\
19162306a36Sopenharmony_cido {								\
19262306a36Sopenharmony_ci	unsigned v;						\
19362306a36Sopenharmony_ci	(pr_reg)[0] = (regs)->r15;				\
19462306a36Sopenharmony_ci	(pr_reg)[1] = (regs)->r14;				\
19562306a36Sopenharmony_ci	(pr_reg)[2] = (regs)->r13;				\
19662306a36Sopenharmony_ci	(pr_reg)[3] = (regs)->r12;				\
19762306a36Sopenharmony_ci	(pr_reg)[4] = (regs)->bp;				\
19862306a36Sopenharmony_ci	(pr_reg)[5] = (regs)->bx;				\
19962306a36Sopenharmony_ci	(pr_reg)[6] = (regs)->r11;				\
20062306a36Sopenharmony_ci	(pr_reg)[7] = (regs)->r10;				\
20162306a36Sopenharmony_ci	(pr_reg)[8] = (regs)->r9;				\
20262306a36Sopenharmony_ci	(pr_reg)[9] = (regs)->r8;				\
20362306a36Sopenharmony_ci	(pr_reg)[10] = (regs)->ax;				\
20462306a36Sopenharmony_ci	(pr_reg)[11] = (regs)->cx;				\
20562306a36Sopenharmony_ci	(pr_reg)[12] = (regs)->dx;				\
20662306a36Sopenharmony_ci	(pr_reg)[13] = (regs)->si;				\
20762306a36Sopenharmony_ci	(pr_reg)[14] = (regs)->di;				\
20862306a36Sopenharmony_ci	(pr_reg)[15] = (regs)->orig_ax;				\
20962306a36Sopenharmony_ci	(pr_reg)[16] = (regs)->ip;				\
21062306a36Sopenharmony_ci	(pr_reg)[17] = (regs)->cs;				\
21162306a36Sopenharmony_ci	(pr_reg)[18] = (regs)->flags;				\
21262306a36Sopenharmony_ci	(pr_reg)[19] = (regs)->sp;				\
21362306a36Sopenharmony_ci	(pr_reg)[20] = (regs)->ss;				\
21462306a36Sopenharmony_ci	(pr_reg)[21] = x86_fsbase_read_cpu();			\
21562306a36Sopenharmony_ci	(pr_reg)[22] = x86_gsbase_read_cpu_inactive();		\
21662306a36Sopenharmony_ci	asm("movl %%ds,%0" : "=r" (v)); (pr_reg)[23] = v;	\
21762306a36Sopenharmony_ci	asm("movl %%es,%0" : "=r" (v)); (pr_reg)[24] = v;	\
21862306a36Sopenharmony_ci	asm("movl %%fs,%0" : "=r" (v)); (pr_reg)[25] = v;	\
21962306a36Sopenharmony_ci	asm("movl %%gs,%0" : "=r" (v)); (pr_reg)[26] = v;	\
22062306a36Sopenharmony_ci} while (0);
22162306a36Sopenharmony_ci
22262306a36Sopenharmony_ci/* I'm not sure if we can use '-' here */
22362306a36Sopenharmony_ci#define ELF_PLATFORM       ("x86_64")
22462306a36Sopenharmony_ciextern void set_personality_64bit(void);
22562306a36Sopenharmony_ciextern int force_personality32;
22662306a36Sopenharmony_ci
22762306a36Sopenharmony_ci#endif /* !CONFIG_X86_32 */
22862306a36Sopenharmony_ci
22962306a36Sopenharmony_ci#define CORE_DUMP_USE_REGSET
23062306a36Sopenharmony_ci#define ELF_EXEC_PAGESIZE	4096
23162306a36Sopenharmony_ci
23262306a36Sopenharmony_ci/*
23362306a36Sopenharmony_ci * This is the base location for PIE (ET_DYN with INTERP) loads. On
23462306a36Sopenharmony_ci * 64-bit, this is above 4GB to leave the entire 32-bit address
23562306a36Sopenharmony_ci * space open for things that want to use the area for 32-bit pointers.
23662306a36Sopenharmony_ci */
23762306a36Sopenharmony_ci#define ELF_ET_DYN_BASE		(mmap_is_ia32() ? 0x000400000UL : \
23862306a36Sopenharmony_ci						  (DEFAULT_MAP_WINDOW / 3 * 2))
23962306a36Sopenharmony_ci
24062306a36Sopenharmony_ci/* This yields a mask that user programs can use to figure out what
24162306a36Sopenharmony_ci   instruction set this CPU supports.  This could be done in user space,
24262306a36Sopenharmony_ci   but it's not easy, and we've already done it here.  */
24362306a36Sopenharmony_ci
24462306a36Sopenharmony_ci#define ELF_HWCAP		(boot_cpu_data.x86_capability[CPUID_1_EDX])
24562306a36Sopenharmony_ci
24662306a36Sopenharmony_ciextern u32 elf_hwcap2;
24762306a36Sopenharmony_ci
24862306a36Sopenharmony_ci/*
24962306a36Sopenharmony_ci * HWCAP2 supplies mask with kernel enabled CPU features, so that
25062306a36Sopenharmony_ci * the application can discover that it can safely use them.
25162306a36Sopenharmony_ci * The bits are defined in uapi/asm/hwcap2.h.
25262306a36Sopenharmony_ci */
25362306a36Sopenharmony_ci#define ELF_HWCAP2		(elf_hwcap2)
25462306a36Sopenharmony_ci
25562306a36Sopenharmony_ci/* This yields a string that ld.so will use to load implementation
25662306a36Sopenharmony_ci   specific libraries for optimization.  This is more specific in
25762306a36Sopenharmony_ci   intent than poking at uname or /proc/cpuinfo.
25862306a36Sopenharmony_ci
25962306a36Sopenharmony_ci   For the moment, we have only optimizations for the Intel generations,
26062306a36Sopenharmony_ci   but that could change... */
26162306a36Sopenharmony_ci
26262306a36Sopenharmony_ci#define SET_PERSONALITY(ex) set_personality_64bit()
26362306a36Sopenharmony_ci
26462306a36Sopenharmony_ci/*
26562306a36Sopenharmony_ci * An executable for which elf_read_implies_exec() returns TRUE will
26662306a36Sopenharmony_ci * have the READ_IMPLIES_EXEC personality flag set automatically.
26762306a36Sopenharmony_ci *
26862306a36Sopenharmony_ci * The decision process for determining the results are:
26962306a36Sopenharmony_ci *
27062306a36Sopenharmony_ci *                 CPU: | lacks NX*  | has NX, ia32     | has NX, x86_64 |
27162306a36Sopenharmony_ci * ELF:                 |            |                  |                |
27262306a36Sopenharmony_ci * ---------------------|------------|------------------|----------------|
27362306a36Sopenharmony_ci * missing PT_GNU_STACK | exec-all   | exec-all         | exec-none      |
27462306a36Sopenharmony_ci * PT_GNU_STACK == RWX  | exec-stack | exec-stack       | exec-stack     |
27562306a36Sopenharmony_ci * PT_GNU_STACK == RW   | exec-none  | exec-none        | exec-none      |
27662306a36Sopenharmony_ci *
27762306a36Sopenharmony_ci *  exec-all  : all PROT_READ user mappings are executable, except when
27862306a36Sopenharmony_ci *              backed by files on a noexec-filesystem.
27962306a36Sopenharmony_ci *  exec-none : only PROT_EXEC user mappings are executable.
28062306a36Sopenharmony_ci *  exec-stack: only the stack and PROT_EXEC user mappings are executable.
28162306a36Sopenharmony_ci *
28262306a36Sopenharmony_ci *  *this column has no architectural effect: NX markings are ignored by
28362306a36Sopenharmony_ci *   hardware, but may have behavioral effects when "wants X" collides with
28462306a36Sopenharmony_ci *   "cannot be X" constraints in memory permission flags, as in
28562306a36Sopenharmony_ci *   https://lkml.kernel.org/r/20190418055759.GA3155@mellanox.com
28662306a36Sopenharmony_ci *
28762306a36Sopenharmony_ci */
28862306a36Sopenharmony_ci#define elf_read_implies_exec(ex, executable_stack)	\
28962306a36Sopenharmony_ci	(mmap_is_ia32() && executable_stack == EXSTACK_DEFAULT)
29062306a36Sopenharmony_ci
29162306a36Sopenharmony_cistruct task_struct;
29262306a36Sopenharmony_ci
29362306a36Sopenharmony_ci#define	ARCH_DLINFO_IA32						\
29462306a36Sopenharmony_cido {									\
29562306a36Sopenharmony_ci	if (VDSO_CURRENT_BASE) {					\
29662306a36Sopenharmony_ci		NEW_AUX_ENT(AT_SYSINFO,	VDSO_ENTRY);			\
29762306a36Sopenharmony_ci		NEW_AUX_ENT(AT_SYSINFO_EHDR, VDSO_CURRENT_BASE);	\
29862306a36Sopenharmony_ci	}								\
29962306a36Sopenharmony_ci	NEW_AUX_ENT(AT_MINSIGSTKSZ, get_sigframe_size());		\
30062306a36Sopenharmony_ci} while (0)
30162306a36Sopenharmony_ci
30262306a36Sopenharmony_ci/*
30362306a36Sopenharmony_ci * True on X86_32 or when emulating IA32 on X86_64
30462306a36Sopenharmony_ci */
30562306a36Sopenharmony_cistatic inline int mmap_is_ia32(void)
30662306a36Sopenharmony_ci{
30762306a36Sopenharmony_ci	return IS_ENABLED(CONFIG_X86_32) ||
30862306a36Sopenharmony_ci	       (IS_ENABLED(CONFIG_COMPAT) &&
30962306a36Sopenharmony_ci		test_thread_flag(TIF_ADDR32));
31062306a36Sopenharmony_ci}
31162306a36Sopenharmony_ci
31262306a36Sopenharmony_ciextern unsigned long task_size_32bit(void);
31362306a36Sopenharmony_ciextern unsigned long task_size_64bit(int full_addr_space);
31462306a36Sopenharmony_ciextern unsigned long get_mmap_base(int is_legacy);
31562306a36Sopenharmony_ciextern bool mmap_address_hint_valid(unsigned long addr, unsigned long len);
31662306a36Sopenharmony_ciextern unsigned long get_sigframe_size(void);
31762306a36Sopenharmony_ci
31862306a36Sopenharmony_ci#ifdef CONFIG_X86_32
31962306a36Sopenharmony_ci
32062306a36Sopenharmony_ci#define __STACK_RND_MASK(is32bit) (0x7ff)
32162306a36Sopenharmony_ci#define STACK_RND_MASK (0x7ff)
32262306a36Sopenharmony_ci
32362306a36Sopenharmony_ci#define ARCH_DLINFO		ARCH_DLINFO_IA32
32462306a36Sopenharmony_ci
32562306a36Sopenharmony_ci/* update AT_VECTOR_SIZE_ARCH if the number of NEW_AUX_ENT entries changes */
32662306a36Sopenharmony_ci
32762306a36Sopenharmony_ci#else /* CONFIG_X86_32 */
32862306a36Sopenharmony_ci
32962306a36Sopenharmony_ci/* 1GB for 64bit, 8MB for 32bit */
33062306a36Sopenharmony_ci#define __STACK_RND_MASK(is32bit) ((is32bit) ? 0x7ff : 0x3fffff)
33162306a36Sopenharmony_ci#define STACK_RND_MASK __STACK_RND_MASK(mmap_is_ia32())
33262306a36Sopenharmony_ci
33362306a36Sopenharmony_ci#define ARCH_DLINFO							\
33462306a36Sopenharmony_cido {									\
33562306a36Sopenharmony_ci	if (vdso64_enabled)						\
33662306a36Sopenharmony_ci		NEW_AUX_ENT(AT_SYSINFO_EHDR,				\
33762306a36Sopenharmony_ci			    (unsigned long __force)current->mm->context.vdso); \
33862306a36Sopenharmony_ci	NEW_AUX_ENT(AT_MINSIGSTKSZ, get_sigframe_size());		\
33962306a36Sopenharmony_ci} while (0)
34062306a36Sopenharmony_ci
34162306a36Sopenharmony_ci/* As a historical oddity, the x32 and x86_64 vDSOs are controlled together. */
34262306a36Sopenharmony_ci#define ARCH_DLINFO_X32							\
34362306a36Sopenharmony_cido {									\
34462306a36Sopenharmony_ci	if (vdso64_enabled)						\
34562306a36Sopenharmony_ci		NEW_AUX_ENT(AT_SYSINFO_EHDR,				\
34662306a36Sopenharmony_ci			    (unsigned long __force)current->mm->context.vdso); \
34762306a36Sopenharmony_ci	NEW_AUX_ENT(AT_MINSIGSTKSZ, get_sigframe_size());		\
34862306a36Sopenharmony_ci} while (0)
34962306a36Sopenharmony_ci
35062306a36Sopenharmony_ci#define AT_SYSINFO		32
35162306a36Sopenharmony_ci
35262306a36Sopenharmony_ci#define COMPAT_ARCH_DLINFO						\
35362306a36Sopenharmony_ciif (exec->e_machine == EM_X86_64)					\
35462306a36Sopenharmony_ci	ARCH_DLINFO_X32;						\
35562306a36Sopenharmony_cielse if (IS_ENABLED(CONFIG_IA32_EMULATION))				\
35662306a36Sopenharmony_ci	ARCH_DLINFO_IA32
35762306a36Sopenharmony_ci
35862306a36Sopenharmony_ci#define COMPAT_ELF_ET_DYN_BASE	(TASK_UNMAPPED_BASE + 0x1000000)
35962306a36Sopenharmony_ci
36062306a36Sopenharmony_ci#endif /* !CONFIG_X86_32 */
36162306a36Sopenharmony_ci
36262306a36Sopenharmony_ci#define VDSO_CURRENT_BASE	((unsigned long)current->mm->context.vdso)
36362306a36Sopenharmony_ci
36462306a36Sopenharmony_ci#define VDSO_ENTRY							\
36562306a36Sopenharmony_ci	((unsigned long)current->mm->context.vdso +			\
36662306a36Sopenharmony_ci	 vdso_image_32.sym___kernel_vsyscall)
36762306a36Sopenharmony_ci
36862306a36Sopenharmony_cistruct linux_binprm;
36962306a36Sopenharmony_ci
37062306a36Sopenharmony_ci#define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1
37162306a36Sopenharmony_ciextern int arch_setup_additional_pages(struct linux_binprm *bprm,
37262306a36Sopenharmony_ci				       int uses_interp);
37362306a36Sopenharmony_ciextern int compat_arch_setup_additional_pages(struct linux_binprm *bprm,
37462306a36Sopenharmony_ci					      int uses_interp, bool x32);
37562306a36Sopenharmony_ci#define COMPAT_ARCH_SETUP_ADDITIONAL_PAGES(bprm, ex, interpreter)	\
37662306a36Sopenharmony_ci	compat_arch_setup_additional_pages(bprm, interpreter,		\
37762306a36Sopenharmony_ci					   (ex->e_machine == EM_X86_64))
37862306a36Sopenharmony_ci
37962306a36Sopenharmony_ciextern bool arch_syscall_is_vdso_sigreturn(struct pt_regs *regs);
38062306a36Sopenharmony_ci
38162306a36Sopenharmony_ci/* Do not change the values. See get_align_mask() */
38262306a36Sopenharmony_cienum align_flags {
38362306a36Sopenharmony_ci	ALIGN_VA_32	= BIT(0),
38462306a36Sopenharmony_ci	ALIGN_VA_64	= BIT(1),
38562306a36Sopenharmony_ci};
38662306a36Sopenharmony_ci
38762306a36Sopenharmony_cistruct va_alignment {
38862306a36Sopenharmony_ci	int flags;
38962306a36Sopenharmony_ci	unsigned long mask;
39062306a36Sopenharmony_ci	unsigned long bits;
39162306a36Sopenharmony_ci} ____cacheline_aligned;
39262306a36Sopenharmony_ci
39362306a36Sopenharmony_ciextern struct va_alignment va_align;
39462306a36Sopenharmony_ciextern unsigned long align_vdso_addr(unsigned long);
39562306a36Sopenharmony_ci#endif /* _ASM_X86_ELF_H */
396