1
2#ifndef _ASM_X86_ELF_H
3#define _ASM_X86_ELF_H
4
5
6
7
8#include <linux/thread_info.h>
9
10#include <asm/ptrace.h>
11#include <asm/user.h>
12#include <asm/auxvec.h>
13#include <asm/fsgsbase.h>
14
15typedef unsigned long elf_greg_t;
16
17#define ELF_NGREG (sizeof(struct user_regs_struct) / sizeof(elf_greg_t))
18typedef elf_greg_t elf_gregset_t[ELF_NGREG];
19
20typedef struct user_i387_struct elf_fpregset_t;
21
22#ifdef __i386__
23
24#define R_386_NONE 0
25#define R_386_32 1
26#define R_386_PC32 2
27#define R_386_GOT32 3
28#define R_386_PLT32 4
29#define R_386_COPY 5
30#define R_386_GLOB_DAT 6
31#define R_386_JMP_SLOT 7
32#define R_386_RELATIVE 8
33#define R_386_GOTOFF 9
34#define R_386_GOTPC 10
35#define R_386_NUM 11
36
37
38
39
40#define ELF_CLASS ELFCLASS32
41#define ELF_DATA ELFDATA2LSB
42#define ELF_ARCH EM_386
43
44#else
45
46
47#define R_X86_64_NONE 0
48#define R_X86_64_64 1
49#define R_X86_64_PC32 2
50#define R_X86_64_GOT32 3
51#define R_X86_64_PLT32 4
52#define R_X86_64_COPY 5
53#define R_X86_64_GLOB_DAT 6
54#define R_X86_64_JUMP_SLOT 7
55#define R_X86_64_RELATIVE 8
56#define R_X86_64_GOTPCREL 9
57
58#define R_X86_64_32 10
59#define R_X86_64_32S 11
60#define R_X86_64_16 12
61#define R_X86_64_PC16 13
62#define R_X86_64_8 14
63#define R_X86_64_PC8 15
64#define R_X86_64_PC64 24
65
66
67
68
69#define ELF_CLASS ELFCLASS64
70#define ELF_DATA ELFDATA2LSB
71#define ELF_ARCH EM_X86_64
72
73#endif
74
75#include <asm/vdso.h>
76
77#ifdef CONFIG_X86_64
78extern unsigned int vdso64_enabled;
79#endif
80#if defined(CONFIG_X86_32) || defined(CONFIG_IA32_EMULATION)
81extern unsigned int vdso32_enabled;
82#endif
83
84
85
86
87#define elf_check_arch_ia32(x) \
88 (((x)->e_machine == EM_386) || ((x)->e_machine == EM_486))
89
90#include <asm/processor.h>
91
92#ifdef CONFIG_X86_32
93#include <asm/desc.h>
94
95#define elf_check_arch(x) elf_check_arch_ia32(x)
96
97
98
99
100
101
102
103
104
105
106
107#define ELF_PLAT_INIT(_r, load_addr) \
108 do { \
109 _r->bx = 0; _r->cx = 0; _r->dx = 0; \
110 _r->si = 0; _r->di = 0; _r->bp = 0; \
111 _r->ax = 0; \
112} while (0)
113
114
115
116
117
118
119#define ELF_CORE_COPY_REGS(pr_reg, regs) \
120do { \
121 pr_reg[0] = regs->bx; \
122 pr_reg[1] = regs->cx; \
123 pr_reg[2] = regs->dx; \
124 pr_reg[3] = regs->si; \
125 pr_reg[4] = regs->di; \
126 pr_reg[5] = regs->bp; \
127 pr_reg[6] = regs->ax; \
128 pr_reg[7] = regs->ds; \
129 pr_reg[8] = regs->es; \
130 pr_reg[9] = regs->fs; \
131 savesegment(gs, pr_reg[10]); \
132 pr_reg[11] = regs->orig_ax; \
133 pr_reg[12] = regs->ip; \
134 pr_reg[13] = regs->cs; \
135 pr_reg[14] = regs->flags; \
136 pr_reg[15] = regs->sp; \
137 pr_reg[16] = regs->ss; \
138} while (0);
139
140#define ELF_PLATFORM (utsname()->machine)
141#define set_personality_64bit() do { } while (0)
142
143#else
144
145
146
147
148#define elf_check_arch(x) \
149 ((x)->e_machine == EM_X86_64)
150
151#define compat_elf_check_arch(x) \
152 (elf_check_arch_ia32(x) || \
153 (IS_ENABLED(CONFIG_X86_X32_ABI) && (x)->e_machine == EM_X86_64))
154
155#if __USER32_DS != __USER_DS
156# error "The following code assumes __USER32_DS == __USER_DS"
157#endif
158
159static inline void elf_common_init(struct thread_struct *t,
160 struct pt_regs *regs, const u16 ds)
161{
162
163 regs->bx = regs->cx = regs->dx = 0;
164 regs->si = regs->di = regs->bp = 0;
165 regs->r8 = regs->r9 = regs->r10 = regs->r11 = 0;
166 regs->r12 = regs->r13 = regs->r14 = regs->r15 = 0;
167 t->fsbase = t->gsbase = 0;
168 t->fsindex = t->gsindex = 0;
169 t->ds = t->es = ds;
170}
171
172#define ELF_PLAT_INIT(_r, load_addr) \
173 elf_common_init(¤t->thread, _r, 0)
174
175#define COMPAT_ELF_PLAT_INIT(regs, load_addr) \
176 elf_common_init(¤t->thread, regs, __USER_DS)
177
178void compat_start_thread(struct pt_regs *regs, u32 new_ip, u32 new_sp, bool x32);
179#define COMPAT_START_THREAD(ex, regs, new_ip, new_sp) \
180 compat_start_thread(regs, new_ip, new_sp, ex->e_machine == EM_X86_64)
181
182void set_personality_ia32(bool);
183#define COMPAT_SET_PERSONALITY(ex) \
184 set_personality_ia32((ex).e_machine == EM_X86_64)
185
186#define COMPAT_ELF_PLATFORM ("i686")
187
188
189
190
191
192
193
194#define ELF_CORE_COPY_REGS(pr_reg, regs) \
195do { \
196 unsigned v; \
197 (pr_reg)[0] = (regs)->r15; \
198 (pr_reg)[1] = (regs)->r14; \
199 (pr_reg)[2] = (regs)->r13; \
200 (pr_reg)[3] = (regs)->r12; \
201 (pr_reg)[4] = (regs)->bp; \
202 (pr_reg)[5] = (regs)->bx; \
203 (pr_reg)[6] = (regs)->r11; \
204 (pr_reg)[7] = (regs)->r10; \
205 (pr_reg)[8] = (regs)->r9; \
206 (pr_reg)[9] = (regs)->r8; \
207 (pr_reg)[10] = (regs)->ax; \
208 (pr_reg)[11] = (regs)->cx; \
209 (pr_reg)[12] = (regs)->dx; \
210 (pr_reg)[13] = (regs)->si; \
211 (pr_reg)[14] = (regs)->di; \
212 (pr_reg)[15] = (regs)->orig_ax; \
213 (pr_reg)[16] = (regs)->ip; \
214 (pr_reg)[17] = (regs)->cs; \
215 (pr_reg)[18] = (regs)->flags; \
216 (pr_reg)[19] = (regs)->sp; \
217 (pr_reg)[20] = (regs)->ss; \
218 (pr_reg)[21] = x86_fsbase_read_cpu(); \
219 (pr_reg)[22] = x86_gsbase_read_cpu_inactive(); \
220 asm("movl %%ds,%0" : "=r" (v)); (pr_reg)[23] = v; \
221 asm("movl %%es,%0" : "=r" (v)); (pr_reg)[24] = v; \
222 asm("movl %%fs,%0" : "=r" (v)); (pr_reg)[25] = v; \
223 asm("movl %%gs,%0" : "=r" (v)); (pr_reg)[26] = v; \
224} while (0);
225
226
227#define ELF_PLATFORM ("x86_64")
228extern void set_personality_64bit(void);
229extern unsigned int sysctl_vsyscall32;
230extern int force_personality32;
231
232#endif
233
234#define CORE_DUMP_USE_REGSET
235#define ELF_EXEC_PAGESIZE 4096
236
237
238
239
240
241
242#define ELF_ET_DYN_BASE (mmap_is_ia32() ? 0x000400000UL : \
243 (DEFAULT_MAP_WINDOW / 3 * 2))
244
245
246
247
248
249#define ELF_HWCAP (boot_cpu_data.x86_capability[CPUID_1_EDX])
250
251extern u32 elf_hwcap2;
252
253
254
255
256
257
258#define ELF_HWCAP2 (elf_hwcap2)
259
260
261
262
263
264
265
266
267#define SET_PERSONALITY(ex) set_personality_64bit()
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293#define elf_read_implies_exec(ex, executable_stack) \
294 (mmap_is_ia32() && executable_stack == EXSTACK_DEFAULT)
295
296struct task_struct;
297
298#define ARCH_DLINFO_IA32 \
299do { \
300 if (VDSO_CURRENT_BASE) { \
301 NEW_AUX_ENT(AT_SYSINFO, VDSO_ENTRY); \
302 NEW_AUX_ENT(AT_SYSINFO_EHDR, VDSO_CURRENT_BASE); \
303 } \
304 NEW_AUX_ENT(AT_MINSIGSTKSZ, get_sigframe_size()); \
305} while (0)
306
307
308
309
310static inline int mmap_is_ia32(void)
311{
312 return IS_ENABLED(CONFIG_X86_32) ||
313 (IS_ENABLED(CONFIG_COMPAT) &&
314 test_thread_flag(TIF_ADDR32));
315}
316
317extern unsigned long task_size_32bit(void);
318extern unsigned long task_size_64bit(int full_addr_space);
319extern unsigned long get_mmap_base(int is_legacy);
320extern bool mmap_address_hint_valid(unsigned long addr, unsigned long len);
321extern unsigned long get_sigframe_size(void);
322
323#ifdef CONFIG_X86_32
324
325#define __STACK_RND_MASK(is32bit) (0x7ff)
326#define STACK_RND_MASK (0x7ff)
327
328#define ARCH_DLINFO ARCH_DLINFO_IA32
329
330
331
332#else
333
334
335#define __STACK_RND_MASK(is32bit) ((is32bit) ? 0x7ff : 0x3fffff)
336#define STACK_RND_MASK __STACK_RND_MASK(mmap_is_ia32())
337
338#define ARCH_DLINFO \
339do { \
340 if (vdso64_enabled) \
341 NEW_AUX_ENT(AT_SYSINFO_EHDR, \
342 (unsigned long __force)current->mm->context.vdso); \
343 NEW_AUX_ENT(AT_MINSIGSTKSZ, get_sigframe_size()); \
344} while (0)
345
346
347#define ARCH_DLINFO_X32 \
348do { \
349 if (vdso64_enabled) \
350 NEW_AUX_ENT(AT_SYSINFO_EHDR, \
351 (unsigned long __force)current->mm->context.vdso); \
352 NEW_AUX_ENT(AT_MINSIGSTKSZ, get_sigframe_size()); \
353} while (0)
354
355#define AT_SYSINFO 32
356
357#define COMPAT_ARCH_DLINFO \
358if (exec->e_machine == EM_X86_64) \
359 ARCH_DLINFO_X32; \
360else if (IS_ENABLED(CONFIG_IA32_EMULATION)) \
361 ARCH_DLINFO_IA32
362
363#define COMPAT_ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x1000000)
364
365#endif
366
367#define VDSO_CURRENT_BASE ((unsigned long)current->mm->context.vdso)
368
369#define VDSO_ENTRY \
370 ((unsigned long)current->mm->context.vdso + \
371 vdso_image_32.sym___kernel_vsyscall)
372
373struct linux_binprm;
374
375#define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1
376extern int arch_setup_additional_pages(struct linux_binprm *bprm,
377 int uses_interp);
378extern int compat_arch_setup_additional_pages(struct linux_binprm *bprm,
379 int uses_interp, bool x32);
380#define COMPAT_ARCH_SETUP_ADDITIONAL_PAGES(bprm, ex, interpreter) \
381 compat_arch_setup_additional_pages(bprm, interpreter, \
382 (ex->e_machine == EM_X86_64))
383
384extern bool arch_syscall_is_vdso_sigreturn(struct pt_regs *regs);
385
386
387enum align_flags {
388 ALIGN_VA_32 = BIT(0),
389 ALIGN_VA_64 = BIT(1),
390};
391
392struct va_alignment {
393 int flags;
394 unsigned long mask;
395 unsigned long bits;
396} ____cacheline_aligned;
397
398extern struct va_alignment va_align;
399extern unsigned long align_vdso_addr(unsigned long);
400#endif
401