diff options
author | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
---|---|---|
committer | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
commit | ada47b5fe13d89735805b566185f4885f5a3f750 (patch) | |
tree | 644b88f8a71896307d71438e9b3af49126ffb22b /arch/um/sys-i386 | |
parent | 43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff) | |
parent | 3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff) |
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'arch/um/sys-i386')
-rw-r--r-- | arch/um/sys-i386/Makefile | 2 | ||||
-rw-r--r-- | arch/um/sys-i386/asm/elf.h | 44 | ||||
-rw-r--r-- | arch/um/sys-i386/elfcore.c | 83 | ||||
-rw-r--r-- | arch/um/sys-i386/ldt.c | 1 | ||||
-rw-r--r-- | arch/um/sys-i386/shared/sysdep/syscalls.h | 6 | ||||
-rw-r--r-- | arch/um/sys-i386/sys_call_table.S | 2 | ||||
-rw-r--r-- | arch/um/sys-i386/syscalls.c | 137 |
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 | ||
9 | obj-$(CONFIG_BINFMT_ELF) += elfcore.o | ||
10 | |||
9 | subarch-obj-y = lib/semaphore_32.o lib/string_32.o | 11 | subarch-obj-y = lib/semaphore_32.o lib/string_32.o |
10 | subarch-obj-$(CONFIG_HIGHMEM) += mm/highmem_32.o | 12 | subarch-obj-$(CONFIG_HIGHMEM) += mm/highmem_32.o |
11 | subarch-obj-$(CONFIG_MODULES) += kernel/module.o | 13 | subarch-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 \ | ||
132 | if ( 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 \ | ||
151 | if ( 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 | |||
9 | Elf32_Half elf_core_extra_phdrs(void) | ||
10 | { | ||
11 | return vsyscall_ehdr ? (((struct elfhdr *)vsyscall_ehdr)->e_phnum) : 0; | ||
12 | } | ||
13 | |||
14 | int 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 | |||
44 | int 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 | |||
69 | size_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 | */ |
14 | extern syscall_handler_t sys_rt_sigaction; | 14 | extern syscall_handler_t sys_rt_sigaction; |
15 | 15 | ||
16 | extern syscall_handler_t old_mmap_i386; | ||
17 | |||
18 | extern syscall_handler_t *sys_call_table[]; | 16 | extern 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(®s->regs)) | 20 | (*sys_call_table[syscall]))(SYSCALL_ARGS(®s->regs)) |
23 | |||
24 | extern 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 | |||
21 | struct 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 | |||
30 | extern int old_mmap(unsigned long addr, unsigned long len, | ||
31 | unsigned long prot, unsigned long flags, | ||
32 | unsigned long fd, unsigned long offset); | ||
33 | |||
34 | long 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 | |||
47 | struct 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 | |||
55 | long 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 | */ | ||
93 | long 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 | |||
174 | long sys_sigaction(int sig, const struct old_sigaction __user *act, | 37 | long sys_sigaction(int sig, const struct old_sigaction __user *act, |
175 | struct old_sigaction __user *oact) | 38 | struct old_sigaction __user *oact) |
176 | { | 39 | { |