1/* SPDX-License-Identifier: GPL-2.0 */ 2/* 3 * This file is subject to the terms and conditions of the GNU General Public 4 * License. See the file "COPYING" in the main directory of this archive 5 * for more details. 6 * 7 * Much of this is taken from binutils and GNU libc ... 8 * Copyright (C) 2020 Loongson Technology Co., Ltd. 9 */ 10#ifndef _ASM_ELF_H 11#define _ASM_ELF_H 12 13#include <linux/auxvec.h> 14#include <linux/fs.h> 15#include <uapi/linux/elf.h> 16 17#include <asm/current.h> 18#include <asm/vdso.h> 19 20/* The ABI of a file. */ 21#define EF_LOONGARCH_ABI_LP64_SOFT_FLOAT 0x1 22#define EF_LOONGARCH_ABI_LP64_SINGLE_FLOAT 0x2 23#define EF_LOONGARCH_ABI_LP64_DOUBLE_FLOAT 0x3 24 25#define EF_LOONGARCH_ABI_ILP32_SOFT_FLOAT 0x5 26#define EF_LOONGARCH_ABI_ILP32_SINGLE_FLOAT 0x6 27#define EF_LOONGARCH_ABI_ILP32_DOUBLE_FLOAT 0x7 28 29/* LoongArch relocation types used by the dynamic linker */ 30#define R_LARCH_NONE 0 31#define R_LARCH_32 1 32#define R_LARCH_64 2 33#define R_LARCH_RELATIVE 3 34#define R_LARCH_COPY 4 35#define R_LARCH_JUMP_SLOT 5 36#define R_LARCH_TLS_DTPMOD32 6 37#define R_LARCH_TLS_DTPMOD64 7 38#define R_LARCH_TLS_DTPREL32 8 39#define R_LARCH_TLS_DTPREL64 9 40#define R_LARCH_TLS_TPREL32 10 41#define R_LARCH_TLS_TPREL64 11 42#define R_LARCH_IRELATIVE 12 43#define R_LARCH_MARK_LA 20 44#define R_LARCH_MARK_PCREL 21 45#define R_LARCH_SOP_PUSH_PCREL 22 46#define R_LARCH_SOP_PUSH_ABSOLUTE 23 47#define R_LARCH_SOP_PUSH_DUP 24 48#define R_LARCH_SOP_PUSH_GPREL 25 49#define R_LARCH_SOP_PUSH_TLS_TPREL 26 50#define R_LARCH_SOP_PUSH_TLS_GOT 27 51#define R_LARCH_SOP_PUSH_TLS_GD 28 52#define R_LARCH_SOP_PUSH_PLT_PCREL 29 53#define R_LARCH_SOP_ASSERT 30 54#define R_LARCH_SOP_NOT 31 55#define R_LARCH_SOP_SUB 32 56#define R_LARCH_SOP_SL 33 57#define R_LARCH_SOP_SR 34 58#define R_LARCH_SOP_ADD 35 59#define R_LARCH_SOP_AND 36 60#define R_LARCH_SOP_IF_ELSE 37 61#define R_LARCH_SOP_POP_32_S_10_5 38 62#define R_LARCH_SOP_POP_32_U_10_12 39 63#define R_LARCH_SOP_POP_32_S_10_12 40 64#define R_LARCH_SOP_POP_32_S_10_16 41 65#define R_LARCH_SOP_POP_32_S_10_16_S2 42 66#define R_LARCH_SOP_POP_32_S_5_20 43 67#define R_LARCH_SOP_POP_32_S_0_5_10_16_S2 44 68#define R_LARCH_SOP_POP_32_S_0_10_10_16_S2 45 69#define R_LARCH_SOP_POP_32_U 46 70#define R_LARCH_ADD8 47 71#define R_LARCH_ADD16 48 72#define R_LARCH_ADD24 49 73#define R_LARCH_ADD32 50 74#define R_LARCH_ADD64 51 75#define R_LARCH_SUB8 52 76#define R_LARCH_SUB16 53 77#define R_LARCH_SUB24 54 78#define R_LARCH_SUB32 55 79#define R_LARCH_SUB64 56 80#define R_LARCH_GNU_VTINHERIT 57 81#define R_LARCH_GNU_VTENTRY 58 82#define R_LARCH_B16 64 83#define R_LARCH_B21 65 84#define R_LARCH_B26 66 85#define R_LARCH_ABS_HI20 67 86#define R_LARCH_ABS_LO12 68 87#define R_LARCH_ABS64_LO20 69 88#define R_LARCH_ABS64_HI12 70 89#define R_LARCH_PCALA_HI20 71 90#define R_LARCH_PCALA_LO12 72 91#define R_LARCH_PCALA64_LO20 73 92#define R_LARCH_PCALA64_HI12 74 93#define R_LARCH_GOT_PC_HI20 75 94#define R_LARCH_GOT_PC_LO12 76 95#define R_LARCH_GOT64_PC_LO20 77 96#define R_LARCH_GOT64_PC_HI12 78 97#define R_LARCH_GOT_HI20 79 98#define R_LARCH_GOT_LO12 80 99#define R_LARCH_GOT64_LO20 81 100#define R_LARCH_GOT64_HI12 82 101#define R_LARCH_TLS_LE_HI20 83 102#define R_LARCH_TLS_LE_LO12 84 103#define R_LARCH_TLS_LE64_LO20 85 104#define R_LARCH_TLS_LE64_HI12 86 105#define R_LARCH_TLS_IE_PC_HI20 87 106#define R_LARCH_TLS_IE_PC_LO12 88 107#define R_LARCH_TLS_IE64_PC_LO20 89 108#define R_LARCH_TLS_IE64_PC_HI12 90 109#define R_LARCH_TLS_IE_HI20 91 110#define R_LARCH_TLS_IE_LO12 92 111#define R_LARCH_TLS_IE64_LO20 93 112#define R_LARCH_TLS_IE64_HI12 94 113#define R_LARCH_TLS_LD_PC_HI20 95 114#define R_LARCH_TLS_LD_HI20 96 115#define R_LARCH_TLS_GD_PC_HI20 97 116#define R_LARCH_TLS_GD_HI20 98 117#define R_LARCH_32_PCREL 99 118#define R_LARCH_RELAX 100 119#define R_LARCH_DELETE 101 120#define R_LARCH_ALIGN 102 121#define R_LARCH_PCREL20_S2 103 122#define R_LARCH_CFA 104 123#define R_LARCH_ADD6 105 124#define R_LARCH_SUB6 106 125#define R_LARCH_ADD_ULEB128 107 126#define R_LARCH_SUB_ULEB128 108 127#define R_LARCH_64_PCREL 109 128 129#ifndef ELF_ARCH 130 131/* ELF register definitions */ 132 133/* 134 * General purpose have the following registers: 135 * Register Number 136 * GPRs 32 137 * ORIG_A0 1 138 * ERA 1 139 * BADVADDR 1 140 * CRMD 1 141 * PRMD 1 142 * EUEN 1 143 * ECFG 1 144 * ESTAT 1 145 * Reserved 5 146 */ 147#define ELF_NGREG 45 148 149/* 150 * Floating point have the following registers: 151 * Register Number 152 * FPR 32 153 * FCC 1 154 * FCSR 1 155 */ 156#define ELF_NFPREG 34 157 158typedef unsigned long elf_greg_t; 159typedef elf_greg_t elf_gregset_t[ELF_NGREG]; 160 161typedef double elf_fpreg_t; 162typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG]; 163 164void loongarch_dump_regs64(u64 *uregs, const struct pt_regs *regs); 165 166#ifdef CONFIG_32BIT 167/* 168 * This is used to ensure we don't load something for the wrong architecture. 169 */ 170#define elf_check_arch elf32_check_arch 171 172/* 173 * These are used to set parameters in the core dumps. 174 */ 175#define ELF_CLASS ELFCLASS32 176 177#define ELF_CORE_COPY_REGS(dest, regs) \ 178 loongarch_dump_regs32((u32 *)&(dest), (regs)); 179 180#endif /* CONFIG_32BIT */ 181 182#ifdef CONFIG_64BIT 183/* 184 * This is used to ensure we don't load something for the wrong architecture. 185 */ 186#define elf_check_arch elf64_check_arch 187 188/* 189 * These are used to set parameters in the core dumps. 190 */ 191#define ELF_CLASS ELFCLASS64 192 193#define ELF_CORE_COPY_REGS(dest, regs) \ 194 loongarch_dump_regs64((u64 *)&(dest), (regs)); 195 196#endif /* CONFIG_64BIT */ 197 198/* 199 * These are used to set parameters in the core dumps. 200 */ 201#define ELF_DATA ELFDATA2LSB 202#define ELF_ARCH EM_LOONGARCH 203 204#endif /* !defined(ELF_ARCH) */ 205 206#define loongarch_elf_check_machine(x) ((x)->e_machine == EM_LOONGARCH) 207 208#define vmcore_elf32_check_arch loongarch_elf_check_machine 209#define vmcore_elf64_check_arch loongarch_elf_check_machine 210 211/* 212 * Return non-zero if HDR identifies an 32bit ELF binary. 213 */ 214#define elf32_check_arch(hdr) \ 215({ \ 216 int __res = 1; \ 217 struct elfhdr *__h = (hdr); \ 218 \ 219 if (!loongarch_elf_check_machine(__h)) \ 220 __res = 0; \ 221 if (__h->e_ident[EI_CLASS] != ELFCLASS32) \ 222 __res = 0; \ 223 \ 224 __res; \ 225}) 226 227/* 228 * Return non-zero if HDR identifies an 64bit ELF binary. 229 */ 230#define elf64_check_arch(hdr) \ 231({ \ 232 int __res = 1; \ 233 struct elfhdr *__h = (hdr); \ 234 \ 235 if (!loongarch_elf_check_machine(__h)) \ 236 __res = 0; \ 237 if (__h->e_ident[EI_CLASS] != ELFCLASS64) \ 238 __res = 0; \ 239 \ 240 __res; \ 241}) 242 243#ifdef CONFIG_32BIT 244 245#define SET_PERSONALITY2(ex, state) \ 246do { \ 247 current->thread.vdso = &vdso_info; \ 248 \ 249 if (personality(current->personality) != PER_LINUX) \ 250 set_personality(PER_LINUX); \ 251} while (0) 252 253#endif /* CONFIG_32BIT */ 254 255#ifdef CONFIG_64BIT 256 257#define SET_PERSONALITY2(ex, state) \ 258do { \ 259 unsigned int p; \ 260 \ 261 clear_thread_flag(TIF_32BIT_REGS); \ 262 clear_thread_flag(TIF_32BIT_ADDR); \ 263 \ 264 current->thread.vdso = &vdso_info; \ 265 \ 266 p = personality(current->personality); \ 267 if (p != PER_LINUX32 && p != PER_LINUX) \ 268 set_personality(PER_LINUX); \ 269} while (0) 270 271#endif /* CONFIG_64BIT */ 272 273#define CORE_DUMP_USE_REGSET 274#define ELF_EXEC_PAGESIZE PAGE_SIZE 275 276/* This yields a mask that user programs can use to figure out what 277 instruction set this cpu supports. This could be done in userspace, 278 but it's not easy, and we've already done it here. */ 279 280#define ELF_HWCAP (elf_hwcap) 281extern unsigned int elf_hwcap; 282#include <asm/hwcap.h> 283 284/* 285 * This yields a string that ld.so will use to load implementation 286 * specific libraries for optimization. This is more specific in 287 * intent than poking at uname or /proc/cpuinfo. 288 */ 289 290#define ELF_PLATFORM __elf_platform 291extern const char *__elf_platform; 292 293#define ELF_PLAT_INIT(_r, load_addr) do { \ 294 _r->regs[1] = _r->regs[2] = _r->regs[3] = _r->regs[4] = 0; \ 295 _r->regs[5] = _r->regs[6] = _r->regs[7] = _r->regs[8] = 0; \ 296 _r->regs[9] = _r->regs[10] /* syscall n */ = _r->regs[12] = 0; \ 297 _r->regs[13] = _r->regs[14] = _r->regs[15] = _r->regs[16] = 0; \ 298 _r->regs[17] = _r->regs[18] = _r->regs[19] = _r->regs[20] = 0; \ 299 _r->regs[21] = _r->regs[22] = _r->regs[23] = _r->regs[24] = 0; \ 300 _r->regs[25] = _r->regs[26] = _r->regs[27] = _r->regs[28] = 0; \ 301 _r->regs[29] = _r->regs[30] = _r->regs[31] = 0; \ 302} while (0) 303 304/* This is the location that an ET_DYN program is loaded if exec'ed. Typical 305 use of this is to invoke "./ld.so someprog" to test out a new version of 306 the loader. We need to make sure that it is out of the way of the program 307 that it will "exec", and that there is sufficient room for the brk. */ 308 309#define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2) 310 311/* update AT_VECTOR_SIZE_ARCH if the number of NEW_AUX_ENT entries changes */ 312#define ARCH_DLINFO \ 313do { \ 314 NEW_AUX_ENT(AT_SYSINFO_EHDR, \ 315 (unsigned long)current->mm->context.vdso); \ 316} while (0) 317 318#define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1 319struct linux_binprm; 320extern int arch_setup_additional_pages(struct linux_binprm *bprm, 321 int uses_interp); 322 323struct arch_elf_state { 324 int fp_abi; 325 int interp_fp_abi; 326}; 327 328#define LOONGARCH_ABI_FP_ANY (0) 329 330#define INIT_ARCH_ELF_STATE { \ 331 .fp_abi = LOONGARCH_ABI_FP_ANY, \ 332 .interp_fp_abi = LOONGARCH_ABI_FP_ANY, \ 333} 334 335#define elf_read_implies_exec(ex, exec_stk) (exec_stk == EXSTACK_DEFAULT) 336 337extern int arch_elf_pt_proc(void *ehdr, void *phdr, struct file *elf, 338 bool is_interp, struct arch_elf_state *state); 339 340extern int arch_check_elf(void *ehdr, bool has_interpreter, void *interp_ehdr, 341 struct arch_elf_state *state); 342 343#endif /* _ASM_ELF_H */ 344