diff options
-rw-r--r-- | arch/x86/ia32/ia32_binfmt.c | 124 | ||||
-rw-r--r-- | include/asm-x86/compat.h | 6 |
2 files changed, 52 insertions, 78 deletions
diff --git a/arch/x86/ia32/ia32_binfmt.c b/arch/x86/ia32/ia32_binfmt.c index 5027650eb273..55822d2cf053 100644 --- a/arch/x86/ia32/ia32_binfmt.c +++ b/arch/x86/ia32/ia32_binfmt.c | |||
@@ -5,10 +5,6 @@ | |||
5 | * This tricks binfmt_elf.c into loading 32bit binaries using lots | 5 | * This tricks binfmt_elf.c into loading 32bit binaries using lots |
6 | * of ugly preprocessor tricks. Talk about very very poor man's inheritance. | 6 | * of ugly preprocessor tricks. Talk about very very poor man's inheritance. |
7 | */ | 7 | */ |
8 | #define __ASM_X86_64_ELF_H 1 | ||
9 | |||
10 | #undef ELF_CLASS | ||
11 | #define ELF_CLASS ELFCLASS32 | ||
12 | 8 | ||
13 | #include <linux/types.h> | 9 | #include <linux/types.h> |
14 | #include <linux/stddef.h> | 10 | #include <linux/stddef.h> |
@@ -19,6 +15,7 @@ | |||
19 | #include <linux/binfmts.h> | 15 | #include <linux/binfmts.h> |
20 | #include <linux/mm.h> | 16 | #include <linux/mm.h> |
21 | #include <linux/security.h> | 17 | #include <linux/security.h> |
18 | #include <linux/elfcore-compat.h> | ||
22 | 19 | ||
23 | #include <asm/segment.h> | 20 | #include <asm/segment.h> |
24 | #include <asm/ptrace.h> | 21 | #include <asm/ptrace.h> |
@@ -31,6 +28,20 @@ | |||
31 | #include <asm/ia32.h> | 28 | #include <asm/ia32.h> |
32 | #include <asm/vsyscall32.h> | 29 | #include <asm/vsyscall32.h> |
33 | 30 | ||
31 | #undef ELF_ARCH | ||
32 | #undef ELF_CLASS | ||
33 | #define ELF_CLASS ELFCLASS32 | ||
34 | #define ELF_ARCH EM_386 | ||
35 | |||
36 | #undef elfhdr | ||
37 | #undef elf_phdr | ||
38 | #undef elf_note | ||
39 | #undef elf_addr_t | ||
40 | #define elfhdr elf32_hdr | ||
41 | #define elf_phdr elf32_phdr | ||
42 | #define elf_note elf32_note | ||
43 | #define elf_addr_t Elf32_Off | ||
44 | |||
34 | #define ELF_NAME "elf/i386" | 45 | #define ELF_NAME "elf/i386" |
35 | 46 | ||
36 | #define AT_SYSINFO 32 | 47 | #define AT_SYSINFO 32 |
@@ -48,74 +59,20 @@ int sysctl_vsyscall32 = 1; | |||
48 | } while(0) | 59 | } while(0) |
49 | 60 | ||
50 | struct file; | 61 | struct file; |
51 | struct elf_phdr; | ||
52 | 62 | ||
53 | #define IA32_EMULATOR 1 | 63 | #define IA32_EMULATOR 1 |
54 | 64 | ||
55 | #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x1000000) | 65 | #undef ELF_ET_DYN_BASE |
56 | |||
57 | #undef ELF_ARCH | ||
58 | #define ELF_ARCH EM_386 | ||
59 | |||
60 | #define ELF_DATA ELFDATA2LSB | ||
61 | 66 | ||
62 | #define USE_ELF_CORE_DUMP 1 | 67 | #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x1000000) |
63 | |||
64 | /* Override elfcore.h */ | ||
65 | #define _LINUX_ELFCORE_H 1 | ||
66 | typedef unsigned int elf_greg_t; | ||
67 | |||
68 | #define ELF_NGREG (sizeof (struct user_regs_struct32) / sizeof(elf_greg_t)) | ||
69 | typedef elf_greg_t elf_gregset_t[ELF_NGREG]; | ||
70 | |||
71 | struct elf_siginfo | ||
72 | { | ||
73 | int si_signo; /* signal number */ | ||
74 | int si_code; /* extra code */ | ||
75 | int si_errno; /* errno */ | ||
76 | }; | ||
77 | 68 | ||
78 | #define jiffies_to_timeval(a,b) do { (b)->tv_usec = 0; (b)->tv_sec = (a)/HZ; }while(0) | 69 | #define jiffies_to_timeval(a,b) do { (b)->tv_usec = 0; (b)->tv_sec = (a)/HZ; }while(0) |
79 | 70 | ||
80 | struct elf_prstatus | ||
81 | { | ||
82 | struct elf_siginfo pr_info; /* Info associated with signal */ | ||
83 | short pr_cursig; /* Current signal */ | ||
84 | unsigned int pr_sigpend; /* Set of pending signals */ | ||
85 | unsigned int pr_sighold; /* Set of held signals */ | ||
86 | pid_t pr_pid; | ||
87 | pid_t pr_ppid; | ||
88 | pid_t pr_pgrp; | ||
89 | pid_t pr_sid; | ||
90 | struct compat_timeval pr_utime; /* User time */ | ||
91 | struct compat_timeval pr_stime; /* System time */ | ||
92 | struct compat_timeval pr_cutime; /* Cumulative user time */ | ||
93 | struct compat_timeval pr_cstime; /* Cumulative system time */ | ||
94 | elf_gregset_t pr_reg; /* GP registers */ | ||
95 | int pr_fpvalid; /* True if math co-processor being used. */ | ||
96 | }; | ||
97 | |||
98 | #define ELF_PRARGSZ (80) /* Number of chars for args */ | ||
99 | |||
100 | struct elf_prpsinfo | ||
101 | { | ||
102 | char pr_state; /* numeric process state */ | ||
103 | char pr_sname; /* char for pr_state */ | ||
104 | char pr_zomb; /* zombie */ | ||
105 | char pr_nice; /* nice val */ | ||
106 | unsigned int pr_flag; /* flags */ | ||
107 | __u16 pr_uid; | ||
108 | __u16 pr_gid; | ||
109 | pid_t pr_pid, pr_ppid, pr_pgrp, pr_sid; | ||
110 | /* Lots missing */ | ||
111 | char pr_fname[16]; /* filename of executable */ | ||
112 | char pr_psargs[ELF_PRARGSZ]; /* initial part of arg list */ | ||
113 | }; | ||
114 | |||
115 | #define _GET_SEG(x) \ | 71 | #define _GET_SEG(x) \ |
116 | ({ __u32 seg; asm("movl %%" __stringify(x) ",%0" : "=r"(seg)); seg; }) | 72 | ({ __u32 seg; asm("movl %%" __stringify(x) ",%0" : "=r"(seg)); seg; }) |
117 | 73 | ||
118 | /* Assumes current==process to be dumped */ | 74 | /* Assumes current==process to be dumped */ |
75 | #undef ELF_CORE_COPY_REGS | ||
119 | #define ELF_CORE_COPY_REGS(pr_reg, regs) \ | 76 | #define ELF_CORE_COPY_REGS(pr_reg, regs) \ |
120 | pr_reg[0] = regs->rbx; \ | 77 | pr_reg[0] = regs->rbx; \ |
121 | pr_reg[1] = regs->rcx; \ | 78 | pr_reg[1] = regs->rcx; \ |
@@ -135,36 +92,41 @@ struct elf_prpsinfo | |||
135 | pr_reg[15] = regs->rsp; \ | 92 | pr_reg[15] = regs->rsp; \ |
136 | pr_reg[16] = regs->ss; | 93 | pr_reg[16] = regs->ss; |
137 | 94 | ||
138 | #define user user32 | 95 | |
96 | #define elf_prstatus compat_elf_prstatus | ||
97 | #define elf_prpsinfo compat_elf_prpsinfo | ||
98 | #define elf_fpregset_t struct user_i387_ia32_struct | ||
99 | #define elf_fpxregset_t struct user32_fxsr_struct | ||
100 | #define user user32 | ||
139 | 101 | ||
140 | #undef elf_read_implies_exec | 102 | #undef elf_read_implies_exec |
141 | #define elf_read_implies_exec(ex, executable_stack) (executable_stack != EXSTACK_DISABLE_X) | 103 | #define elf_read_implies_exec(ex, executable_stack) (executable_stack != EXSTACK_DISABLE_X) |
142 | //#include <asm/ia32.h> | ||
143 | #include <linux/elf.h> | ||
144 | |||
145 | typedef struct user_i387_ia32_struct elf_fpregset_t; | ||
146 | typedef struct user32_fxsr_struct elf_fpxregset_t; | ||
147 | |||
148 | 104 | ||
149 | static inline void elf_core_copy_regs(elf_gregset_t *elfregs, struct pt_regs *regs) | 105 | #define elf_core_copy_regs elf32_core_copy_regs |
106 | static inline void elf32_core_copy_regs(compat_elf_gregset_t *elfregs, | ||
107 | struct pt_regs *regs) | ||
150 | { | 108 | { |
151 | ELF_CORE_COPY_REGS((*elfregs), regs) | 109 | ELF_CORE_COPY_REGS((&elfregs->ebx), regs) |
152 | } | 110 | } |
153 | 111 | ||
154 | static inline int elf_core_copy_task_regs(struct task_struct *t, elf_gregset_t* elfregs) | 112 | #define elf_core_copy_task_regs elf32_core_copy_task_regs |
113 | static inline int elf32_core_copy_task_regs(struct task_struct *t, | ||
114 | compat_elf_gregset_t* elfregs) | ||
155 | { | 115 | { |
156 | struct pt_regs *pp = task_pt_regs(t); | 116 | struct pt_regs *pp = task_pt_regs(t); |
157 | ELF_CORE_COPY_REGS((*elfregs), pp); | 117 | ELF_CORE_COPY_REGS((&elfregs->ebx), pp); |
158 | /* fix wrong segments */ | 118 | /* fix wrong segments */ |
159 | (*elfregs)[7] = t->thread.ds; | 119 | elfregs->ds = t->thread.ds; |
160 | (*elfregs)[9] = t->thread.fsindex; | 120 | elfregs->fs = t->thread.fsindex; |
161 | (*elfregs)[10] = t->thread.gsindex; | 121 | elfregs->gs = t->thread.gsindex; |
162 | (*elfregs)[8] = t->thread.es; | 122 | elfregs->es = t->thread.es; |
163 | return 1; | 123 | return 1; |
164 | } | 124 | } |
165 | 125 | ||
126 | #define elf_core_copy_task_fpregs elf32_core_copy_task_fpregs | ||
166 | static inline int | 127 | static inline int |
167 | elf_core_copy_task_fpregs(struct task_struct *tsk, struct pt_regs *regs, elf_fpregset_t *fpu) | 128 | elf32_core_copy_task_fpregs(struct task_struct *tsk, struct pt_regs *regs, |
129 | elf_fpregset_t *fpu) | ||
168 | { | 130 | { |
169 | struct _fpstate_ia32 *fpstate = (void*)fpu; | 131 | struct _fpstate_ia32 *fpstate = (void*)fpu; |
170 | mm_segment_t oldfs = get_fs(); | 132 | mm_segment_t oldfs = get_fs(); |
@@ -186,8 +148,9 @@ elf_core_copy_task_fpregs(struct task_struct *tsk, struct pt_regs *regs, elf_fpr | |||
186 | 148 | ||
187 | #define ELF_CORE_COPY_XFPREGS 1 | 149 | #define ELF_CORE_COPY_XFPREGS 1 |
188 | #define ELF_CORE_XFPREG_TYPE NT_PRXFPREG | 150 | #define ELF_CORE_XFPREG_TYPE NT_PRXFPREG |
151 | #define elf_core_copy_task_xfpregs elf32_core_copy_task_xfpregs | ||
189 | static inline int | 152 | static inline int |
190 | elf_core_copy_task_xfpregs(struct task_struct *t, elf_fpxregset_t *xfpu) | 153 | elf32_core_copy_task_xfpregs(struct task_struct *t, elf_fpxregset_t *xfpu) |
191 | { | 154 | { |
192 | struct pt_regs *regs = task_pt_regs(t); | 155 | struct pt_regs *regs = task_pt_regs(t); |
193 | if (!tsk_used_math(t)) | 156 | if (!tsk_used_math(t)) |
@@ -206,6 +169,10 @@ elf_core_copy_task_xfpregs(struct task_struct *t, elf_fpxregset_t *xfpu) | |||
206 | 169 | ||
207 | extern int force_personality32; | 170 | extern int force_personality32; |
208 | 171 | ||
172 | #undef ELF_EXEC_PAGESIZE | ||
173 | #undef ELF_HWCAP | ||
174 | #undef ELF_PLATFORM | ||
175 | #undef SET_PERSONALITY | ||
209 | #define ELF_EXEC_PAGESIZE PAGE_SIZE | 176 | #define ELF_EXEC_PAGESIZE PAGE_SIZE |
210 | #define ELF_HWCAP (boot_cpu_data.x86_capability[0]) | 177 | #define ELF_HWCAP (boot_cpu_data.x86_capability[0]) |
211 | #define ELF_PLATFORM ("i686") | 178 | #define ELF_PLATFORM ("i686") |
@@ -231,6 +198,7 @@ do { \ | |||
231 | 198 | ||
232 | #define load_elf_binary load_elf32_binary | 199 | #define load_elf_binary load_elf32_binary |
233 | 200 | ||
201 | #undef ELF_PLAT_INIT | ||
234 | #define ELF_PLAT_INIT(r, load_addr) elf32_init(r) | 202 | #define ELF_PLAT_INIT(r, load_addr) elf32_init(r) |
235 | 203 | ||
236 | #undef start_thread | 204 | #undef start_thread |
diff --git a/include/asm-x86/compat.h b/include/asm-x86/compat.h index 53cb96b68a62..66ba7987184a 100644 --- a/include/asm-x86/compat.h +++ b/include/asm-x86/compat.h | |||
@@ -6,6 +6,7 @@ | |||
6 | */ | 6 | */ |
7 | #include <linux/types.h> | 7 | #include <linux/types.h> |
8 | #include <linux/sched.h> | 8 | #include <linux/sched.h> |
9 | #include <asm/user32.h> | ||
9 | 10 | ||
10 | #define COMPAT_USER_HZ 100 | 11 | #define COMPAT_USER_HZ 100 |
11 | 12 | ||
@@ -181,6 +182,11 @@ struct compat_shmid64_ds { | |||
181 | }; | 182 | }; |
182 | 183 | ||
183 | /* | 184 | /* |
185 | * The type of struct elf_prstatus.pr_reg in compatible core dumps. | ||
186 | */ | ||
187 | typedef struct user_regs_struct32 compat_elf_gregset_t; | ||
188 | |||
189 | /* | ||
184 | * A pointer passed in from user mode. This should not | 190 | * A pointer passed in from user mode. This should not |
185 | * be used for syscall parameters, just declare them | 191 | * be used for syscall parameters, just declare them |
186 | * as pointers because the syscall entry code will have | 192 | * as pointers because the syscall entry code will have |