Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/arch/loongarch/include/asm/elf.h
50159 views
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
373