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(¤t->thread, _r, 0) 17062306a36Sopenharmony_ci 17162306a36Sopenharmony_ci#define COMPAT_ELF_PLAT_INIT(regs, load_addr) \ 17262306a36Sopenharmony_ci elf_common_init(¤t->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