18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Copyright (C) 2012 ARM Ltd. 48c2ecf20Sopenharmony_ci */ 58c2ecf20Sopenharmony_ci#ifndef __ASM_ELF_H 68c2ecf20Sopenharmony_ci#define __ASM_ELF_H 78c2ecf20Sopenharmony_ci 88c2ecf20Sopenharmony_ci#include <asm/hwcap.h> 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_ci/* 118c2ecf20Sopenharmony_ci * ELF register definitions.. 128c2ecf20Sopenharmony_ci */ 138c2ecf20Sopenharmony_ci#include <asm/ptrace.h> 148c2ecf20Sopenharmony_ci#include <asm/user.h> 158c2ecf20Sopenharmony_ci 168c2ecf20Sopenharmony_ci/* 178c2ecf20Sopenharmony_ci * AArch64 static relocation types. 188c2ecf20Sopenharmony_ci */ 198c2ecf20Sopenharmony_ci 208c2ecf20Sopenharmony_ci/* Miscellaneous. */ 218c2ecf20Sopenharmony_ci#define R_ARM_NONE 0 228c2ecf20Sopenharmony_ci#define R_AARCH64_NONE 256 238c2ecf20Sopenharmony_ci 248c2ecf20Sopenharmony_ci/* Data. */ 258c2ecf20Sopenharmony_ci#define R_AARCH64_ABS64 257 268c2ecf20Sopenharmony_ci#define R_AARCH64_ABS32 258 278c2ecf20Sopenharmony_ci#define R_AARCH64_ABS16 259 288c2ecf20Sopenharmony_ci#define R_AARCH64_PREL64 260 298c2ecf20Sopenharmony_ci#define R_AARCH64_PREL32 261 308c2ecf20Sopenharmony_ci#define R_AARCH64_PREL16 262 318c2ecf20Sopenharmony_ci 328c2ecf20Sopenharmony_ci/* Instructions. */ 338c2ecf20Sopenharmony_ci#define R_AARCH64_MOVW_UABS_G0 263 348c2ecf20Sopenharmony_ci#define R_AARCH64_MOVW_UABS_G0_NC 264 358c2ecf20Sopenharmony_ci#define R_AARCH64_MOVW_UABS_G1 265 368c2ecf20Sopenharmony_ci#define R_AARCH64_MOVW_UABS_G1_NC 266 378c2ecf20Sopenharmony_ci#define R_AARCH64_MOVW_UABS_G2 267 388c2ecf20Sopenharmony_ci#define R_AARCH64_MOVW_UABS_G2_NC 268 398c2ecf20Sopenharmony_ci#define R_AARCH64_MOVW_UABS_G3 269 408c2ecf20Sopenharmony_ci 418c2ecf20Sopenharmony_ci#define R_AARCH64_MOVW_SABS_G0 270 428c2ecf20Sopenharmony_ci#define R_AARCH64_MOVW_SABS_G1 271 438c2ecf20Sopenharmony_ci#define R_AARCH64_MOVW_SABS_G2 272 448c2ecf20Sopenharmony_ci 458c2ecf20Sopenharmony_ci#define R_AARCH64_LD_PREL_LO19 273 468c2ecf20Sopenharmony_ci#define R_AARCH64_ADR_PREL_LO21 274 478c2ecf20Sopenharmony_ci#define R_AARCH64_ADR_PREL_PG_HI21 275 488c2ecf20Sopenharmony_ci#define R_AARCH64_ADR_PREL_PG_HI21_NC 276 498c2ecf20Sopenharmony_ci#define R_AARCH64_ADD_ABS_LO12_NC 277 508c2ecf20Sopenharmony_ci#define R_AARCH64_LDST8_ABS_LO12_NC 278 518c2ecf20Sopenharmony_ci 528c2ecf20Sopenharmony_ci#define R_AARCH64_TSTBR14 279 538c2ecf20Sopenharmony_ci#define R_AARCH64_CONDBR19 280 548c2ecf20Sopenharmony_ci#define R_AARCH64_JUMP26 282 558c2ecf20Sopenharmony_ci#define R_AARCH64_CALL26 283 568c2ecf20Sopenharmony_ci#define R_AARCH64_LDST16_ABS_LO12_NC 284 578c2ecf20Sopenharmony_ci#define R_AARCH64_LDST32_ABS_LO12_NC 285 588c2ecf20Sopenharmony_ci#define R_AARCH64_LDST64_ABS_LO12_NC 286 598c2ecf20Sopenharmony_ci#define R_AARCH64_LDST128_ABS_LO12_NC 299 608c2ecf20Sopenharmony_ci 618c2ecf20Sopenharmony_ci#define R_AARCH64_MOVW_PREL_G0 287 628c2ecf20Sopenharmony_ci#define R_AARCH64_MOVW_PREL_G0_NC 288 638c2ecf20Sopenharmony_ci#define R_AARCH64_MOVW_PREL_G1 289 648c2ecf20Sopenharmony_ci#define R_AARCH64_MOVW_PREL_G1_NC 290 658c2ecf20Sopenharmony_ci#define R_AARCH64_MOVW_PREL_G2 291 668c2ecf20Sopenharmony_ci#define R_AARCH64_MOVW_PREL_G2_NC 292 678c2ecf20Sopenharmony_ci#define R_AARCH64_MOVW_PREL_G3 293 688c2ecf20Sopenharmony_ci 698c2ecf20Sopenharmony_ci#define R_AARCH64_RELATIVE 1027 708c2ecf20Sopenharmony_ci 718c2ecf20Sopenharmony_ci/* 728c2ecf20Sopenharmony_ci * These are used to set parameters in the core dumps. 738c2ecf20Sopenharmony_ci */ 748c2ecf20Sopenharmony_ci#define ELF_CLASS ELFCLASS64 758c2ecf20Sopenharmony_ci#ifdef __AARCH64EB__ 768c2ecf20Sopenharmony_ci#define ELF_DATA ELFDATA2MSB 778c2ecf20Sopenharmony_ci#else 788c2ecf20Sopenharmony_ci#define ELF_DATA ELFDATA2LSB 798c2ecf20Sopenharmony_ci#endif 808c2ecf20Sopenharmony_ci#define ELF_ARCH EM_AARCH64 818c2ecf20Sopenharmony_ci 828c2ecf20Sopenharmony_ci/* 838c2ecf20Sopenharmony_ci * This yields a string that ld.so will use to load implementation 848c2ecf20Sopenharmony_ci * specific libraries for optimization. This is more specific in 858c2ecf20Sopenharmony_ci * intent than poking at uname or /proc/cpuinfo. 868c2ecf20Sopenharmony_ci */ 878c2ecf20Sopenharmony_ci#define ELF_PLATFORM_SIZE 16 888c2ecf20Sopenharmony_ci#ifdef __AARCH64EB__ 898c2ecf20Sopenharmony_ci#define ELF_PLATFORM ("aarch64_be") 908c2ecf20Sopenharmony_ci#else 918c2ecf20Sopenharmony_ci#define ELF_PLATFORM ("aarch64") 928c2ecf20Sopenharmony_ci#endif 938c2ecf20Sopenharmony_ci 948c2ecf20Sopenharmony_ci/* 958c2ecf20Sopenharmony_ci * This is used to ensure we don't load something for the wrong architecture. 968c2ecf20Sopenharmony_ci */ 978c2ecf20Sopenharmony_ci#define elf_check_arch(x) ((x)->e_machine == EM_AARCH64) 988c2ecf20Sopenharmony_ci 998c2ecf20Sopenharmony_ci/* 1008c2ecf20Sopenharmony_ci * An executable for which elf_read_implies_exec() returns TRUE will 1018c2ecf20Sopenharmony_ci * have the READ_IMPLIES_EXEC personality flag set automatically. 1028c2ecf20Sopenharmony_ci * 1038c2ecf20Sopenharmony_ci * The decision process for determining the results are: 1048c2ecf20Sopenharmony_ci * 1058c2ecf20Sopenharmony_ci * CPU*: | arm32 | arm64 | 1068c2ecf20Sopenharmony_ci * ELF: | | | 1078c2ecf20Sopenharmony_ci * ---------------------|------------|------------| 1088c2ecf20Sopenharmony_ci * missing PT_GNU_STACK | exec-all | exec-none | 1098c2ecf20Sopenharmony_ci * PT_GNU_STACK == RWX | exec-stack | exec-stack | 1108c2ecf20Sopenharmony_ci * PT_GNU_STACK == RW | exec-none | exec-none | 1118c2ecf20Sopenharmony_ci * 1128c2ecf20Sopenharmony_ci * exec-all : all PROT_READ user mappings are executable, except when 1138c2ecf20Sopenharmony_ci * backed by files on a noexec-filesystem. 1148c2ecf20Sopenharmony_ci * exec-none : only PROT_EXEC user mappings are executable. 1158c2ecf20Sopenharmony_ci * exec-stack: only the stack and PROT_EXEC user mappings are executable. 1168c2ecf20Sopenharmony_ci * 1178c2ecf20Sopenharmony_ci * *all arm64 CPUs support NX, so there is no "lacks NX" column. 1188c2ecf20Sopenharmony_ci * 1198c2ecf20Sopenharmony_ci */ 1208c2ecf20Sopenharmony_ci#define compat_elf_read_implies_exec(ex, stk) (stk == EXSTACK_DEFAULT) 1218c2ecf20Sopenharmony_ci 1228c2ecf20Sopenharmony_ci#define CORE_DUMP_USE_REGSET 1238c2ecf20Sopenharmony_ci#define ELF_EXEC_PAGESIZE PAGE_SIZE 1248c2ecf20Sopenharmony_ci 1258c2ecf20Sopenharmony_ci/* 1268c2ecf20Sopenharmony_ci * This is the base location for PIE (ET_DYN with INTERP) loads. On 1278c2ecf20Sopenharmony_ci * 64-bit, this is above 4GB to leave the entire 32-bit address 1288c2ecf20Sopenharmony_ci * space open for things that want to use the area for 32-bit pointers. 1298c2ecf20Sopenharmony_ci */ 1308c2ecf20Sopenharmony_ci#ifdef CONFIG_ARM64_FORCE_52BIT 1318c2ecf20Sopenharmony_ci#define ELF_ET_DYN_BASE (2 * TASK_SIZE_64 / 3) 1328c2ecf20Sopenharmony_ci#else 1338c2ecf20Sopenharmony_ci#define ELF_ET_DYN_BASE (2 * DEFAULT_MAP_WINDOW_64 / 3) 1348c2ecf20Sopenharmony_ci#endif /* CONFIG_ARM64_FORCE_52BIT */ 1358c2ecf20Sopenharmony_ci 1368c2ecf20Sopenharmony_ci#ifndef __ASSEMBLY__ 1378c2ecf20Sopenharmony_ci 1388c2ecf20Sopenharmony_ci#include <uapi/linux/elf.h> 1398c2ecf20Sopenharmony_ci#include <linux/bug.h> 1408c2ecf20Sopenharmony_ci#include <linux/errno.h> 1418c2ecf20Sopenharmony_ci#include <linux/fs.h> 1428c2ecf20Sopenharmony_ci#include <linux/types.h> 1438c2ecf20Sopenharmony_ci#include <asm/processor.h> /* for signal_minsigstksz, used by ARCH_DLINFO */ 1448c2ecf20Sopenharmony_ci 1458c2ecf20Sopenharmony_citypedef unsigned long elf_greg_t; 1468c2ecf20Sopenharmony_ci 1478c2ecf20Sopenharmony_ci#define ELF_NGREG (sizeof(struct user_pt_regs) / sizeof(elf_greg_t)) 1488c2ecf20Sopenharmony_ci#define ELF_CORE_COPY_REGS(dest, regs) \ 1498c2ecf20Sopenharmony_ci *(struct user_pt_regs *)&(dest) = (regs)->user_regs; 1508c2ecf20Sopenharmony_ci 1518c2ecf20Sopenharmony_citypedef elf_greg_t elf_gregset_t[ELF_NGREG]; 1528c2ecf20Sopenharmony_citypedef struct user_fpsimd_state elf_fpregset_t; 1538c2ecf20Sopenharmony_ci 1548c2ecf20Sopenharmony_ci/* 1558c2ecf20Sopenharmony_ci * When the program starts, a1 contains a pointer to a function to be 1568c2ecf20Sopenharmony_ci * registered with atexit, as per the SVR4 ABI. A value of 0 means we have no 1578c2ecf20Sopenharmony_ci * such handler. 1588c2ecf20Sopenharmony_ci */ 1598c2ecf20Sopenharmony_ci#define ELF_PLAT_INIT(_r, load_addr) (_r)->regs[0] = 0 1608c2ecf20Sopenharmony_ci 1618c2ecf20Sopenharmony_ci#define SET_PERSONALITY(ex) \ 1628c2ecf20Sopenharmony_ci({ \ 1638c2ecf20Sopenharmony_ci clear_thread_flag(TIF_32BIT); \ 1648c2ecf20Sopenharmony_ci current->personality &= ~READ_IMPLIES_EXEC; \ 1658c2ecf20Sopenharmony_ci}) 1668c2ecf20Sopenharmony_ci 1678c2ecf20Sopenharmony_ci/* update AT_VECTOR_SIZE_ARCH if the number of NEW_AUX_ENT entries changes */ 1688c2ecf20Sopenharmony_ci#define ARCH_DLINFO \ 1698c2ecf20Sopenharmony_cido { \ 1708c2ecf20Sopenharmony_ci NEW_AUX_ENT(AT_SYSINFO_EHDR, \ 1718c2ecf20Sopenharmony_ci (elf_addr_t)current->mm->context.vdso); \ 1728c2ecf20Sopenharmony_ci \ 1738c2ecf20Sopenharmony_ci /* \ 1748c2ecf20Sopenharmony_ci * Should always be nonzero unless there's a kernel bug. \ 1758c2ecf20Sopenharmony_ci * If we haven't determined a sensible value to give to \ 1768c2ecf20Sopenharmony_ci * userspace, omit the entry: \ 1778c2ecf20Sopenharmony_ci */ \ 1788c2ecf20Sopenharmony_ci if (likely(signal_minsigstksz)) \ 1798c2ecf20Sopenharmony_ci NEW_AUX_ENT(AT_MINSIGSTKSZ, signal_minsigstksz); \ 1808c2ecf20Sopenharmony_ci else \ 1818c2ecf20Sopenharmony_ci NEW_AUX_ENT(AT_IGNORE, 0); \ 1828c2ecf20Sopenharmony_ci} while (0) 1838c2ecf20Sopenharmony_ci 1848c2ecf20Sopenharmony_ci#define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1858c2ecf20Sopenharmony_cistruct linux_binprm; 1868c2ecf20Sopenharmony_ciextern int arch_setup_additional_pages(struct linux_binprm *bprm, 1878c2ecf20Sopenharmony_ci int uses_interp); 1888c2ecf20Sopenharmony_ci 1898c2ecf20Sopenharmony_ci/* 1GB of VA */ 1908c2ecf20Sopenharmony_ci#ifdef CONFIG_COMPAT 1918c2ecf20Sopenharmony_ci#define STACK_RND_MASK (test_thread_flag(TIF_32BIT) ? \ 1928c2ecf20Sopenharmony_ci 0x7ff >> (PAGE_SHIFT - 12) : \ 1938c2ecf20Sopenharmony_ci 0x3ffff >> (PAGE_SHIFT - 12)) 1948c2ecf20Sopenharmony_ci#else 1958c2ecf20Sopenharmony_ci#define STACK_RND_MASK (0x3ffff >> (PAGE_SHIFT - 12)) 1968c2ecf20Sopenharmony_ci#endif 1978c2ecf20Sopenharmony_ci 1988c2ecf20Sopenharmony_ci#ifdef __AARCH64EB__ 1998c2ecf20Sopenharmony_ci#define COMPAT_ELF_PLATFORM ("v8b") 2008c2ecf20Sopenharmony_ci#else 2018c2ecf20Sopenharmony_ci#define COMPAT_ELF_PLATFORM ("v8l") 2028c2ecf20Sopenharmony_ci#endif 2038c2ecf20Sopenharmony_ci 2048c2ecf20Sopenharmony_ci#ifdef CONFIG_COMPAT 2058c2ecf20Sopenharmony_ci 2068c2ecf20Sopenharmony_ci/* PIE load location for compat arm. Must match ARM ELF_ET_DYN_BASE. */ 2078c2ecf20Sopenharmony_ci#define COMPAT_ELF_ET_DYN_BASE 0x000400000UL 2088c2ecf20Sopenharmony_ci 2098c2ecf20Sopenharmony_ci/* AArch32 registers. */ 2108c2ecf20Sopenharmony_ci#define COMPAT_ELF_NGREG 18 2118c2ecf20Sopenharmony_citypedef unsigned int compat_elf_greg_t; 2128c2ecf20Sopenharmony_citypedef compat_elf_greg_t compat_elf_gregset_t[COMPAT_ELF_NGREG]; 2138c2ecf20Sopenharmony_ci 2148c2ecf20Sopenharmony_ci/* AArch32 EABI. */ 2158c2ecf20Sopenharmony_ci#define EF_ARM_EABI_MASK 0xff000000 2168c2ecf20Sopenharmony_ci#define compat_elf_check_arch(x) (system_supports_32bit_el0() && \ 2178c2ecf20Sopenharmony_ci ((x)->e_machine == EM_ARM) && \ 2188c2ecf20Sopenharmony_ci ((x)->e_flags & EF_ARM_EABI_MASK)) 2198c2ecf20Sopenharmony_ci 2208c2ecf20Sopenharmony_ci#define compat_start_thread compat_start_thread 2218c2ecf20Sopenharmony_ci/* 2228c2ecf20Sopenharmony_ci * Unlike the native SET_PERSONALITY macro, the compat version maintains 2238c2ecf20Sopenharmony_ci * READ_IMPLIES_EXEC across an execve() since this is the behaviour on 2248c2ecf20Sopenharmony_ci * arch/arm/. 2258c2ecf20Sopenharmony_ci */ 2268c2ecf20Sopenharmony_ci#define COMPAT_SET_PERSONALITY(ex) \ 2278c2ecf20Sopenharmony_ci({ \ 2288c2ecf20Sopenharmony_ci set_thread_flag(TIF_32BIT); \ 2298c2ecf20Sopenharmony_ci }) 2308c2ecf20Sopenharmony_ci#ifdef CONFIG_COMPAT_VDSO 2318c2ecf20Sopenharmony_ci#define COMPAT_ARCH_DLINFO \ 2328c2ecf20Sopenharmony_cido { \ 2338c2ecf20Sopenharmony_ci /* \ 2348c2ecf20Sopenharmony_ci * Note that we use Elf64_Off instead of elf_addr_t because \ 2358c2ecf20Sopenharmony_ci * elf_addr_t in compat is defined as Elf32_Addr and casting \ 2368c2ecf20Sopenharmony_ci * current->mm->context.vdso to it triggers a cast warning of \ 2378c2ecf20Sopenharmony_ci * cast from pointer to integer of different size. \ 2388c2ecf20Sopenharmony_ci */ \ 2398c2ecf20Sopenharmony_ci NEW_AUX_ENT(AT_SYSINFO_EHDR, \ 2408c2ecf20Sopenharmony_ci (Elf64_Off)current->mm->context.vdso); \ 2418c2ecf20Sopenharmony_ci} while (0) 2428c2ecf20Sopenharmony_ci#else 2438c2ecf20Sopenharmony_ci#define COMPAT_ARCH_DLINFO 2448c2ecf20Sopenharmony_ci#endif 2458c2ecf20Sopenharmony_ciextern int aarch32_setup_additional_pages(struct linux_binprm *bprm, 2468c2ecf20Sopenharmony_ci int uses_interp); 2478c2ecf20Sopenharmony_ci#define compat_arch_setup_additional_pages \ 2488c2ecf20Sopenharmony_ci aarch32_setup_additional_pages 2498c2ecf20Sopenharmony_ci 2508c2ecf20Sopenharmony_ci#endif /* CONFIG_COMPAT */ 2518c2ecf20Sopenharmony_ci 2528c2ecf20Sopenharmony_cistruct arch_elf_state { 2538c2ecf20Sopenharmony_ci int flags; 2548c2ecf20Sopenharmony_ci}; 2558c2ecf20Sopenharmony_ci 2568c2ecf20Sopenharmony_ci#define ARM64_ELF_BTI (1 << 0) 2578c2ecf20Sopenharmony_ci 2588c2ecf20Sopenharmony_ci#define INIT_ARCH_ELF_STATE { \ 2598c2ecf20Sopenharmony_ci .flags = 0, \ 2608c2ecf20Sopenharmony_ci} 2618c2ecf20Sopenharmony_ci 2628c2ecf20Sopenharmony_cistatic inline int arch_parse_elf_property(u32 type, const void *data, 2638c2ecf20Sopenharmony_ci size_t datasz, bool compat, 2648c2ecf20Sopenharmony_ci struct arch_elf_state *arch) 2658c2ecf20Sopenharmony_ci{ 2668c2ecf20Sopenharmony_ci /* No known properties for AArch32 yet */ 2678c2ecf20Sopenharmony_ci if (IS_ENABLED(CONFIG_COMPAT) && compat) 2688c2ecf20Sopenharmony_ci return 0; 2698c2ecf20Sopenharmony_ci 2708c2ecf20Sopenharmony_ci if (type == GNU_PROPERTY_AARCH64_FEATURE_1_AND) { 2718c2ecf20Sopenharmony_ci const u32 *p = data; 2728c2ecf20Sopenharmony_ci 2738c2ecf20Sopenharmony_ci if (datasz != sizeof(*p)) 2748c2ecf20Sopenharmony_ci return -ENOEXEC; 2758c2ecf20Sopenharmony_ci 2768c2ecf20Sopenharmony_ci if (system_supports_bti() && 2778c2ecf20Sopenharmony_ci (*p & GNU_PROPERTY_AARCH64_FEATURE_1_BTI)) 2788c2ecf20Sopenharmony_ci arch->flags |= ARM64_ELF_BTI; 2798c2ecf20Sopenharmony_ci } 2808c2ecf20Sopenharmony_ci 2818c2ecf20Sopenharmony_ci return 0; 2828c2ecf20Sopenharmony_ci} 2838c2ecf20Sopenharmony_ci 2848c2ecf20Sopenharmony_cistatic inline int arch_elf_pt_proc(void *ehdr, void *phdr, 2858c2ecf20Sopenharmony_ci struct file *f, bool is_interp, 2868c2ecf20Sopenharmony_ci struct arch_elf_state *state) 2878c2ecf20Sopenharmony_ci{ 2888c2ecf20Sopenharmony_ci return 0; 2898c2ecf20Sopenharmony_ci} 2908c2ecf20Sopenharmony_ci 2918c2ecf20Sopenharmony_cistatic inline int arch_check_elf(void *ehdr, bool has_interp, 2928c2ecf20Sopenharmony_ci void *interp_ehdr, 2938c2ecf20Sopenharmony_ci struct arch_elf_state *state) 2948c2ecf20Sopenharmony_ci{ 2958c2ecf20Sopenharmony_ci return 0; 2968c2ecf20Sopenharmony_ci} 2978c2ecf20Sopenharmony_ci 2988c2ecf20Sopenharmony_ci#endif /* !__ASSEMBLY__ */ 2998c2ecf20Sopenharmony_ci 3008c2ecf20Sopenharmony_ci#endif 301