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