1 |
1275 |
phoenix |
#ifndef __ASM_X86_64_ELF_H
|
2 |
|
|
#define __ASM_X86_64_ELF_H
|
3 |
|
|
|
4 |
|
|
/*
|
5 |
|
|
* ELF register definitions..
|
6 |
|
|
*/
|
7 |
|
|
|
8 |
|
|
#include <asm/ptrace.h>
|
9 |
|
|
#include <asm/user.h>
|
10 |
|
|
|
11 |
|
|
typedef unsigned long elf_greg_t;
|
12 |
|
|
|
13 |
|
|
#define ELF_NGREG (sizeof (struct user_regs_struct) / sizeof(elf_greg_t))
|
14 |
|
|
typedef elf_greg_t elf_gregset_t[ELF_NGREG];
|
15 |
|
|
|
16 |
|
|
typedef struct user_i387_struct elf_fpregset_t;
|
17 |
|
|
typedef struct user_fxsr_struct elf_fpxregset_t;
|
18 |
|
|
|
19 |
|
|
/*
|
20 |
|
|
* This is used to ensure we don't load something for the wrong architecture.
|
21 |
|
|
*/
|
22 |
|
|
#define elf_check_arch(x) \
|
23 |
|
|
((x)->e_machine == EM_X86_64)
|
24 |
|
|
|
25 |
|
|
/*
|
26 |
|
|
* These are used to set parameters in the core dumps.
|
27 |
|
|
*/
|
28 |
|
|
#define ELF_CLASS ELFCLASS64
|
29 |
|
|
#define ELF_DATA ELFDATA2LSB
|
30 |
|
|
#define ELF_ARCH EM_X86_64
|
31 |
|
|
|
32 |
|
|
/* SVR4/i386 ABI (pages 3-31, 3-32) says that when the program starts %edx
|
33 |
|
|
contains a pointer to a function which might be registered using `atexit'.
|
34 |
|
|
This provides a mean for the dynamic linker to call DT_FINI functions for
|
35 |
|
|
shared libraries that have been loaded before the code runs.
|
36 |
|
|
|
37 |
|
|
A value of 0 tells we have no such handler.
|
38 |
|
|
|
39 |
|
|
We might as well make sure everything else is cleared too (except for %esp),
|
40 |
|
|
just to make things more deterministic.
|
41 |
|
|
*/
|
42 |
|
|
#define ELF_PLAT_INIT(_r, load_addr) do { \
|
43 |
|
|
struct task_struct *cur = current; \
|
44 |
|
|
(_r)->rbx = 0; (_r)->rcx = 0; (_r)->rdx = 0; \
|
45 |
|
|
(_r)->rsi = 0; (_r)->rdi = 0; (_r)->rbp = 0; \
|
46 |
|
|
(_r)->rax = 0; \
|
47 |
|
|
(_r)->r8 = 0; \
|
48 |
|
|
(_r)->r9 = 0; \
|
49 |
|
|
(_r)->r10 = 0; \
|
50 |
|
|
(_r)->r11 = 0; \
|
51 |
|
|
(_r)->r12 = 0; \
|
52 |
|
|
(_r)->r13 = 0; \
|
53 |
|
|
(_r)->r14 = 0; \
|
54 |
|
|
(_r)->r15 = 0; \
|
55 |
|
|
cur->thread.fs = 0; cur->thread.gs = 0; \
|
56 |
|
|
cur->thread.fsindex = 0; cur->thread.gsindex = 0; \
|
57 |
|
|
cur->thread.ds = 0; cur->thread.es = 0; \
|
58 |
|
|
cur->thread.flags &= ~THREAD_IA32; \
|
59 |
|
|
} while (0)
|
60 |
|
|
|
61 |
|
|
#define USE_ELF_CORE_DUMP
|
62 |
|
|
#define ELF_EXEC_PAGESIZE 4096
|
63 |
|
|
|
64 |
|
|
/* This is the location that an ET_DYN program is loaded if exec'ed. Typical
|
65 |
|
|
use of this is to invoke "./ld.so someprog" to test out a new version of
|
66 |
|
|
the loader. We need to make sure that it is out of the way of the program
|
67 |
|
|
that it will "exec", and that there is sufficient room for the brk. */
|
68 |
|
|
|
69 |
|
|
#define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3)
|
70 |
|
|
|
71 |
|
|
/* regs is struct pt_regs, pr_reg is elf_gregset_t (which is
|
72 |
|
|
now struct_user_regs, they are different). Assumes current is the process
|
73 |
|
|
getting dumped. */
|
74 |
|
|
|
75 |
|
|
#define ELF_CORE_COPY_REGS(pr_reg, regs) do { \
|
76 |
|
|
unsigned v; \
|
77 |
|
|
(pr_reg)[0] = (regs)->r15; \
|
78 |
|
|
(pr_reg)[1] = (regs)->r14; \
|
79 |
|
|
(pr_reg)[2] = (regs)->r13; \
|
80 |
|
|
(pr_reg)[3] = (regs)->r12; \
|
81 |
|
|
(pr_reg)[4] = (regs)->rbp; \
|
82 |
|
|
(pr_reg)[5] = (regs)->rbx; \
|
83 |
|
|
(pr_reg)[6] = (regs)->r11; \
|
84 |
|
|
(pr_reg)[7] = (regs)->r10; \
|
85 |
|
|
(pr_reg)[8] = (regs)->r9; \
|
86 |
|
|
(pr_reg)[9] = (regs)->r8; \
|
87 |
|
|
(pr_reg)[10] = (regs)->rax; \
|
88 |
|
|
(pr_reg)[11] = (regs)->rcx; \
|
89 |
|
|
(pr_reg)[12] = (regs)->rdx; \
|
90 |
|
|
(pr_reg)[13] = (regs)->rsi; \
|
91 |
|
|
(pr_reg)[14] = (regs)->rdi; \
|
92 |
|
|
(pr_reg)[15] = (regs)->orig_rax; \
|
93 |
|
|
(pr_reg)[16] = (regs)->rip; \
|
94 |
|
|
(pr_reg)[17] = (regs)->cs; \
|
95 |
|
|
(pr_reg)[18] = (regs)->eflags; \
|
96 |
|
|
(pr_reg)[19] = (regs)->rsp; \
|
97 |
|
|
(pr_reg)[20] = (regs)->ss; \
|
98 |
|
|
(pr_reg)[21] = current->thread.fs; \
|
99 |
|
|
(pr_reg)[22] = current->thread.gs; \
|
100 |
|
|
asm("movl %%ds,%0" : "=r" (v)); (pr_reg)[23] = v; \
|
101 |
|
|
asm("movl %%es,%0" : "=r" (v)); (pr_reg)[24] = v; \
|
102 |
|
|
asm("movl %%fs,%0" : "=r" (v)); (pr_reg)[25] = v; \
|
103 |
|
|
asm("movl %%gs,%0" : "=r" (v)); (pr_reg)[26] = v; \
|
104 |
|
|
} while(0);
|
105 |
|
|
|
106 |
|
|
/* This yields a mask that user programs can use to figure out what
|
107 |
|
|
instruction set this CPU supports. This could be done in user space,
|
108 |
|
|
but it's not easy, and we've already done it here. */
|
109 |
|
|
|
110 |
|
|
#define ELF_HWCAP (boot_cpu_data.x86_capability[0])
|
111 |
|
|
|
112 |
|
|
/* This yields a string that ld.so will use to load implementation
|
113 |
|
|
specific libraries for optimization. This is more specific in
|
114 |
|
|
intent than poking at uname or /proc/cpuinfo.
|
115 |
|
|
|
116 |
|
|
For the moment, we have only optimizations for the Intel generations,
|
117 |
|
|
but that could change... */
|
118 |
|
|
|
119 |
|
|
/* I'm not sure if we can use '-' here */
|
120 |
|
|
#define ELF_PLATFORM ("x86_64")
|
121 |
|
|
|
122 |
|
|
#ifdef __KERNEL__
|
123 |
|
|
extern void set_personality_64bit(void);
|
124 |
|
|
#define SET_PERSONALITY(ex, ibcs2) set_personality_64bit()
|
125 |
|
|
|
126 |
|
|
#endif
|
127 |
|
|
|
128 |
|
|
#endif
|