aboutsummaryrefslogtreecommitdiffstats
path: root/arch/um/sys-i386
diff options
context:
space:
mode:
Diffstat (limited to 'arch/um/sys-i386')
-rw-r--r--arch/um/sys-i386/Makefile2
-rw-r--r--arch/um/sys-i386/asm/elf.h44
-rw-r--r--arch/um/sys-i386/elfcore.c83
-rw-r--r--arch/um/sys-i386/ldt.c1
-rw-r--r--arch/um/sys-i386/shared/sysdep/syscalls.h6
-rw-r--r--arch/um/sys-i386/sys_call_table.S2
-rw-r--r--arch/um/sys-i386/syscalls.c137
7 files changed, 87 insertions, 188 deletions
diff --git a/arch/um/sys-i386/Makefile b/arch/um/sys-i386/Makefile
index 1b549bca4645..804b28dd0328 100644
--- a/arch/um/sys-i386/Makefile
+++ b/arch/um/sys-i386/Makefile
@@ -6,6 +6,8 @@ obj-y = bug.o bugs.o checksum.o delay.o fault.o ksyms.o ldt.o ptrace.o \
6 ptrace_user.o setjmp.o signal.o stub.o stub_segv.o syscalls.o sysrq.o \ 6 ptrace_user.o setjmp.o signal.o stub.o stub_segv.o syscalls.o sysrq.o \
7 sys_call_table.o tls.o 7 sys_call_table.o tls.o
8 8
9obj-$(CONFIG_BINFMT_ELF) += elfcore.o
10
9subarch-obj-y = lib/semaphore_32.o lib/string_32.o 11subarch-obj-y = lib/semaphore_32.o lib/string_32.o
10subarch-obj-$(CONFIG_HIGHMEM) += mm/highmem_32.o 12subarch-obj-$(CONFIG_HIGHMEM) += mm/highmem_32.o
11subarch-obj-$(CONFIG_MODULES) += kernel/module.o 13subarch-obj-$(CONFIG_MODULES) += kernel/module.o
diff --git a/arch/um/sys-i386/asm/elf.h b/arch/um/sys-i386/asm/elf.h
index d0da9d7c5371..e64cd41d7bab 100644
--- a/arch/um/sys-i386/asm/elf.h
+++ b/arch/um/sys-i386/asm/elf.h
@@ -48,7 +48,6 @@ typedef struct user_i387_struct elf_fpregset_t;
48 PT_REGS_EAX(regs) = 0; \ 48 PT_REGS_EAX(regs) = 0; \
49} while (0) 49} while (0)
50 50
51#define USE_ELF_CORE_DUMP
52#define ELF_EXEC_PAGESIZE 4096 51#define ELF_EXEC_PAGESIZE 4096
53 52
54#define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3) 53#define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3)
@@ -117,47 +116,4 @@ do { \
117 } \ 116 } \
118} while (0) 117} while (0)
119 118
120/*
121 * These macros parameterize elf_core_dump in fs/binfmt_elf.c to write out
122 * extra segments containing the vsyscall DSO contents. Dumping its
123 * contents makes post-mortem fully interpretable later without matching up
124 * the same kernel and hardware config to see what PC values meant.
125 * Dumping its extra ELF program headers includes all the other information
126 * a debugger needs to easily find how the vsyscall DSO was being used.
127 */
128#define ELF_CORE_EXTRA_PHDRS \
129 (vsyscall_ehdr ? (((struct elfhdr *)vsyscall_ehdr)->e_phnum) : 0 )
130
131#define ELF_CORE_WRITE_EXTRA_PHDRS \
132if ( vsyscall_ehdr ) { \
133 const struct elfhdr *const ehdrp = (struct elfhdr *)vsyscall_ehdr; \
134 const struct elf_phdr *const phdrp = \
135 (const struct elf_phdr *) (vsyscall_ehdr + ehdrp->e_phoff); \
136 int i; \
137 Elf32_Off ofs = 0; \
138 for (i = 0; i < ehdrp->e_phnum; ++i) { \
139 struct elf_phdr phdr = phdrp[i]; \
140 if (phdr.p_type == PT_LOAD) { \
141 ofs = phdr.p_offset = offset; \
142 offset += phdr.p_filesz; \
143 } \
144 else \
145 phdr.p_offset += ofs; \
146 phdr.p_paddr = 0; /* match other core phdrs */ \
147 DUMP_WRITE(&phdr, sizeof(phdr)); \
148 } \
149}
150#define ELF_CORE_WRITE_EXTRA_DATA \
151if ( vsyscall_ehdr ) { \
152 const struct elfhdr *const ehdrp = (struct elfhdr *)vsyscall_ehdr; \
153 const struct elf_phdr *const phdrp = \
154 (const struct elf_phdr *) (vsyscall_ehdr + ehdrp->e_phoff); \
155 int i; \
156 for (i = 0; i < ehdrp->e_phnum; ++i) { \
157 if (phdrp[i].p_type == PT_LOAD) \
158 DUMP_WRITE((void *) phdrp[i].p_vaddr, \
159 phdrp[i].p_filesz); \
160 } \
161}
162
163#endif 119#endif
diff --git a/arch/um/sys-i386/elfcore.c b/arch/um/sys-i386/elfcore.c
new file mode 100644
index 000000000000..6bb49b687c97
--- /dev/null
+++ b/arch/um/sys-i386/elfcore.c
@@ -0,0 +1,83 @@
1#include <linux/elf.h>
2#include <linux/coredump.h>
3#include <linux/fs.h>
4#include <linux/mm.h>
5
6#include <asm/elf.h>
7
8
9Elf32_Half elf_core_extra_phdrs(void)
10{
11 return vsyscall_ehdr ? (((struct elfhdr *)vsyscall_ehdr)->e_phnum) : 0;
12}
13
14int elf_core_write_extra_phdrs(struct file *file, loff_t offset, size_t *size,
15 unsigned long limit)
16{
17 if ( vsyscall_ehdr ) {
18 const struct elfhdr *const ehdrp =
19 (struct elfhdr *) vsyscall_ehdr;
20 const struct elf_phdr *const phdrp =
21 (const struct elf_phdr *) (vsyscall_ehdr + ehdrp->e_phoff);
22 int i;
23 Elf32_Off ofs = 0;
24
25 for (i = 0; i < ehdrp->e_phnum; ++i) {
26 struct elf_phdr phdr = phdrp[i];
27
28 if (phdr.p_type == PT_LOAD) {
29 ofs = phdr.p_offset = offset;
30 offset += phdr.p_filesz;
31 } else {
32 phdr.p_offset += ofs;
33 }
34 phdr.p_paddr = 0; /* match other core phdrs */
35 *size += sizeof(phdr);
36 if (*size > limit
37 || !dump_write(file, &phdr, sizeof(phdr)))
38 return 0;
39 }
40 }
41 return 1;
42}
43
44int elf_core_write_extra_data(struct file *file, size_t *size,
45 unsigned long limit)
46{
47 if ( vsyscall_ehdr ) {
48 const struct elfhdr *const ehdrp =
49 (struct elfhdr *) vsyscall_ehdr;
50 const struct elf_phdr *const phdrp =
51 (const struct elf_phdr *) (vsyscall_ehdr + ehdrp->e_phoff);
52 int i;
53
54 for (i = 0; i < ehdrp->e_phnum; ++i) {
55 if (phdrp[i].p_type == PT_LOAD) {
56 void *addr = (void *) phdrp[i].p_vaddr;
57 size_t filesz = phdrp[i].p_filesz;
58
59 *size += filesz;
60 if (*size > limit
61 || !dump_write(file, addr, filesz))
62 return 0;
63 }
64 }
65 }
66 return 1;
67}
68
69size_t elf_core_extra_data_size(void)
70{
71 if ( vsyscall_ehdr ) {
72 const struct elfhdr *const ehdrp =
73 (struct elfhdr *)vsyscall_ehdr;
74 const struct elf_phdr *const phdrp =
75 (const struct elf_phdr *) (vsyscall_ehdr + ehdrp->e_phoff);
76 int i;
77
78 for (i = 0; i < ehdrp->e_phnum; ++i)
79 if (phdrp[i].p_type == PT_LOAD)
80 return (size_t) phdrp[i].p_filesz;
81 }
82 return 0;
83}
diff --git a/arch/um/sys-i386/ldt.c b/arch/um/sys-i386/ldt.c
index a4846a84a7be..3f2bf208d884 100644
--- a/arch/um/sys-i386/ldt.c
+++ b/arch/um/sys-i386/ldt.c
@@ -5,6 +5,7 @@
5 5
6#include <linux/mm.h> 6#include <linux/mm.h>
7#include <linux/sched.h> 7#include <linux/sched.h>
8#include <linux/slab.h>
8#include <asm/unistd.h> 9#include <asm/unistd.h>
9#include "os.h" 10#include "os.h"
10#include "proc_mm.h" 11#include "proc_mm.h"
diff --git a/arch/um/sys-i386/shared/sysdep/syscalls.h b/arch/um/sys-i386/shared/sysdep/syscalls.h
index 905698197e35..05cb796aecb5 100644
--- a/arch/um/sys-i386/shared/sysdep/syscalls.h
+++ b/arch/um/sys-i386/shared/sysdep/syscalls.h
@@ -13,14 +13,8 @@ typedef long syscall_handler_t(struct pt_regs);
13 */ 13 */
14extern syscall_handler_t sys_rt_sigaction; 14extern syscall_handler_t sys_rt_sigaction;
15 15
16extern syscall_handler_t old_mmap_i386;
17
18extern syscall_handler_t *sys_call_table[]; 16extern syscall_handler_t *sys_call_table[];
19 17
20#define EXECUTE_SYSCALL(syscall, regs) \ 18#define EXECUTE_SYSCALL(syscall, regs) \
21 ((long (*)(struct syscall_args)) \ 19 ((long (*)(struct syscall_args)) \
22 (*sys_call_table[syscall]))(SYSCALL_ARGS(&regs->regs)) 20 (*sys_call_table[syscall]))(SYSCALL_ARGS(&regs->regs))
23
24extern long sys_mmap2(unsigned long addr, unsigned long len,
25 unsigned long prot, unsigned long flags,
26 unsigned long fd, unsigned long pgoff);
diff --git a/arch/um/sys-i386/sys_call_table.S b/arch/um/sys-i386/sys_call_table.S
index c6260dd6ebb9..de274071455d 100644
--- a/arch/um/sys-i386/sys_call_table.S
+++ b/arch/um/sys-i386/sys_call_table.S
@@ -7,7 +7,7 @@
7#define sys_vm86old sys_ni_syscall 7#define sys_vm86old sys_ni_syscall
8#define sys_vm86 sys_ni_syscall 8#define sys_vm86 sys_ni_syscall
9 9
10#define old_mmap old_mmap_i386 10#define old_mmap sys_old_mmap
11 11
12#define ptregs_fork sys_fork 12#define ptregs_fork sys_fork
13#define ptregs_execve sys_execve 13#define ptregs_execve sys_execve
diff --git a/arch/um/sys-i386/syscalls.c b/arch/um/sys-i386/syscalls.c
index 857ca0b3bdef..70ca357393b8 100644
--- a/arch/um/sys-i386/syscalls.c
+++ b/arch/um/sys-i386/syscalls.c
@@ -12,57 +12,6 @@
12#include "asm/unistd.h" 12#include "asm/unistd.h"
13 13
14/* 14/*
15 * Perform the select(nd, in, out, ex, tv) and mmap() system
16 * calls. Linux/i386 didn't use to be able to handle more than
17 * 4 system call parameters, so these system calls used a memory
18 * block for parameter passing..
19 */
20
21struct mmap_arg_struct {
22 unsigned long addr;
23 unsigned long len;
24 unsigned long prot;
25 unsigned long flags;
26 unsigned long fd;
27 unsigned long offset;
28};
29
30extern int old_mmap(unsigned long addr, unsigned long len,
31 unsigned long prot, unsigned long flags,
32 unsigned long fd, unsigned long offset);
33
34long old_mmap_i386(struct mmap_arg_struct __user *arg)
35{
36 struct mmap_arg_struct a;
37 int err = -EFAULT;
38
39 if (copy_from_user(&a, arg, sizeof(a)))
40 goto out;
41
42 err = old_mmap(a.addr, a.len, a.prot, a.flags, a.fd, a.offset);
43 out:
44 return err;
45}
46
47struct sel_arg_struct {
48 unsigned long n;
49 fd_set __user *inp;
50 fd_set __user *outp;
51 fd_set __user *exp;
52 struct timeval __user *tvp;
53};
54
55long old_select(struct sel_arg_struct __user *arg)
56{
57 struct sel_arg_struct a;
58
59 if (copy_from_user(&a, arg, sizeof(a)))
60 return -EFAULT;
61 /* sys_select() does the appropriate kernel locking */
62 return sys_select(a.n, a.inp, a.outp, a.exp, a.tvp);
63}
64
65/*
66 * The prototype on i386 is: 15 * The prototype on i386 is:
67 * 16 *
68 * int clone(int flags, void * child_stack, int * parent_tidptr, struct user_desc * newtls, int * child_tidptr) 17 * int clone(int flags, void * child_stack, int * parent_tidptr, struct user_desc * newtls, int * child_tidptr)
@@ -85,92 +34,6 @@ long sys_clone(unsigned long clone_flags, unsigned long newsp,
85 return ret; 34 return ret;
86} 35}
87 36
88/*
89 * sys_ipc() is the de-multiplexer for the SysV IPC calls..
90 *
91 * This is really horribly ugly.
92 */
93long sys_ipc (uint call, int first, int second,
94 int third, void __user *ptr, long fifth)
95{
96 int version, ret;
97
98 version = call >> 16; /* hack for backward compatibility */
99 call &= 0xffff;
100
101 switch (call) {
102 case SEMOP:
103 return sys_semtimedop(first, (struct sembuf __user *) ptr,
104 second, NULL);
105 case SEMTIMEDOP:
106 return sys_semtimedop(first, (struct sembuf __user *) ptr,
107 second,
108 (const struct timespec __user *) fifth);
109 case SEMGET:
110 return sys_semget (first, second, third);
111 case SEMCTL: {
112 union semun fourth;
113 if (!ptr)
114 return -EINVAL;
115 if (get_user(fourth.__pad, (void __user * __user *) ptr))
116 return -EFAULT;
117 return sys_semctl (first, second, third, fourth);
118 }
119
120 case MSGSND:
121 return sys_msgsnd (first, (struct msgbuf *) ptr,
122 second, third);
123 case MSGRCV:
124 switch (version) {
125 case 0: {
126 struct ipc_kludge tmp;
127 if (!ptr)
128 return -EINVAL;
129
130 if (copy_from_user(&tmp,
131 (struct ipc_kludge *) ptr,
132 sizeof (tmp)))
133 return -EFAULT;
134 return sys_msgrcv (first, tmp.msgp, second,
135 tmp.msgtyp, third);
136 }
137 default:
138 panic("msgrcv with version != 0");
139 return sys_msgrcv (first,
140 (struct msgbuf *) ptr,
141 second, fifth, third);
142 }
143 case MSGGET:
144 return sys_msgget ((key_t) first, second);
145 case MSGCTL:
146 return sys_msgctl (first, second, (struct msqid_ds *) ptr);
147
148 case SHMAT:
149 switch (version) {
150 default: {
151 ulong raddr;
152 ret = do_shmat (first, (char *) ptr, second, &raddr);
153 if (ret)
154 return ret;
155 return put_user (raddr, (ulong *) third);
156 }
157 case 1: /* iBCS2 emulator entry point */
158 if (!segment_eq(get_fs(), get_ds()))
159 return -EINVAL;
160 return do_shmat (first, (char *) ptr, second, (ulong *) third);
161 }
162 case SHMDT:
163 return sys_shmdt ((char *)ptr);
164 case SHMGET:
165 return sys_shmget (first, second, third);
166 case SHMCTL:
167 return sys_shmctl (first, second,
168 (struct shmid_ds *) ptr);
169 default:
170 return -ENOSYS;
171 }
172}
173
174long sys_sigaction(int sig, const struct old_sigaction __user *act, 37long sys_sigaction(int sig, const struct old_sigaction __user *act,
175 struct old_sigaction __user *oact) 38 struct old_sigaction __user *oact)
176{ 39{