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 #define R_LARCH_CALL36 110 124 #define R_LARCH_TLS_DESC_PC_HI20 111 125 #define R_LARCH_TLS_DESC_PC_LO12 112 126 #define R_LARCH_TLS_DESC64_PC_LO20 113 127 #define R_LARCH_TLS_DESC64_PC_HI12 114 128 #define R_LARCH_TLS_DESC_HI20 115 129 #define R_LARCH_TLS_DESC_LO12 116 130 #define R_LARCH_TLS_DESC64_LO20 117 131 #define R_LARCH_TLS_DESC64_HI12 118 132 #define R_LARCH_TLS_DESC_LD 119 133 #define R_LARCH_TLS_DESC_CALL 120 134 #define R_LARCH_TLS_LE_HI20_R 121 135 #define R_LARCH_TLS_LE_ADD_R 122 136 #define R_LARCH_TLS_LE_LO12_R 123 137 #define R_LARCH_TLS_LD_PCREL20_S2 124 138 #define R_LARCH_TLS_GD_PCREL20_S2 125 139 #define R_LARCH_TLS_DESC_PCREL20_S2 126 140 #define R_LARCH_CALL30 127 141 #define R_LARCH_PCADD_HI20 128 142 #define R_LARCH_PCADD_LO12 129 143 #define R_LARCH_GOT_PCADD_HI20 130 144 #define R_LARCH_GOT_PCADD_LO12 131 145 #define R_LARCH_TLS_IE_PCADD_HI20 132 146 #define R_LARCH_TLS_IE_PCADD_LO12 133 147 #define R_LARCH_TLS_LD_PCADD_HI20 134 148 #define R_LARCH_TLS_LD_PCADD_LO12 135 149 #define R_LARCH_TLS_GD_PCADD_HI20 136 150 #define R_LARCH_TLS_GD_PCADD_LO12 137 151 #define R_LARCH_TLS_DESC_PCADD_HI20 138 152 #define R_LARCH_TLS_DESC_PCADD_LO12 139 153 154 #ifndef ELF_ARCH 155 156 /* ELF register definitions */ 157 158 /* 159 * General purpose have the following registers: 160 * Register Number 161 * GPRs 32 162 * ORIG_A0 1 163 * ERA 1 164 * BADVADDR 1 165 * CRMD 1 166 * PRMD 1 167 * EUEN 1 168 * ECFG 1 169 * ESTAT 1 170 * Reserved 5 171 */ 172 #define ELF_NGREG 45 173 174 /* 175 * Floating point have the following registers: 176 * Register Number 177 * FPR 32 178 * FCC 1 179 * FCSR 1 180 */ 181 #define ELF_NFPREG 34 182 183 typedef unsigned long elf_greg_t; 184 typedef elf_greg_t elf_gregset_t[ELF_NGREG]; 185 186 typedef double elf_fpreg_t; 187 typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG]; 188 189 void loongarch_dump_regs32(u32 *uregs, const struct pt_regs *regs); 190 void loongarch_dump_regs64(u64 *uregs, const struct pt_regs *regs); 191 192 #ifdef CONFIG_32BIT 193 /* 194 * This is used to ensure we don't load something for the wrong architecture. 195 */ 196 #define elf_check_arch elf32_check_arch 197 198 /* 199 * These are used to set parameters in the core dumps. 200 */ 201 #define ELF_CLASS ELFCLASS32 202 203 #define ELF_CORE_COPY_REGS(dest, regs) \ 204 loongarch_dump_regs32((u32 *)&(dest), (regs)); 205 206 #endif /* CONFIG_32BIT */ 207 208 #ifdef CONFIG_64BIT 209 /* 210 * This is used to ensure we don't load something for the wrong architecture. 211 */ 212 #define elf_check_arch elf64_check_arch 213 214 /* 215 * These are used to set parameters in the core dumps. 216 */ 217 #define ELF_CLASS ELFCLASS64 218 219 #define ELF_CORE_COPY_REGS(dest, regs) \ 220 loongarch_dump_regs64((u64 *)&(dest), (regs)); 221 222 #endif /* CONFIG_64BIT */ 223 224 /* 225 * These are used to set parameters in the core dumps. 226 */ 227 #define ELF_DATA ELFDATA2LSB 228 #define ELF_ARCH EM_LOONGARCH 229 230 #endif /* !defined(ELF_ARCH) */ 231 232 #define loongarch_elf_check_machine(x) ((x)->e_machine == EM_LOONGARCH) 233 234 #define vmcore_elf32_check_arch loongarch_elf_check_machine 235 #define vmcore_elf64_check_arch loongarch_elf_check_machine 236 237 /* 238 * Return non-zero if HDR identifies an 32bit ELF binary. 239 */ 240 #define elf32_check_arch(hdr) \ 241 ({ \ 242 int __res = 1; \ 243 struct elfhdr *__h = (hdr); \ 244 \ 245 if (!loongarch_elf_check_machine(__h)) \ 246 __res = 0; \ 247 if (__h->e_ident[EI_CLASS] != ELFCLASS32) \ 248 __res = 0; \ 249 \ 250 __res; \ 251 }) 252 253 /* 254 * Return non-zero if HDR identifies an 64bit ELF binary. 255 */ 256 #define elf64_check_arch(hdr) \ 257 ({ \ 258 int __res = 1; \ 259 struct elfhdr *__h = (hdr); \ 260 \ 261 if (!loongarch_elf_check_machine(__h)) \ 262 __res = 0; \ 263 if (__h->e_ident[EI_CLASS] != ELFCLASS64) \ 264 __res = 0; \ 265 \ 266 __res; \ 267 }) 268 269 #ifdef CONFIG_32BIT 270 271 #define SET_PERSONALITY2(ex, state) \ 272 do { \ 273 current->thread.vdso = &vdso_info; \ 274 \ 275 if (personality(current->personality) != PER_LINUX) \ 276 set_personality(PER_LINUX); \ 277 } while (0) 278 279 #endif /* CONFIG_32BIT */ 280 281 #ifdef CONFIG_64BIT 282 283 #define SET_PERSONALITY2(ex, state) \ 284 do { \ 285 unsigned int p; \ 286 \ 287 clear_thread_flag(TIF_32BIT_REGS); \ 288 clear_thread_flag(TIF_32BIT_ADDR); \ 289 \ 290 current->thread.vdso = &vdso_info; \ 291 \ 292 p = personality(current->personality); \ 293 if (p != PER_LINUX32 && p != PER_LINUX) \ 294 set_personality(PER_LINUX); \ 295 } while (0) 296 297 #endif /* CONFIG_64BIT */ 298 299 #define CORE_DUMP_USE_REGSET 300 #define ELF_EXEC_PAGESIZE PAGE_SIZE 301 302 /* 303 * This yields a mask that user programs can use to figure out what 304 * instruction set this cpu supports. This could be done in userspace, 305 * but it's not easy, and we've already done it here. 306 */ 307 308 #define ELF_HWCAP (elf_hwcap) 309 extern unsigned int elf_hwcap; 310 #include <asm/hwcap.h> 311 312 /* 313 * This yields a string that ld.so will use to load implementation 314 * specific libraries for optimization. This is more specific in 315 * intent than poking at uname or /proc/cpuinfo. 316 */ 317 318 #define ELF_PLATFORM __elf_platform 319 extern const char *__elf_platform; 320 321 #define ELF_PLAT_INIT(_r, load_addr) do { \ 322 _r->regs[1] = _r->regs[2] = _r->regs[3] = _r->regs[4] = 0; \ 323 _r->regs[5] = _r->regs[6] = _r->regs[7] = _r->regs[8] = 0; \ 324 _r->regs[9] = _r->regs[10] /* syscall n */ = _r->regs[12] = 0; \ 325 _r->regs[13] = _r->regs[14] = _r->regs[15] = _r->regs[16] = 0; \ 326 _r->regs[17] = _r->regs[18] = _r->regs[19] = _r->regs[20] = 0; \ 327 _r->regs[21] = _r->regs[22] = _r->regs[23] = _r->regs[24] = 0; \ 328 _r->regs[25] = _r->regs[26] = _r->regs[27] = _r->regs[28] = 0; \ 329 _r->regs[29] = _r->regs[30] = _r->regs[31] = 0; \ 330 } while (0) 331 332 /* 333 * This is the location that an ET_DYN program is loaded if exec'ed. Typical 334 * use of this is to invoke "./ld.so someprog" to test out a new version of 335 * the loader. We need to make sure that it is out of the way of the program 336 * that it will "exec", and that there is sufficient room for the brk. 337 */ 338 339 #define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2) 340 341 /* update AT_VECTOR_SIZE_ARCH if the number of NEW_AUX_ENT entries changes */ 342 #define ARCH_DLINFO \ 343 do { \ 344 NEW_AUX_ENT(AT_SYSINFO_EHDR, \ 345 (unsigned long)current->mm->context.vdso); \ 346 } while (0) 347 348 #define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1 349 struct linux_binprm; 350 extern int arch_setup_additional_pages(struct linux_binprm *bprm, 351 int uses_interp); 352 353 struct arch_elf_state { 354 int fp_abi; 355 int interp_fp_abi; 356 }; 357 358 #define LOONGARCH_ABI_FP_ANY (0) 359 360 #define INIT_ARCH_ELF_STATE { \ 361 .fp_abi = LOONGARCH_ABI_FP_ANY, \ 362 .interp_fp_abi = LOONGARCH_ABI_FP_ANY, \ 363 } 364 365 extern int arch_elf_pt_proc(void *ehdr, void *phdr, struct file *elf, 366 bool is_interp, struct arch_elf_state *state); 367 368 extern int arch_check_elf(void *ehdr, bool has_interpreter, void *interp_ehdr, 369 struct arch_elf_state *state); 370 371 #endif /* _ASM_ELF_H */ 372