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