aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/ia32/ia32_binfmt.c124
-rw-r--r--include/asm-x86/compat.h6
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
50struct file; 61struct file;
51struct 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
66typedef unsigned int elf_greg_t;
67
68#define ELF_NGREG (sizeof (struct user_regs_struct32) / sizeof(elf_greg_t))
69typedef elf_greg_t elf_gregset_t[ELF_NGREG];
70
71struct 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
80struct 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
100struct 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
145typedef struct user_i387_ia32_struct elf_fpregset_t;
146typedef struct user32_fxsr_struct elf_fpxregset_t;
147
148 104
149static inline void elf_core_copy_regs(elf_gregset_t *elfregs, struct pt_regs *regs) 105#define elf_core_copy_regs elf32_core_copy_regs
106static 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
154static 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
113static 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
166static inline int 127static inline int
167elf_core_copy_task_fpregs(struct task_struct *tsk, struct pt_regs *regs, elf_fpregset_t *fpu) 128elf32_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
189static inline int 152static inline int
190elf_core_copy_task_xfpregs(struct task_struct *t, elf_fpxregset_t *xfpu) 153elf32_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
207extern int force_personality32; 170extern 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 */
187typedef 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