diff options
Diffstat (limited to 'arch/um/os-Linux')
-rw-r--r-- | arch/um/os-Linux/Makefile | 4 | ||||
-rw-r--r-- | arch/um/os-Linux/elf_aux.c | 7 | ||||
-rw-r--r-- | arch/um/os-Linux/helper.c | 4 | ||||
-rw-r--r-- | arch/um/os-Linux/main.c | 4 | ||||
-rw-r--r-- | arch/um/os-Linux/mem.c | 6 | ||||
-rw-r--r-- | arch/um/os-Linux/registers.c | 9 | ||||
-rw-r--r-- | arch/um/os-Linux/skas/mem.c | 2 | ||||
-rw-r--r-- | arch/um/os-Linux/skas/process.c | 19 | ||||
-rw-r--r-- | arch/um/os-Linux/user_syms.c | 5 |
9 files changed, 46 insertions, 14 deletions
diff --git a/arch/um/os-Linux/Makefile b/arch/um/os-Linux/Makefile index d66f0388f09..b33f4dfe7ae 100644 --- a/arch/um/os-Linux/Makefile +++ b/arch/um/os-Linux/Makefile | |||
@@ -3,10 +3,12 @@ | |||
3 | # Licensed under the GPL | 3 | # Licensed under the GPL |
4 | # | 4 | # |
5 | 5 | ||
6 | obj-y = aio.o elf_aux.o execvp.o file.o helper.o irq.o main.o mem.o process.o \ | 6 | obj-y = aio.o execvp.o file.o helper.o irq.o main.o mem.o process.o \ |
7 | registers.o sigio.o signal.o start_up.o time.o tty.o uaccess.o \ | 7 | registers.o sigio.o signal.o start_up.o time.o tty.o uaccess.o \ |
8 | umid.o tls.o user_syms.o util.o drivers/ sys-$(SUBARCH)/ skas/ | 8 | umid.o tls.o user_syms.o util.o drivers/ sys-$(SUBARCH)/ skas/ |
9 | 9 | ||
10 | obj-$(CONFIG_ARCH_REUSE_HOST_VSYSCALL_AREA) += elf_aux.o | ||
11 | |||
10 | USER_OBJS := $(user-objs-y) aio.o elf_aux.o execvp.o file.o helper.o irq.o \ | 12 | USER_OBJS := $(user-objs-y) aio.o elf_aux.o execvp.o file.o helper.o irq.o \ |
11 | main.o mem.o process.o registers.o sigio.o signal.o start_up.o time.o \ | 13 | main.o mem.o process.o registers.o sigio.o signal.o start_up.o time.o \ |
12 | tty.o tls.o uaccess.o umid.o util.o | 14 | tty.o tls.o uaccess.o umid.o util.o |
diff --git a/arch/um/os-Linux/elf_aux.c b/arch/um/os-Linux/elf_aux.c index 608784d4ec5..95332379938 100644 --- a/arch/um/os-Linux/elf_aux.c +++ b/arch/um/os-Linux/elf_aux.c | |||
@@ -14,16 +14,11 @@ | |||
14 | #include "mem_user.h" | 14 | #include "mem_user.h" |
15 | #include <kern_constants.h> | 15 | #include <kern_constants.h> |
16 | 16 | ||
17 | /* Use the one from the kernel - the host may miss it, if having old headers. */ | ||
18 | #if UM_ELF_CLASS == UM_ELFCLASS32 | ||
19 | typedef Elf32_auxv_t elf_auxv_t; | 17 | typedef Elf32_auxv_t elf_auxv_t; |
20 | #else | ||
21 | typedef Elf64_auxv_t elf_auxv_t; | ||
22 | #endif | ||
23 | 18 | ||
24 | /* These are initialized very early in boot and never changed */ | 19 | /* These are initialized very early in boot and never changed */ |
25 | char * elf_aux_platform; | 20 | char * elf_aux_platform; |
26 | long elf_aux_hwcap; | 21 | extern long elf_aux_hwcap; |
27 | unsigned long vsyscall_ehdr; | 22 | unsigned long vsyscall_ehdr; |
28 | unsigned long vsyscall_end; | 23 | unsigned long vsyscall_end; |
29 | unsigned long __kernel_vsyscall; | 24 | unsigned long __kernel_vsyscall; |
diff --git a/arch/um/os-Linux/helper.c b/arch/um/os-Linux/helper.c index b6b1096152a..feff22d6467 100644 --- a/arch/um/os-Linux/helper.c +++ b/arch/um/os-Linux/helper.c | |||
@@ -28,14 +28,14 @@ static int helper_child(void *arg) | |||
28 | { | 28 | { |
29 | struct helper_data *data = arg; | 29 | struct helper_data *data = arg; |
30 | char **argv = data->argv; | 30 | char **argv = data->argv; |
31 | int err; | 31 | int err, ret; |
32 | 32 | ||
33 | if (data->pre_exec != NULL) | 33 | if (data->pre_exec != NULL) |
34 | (*data->pre_exec)(data->pre_data); | 34 | (*data->pre_exec)(data->pre_data); |
35 | err = execvp_noalloc(data->buf, argv[0], argv); | 35 | err = execvp_noalloc(data->buf, argv[0], argv); |
36 | 36 | ||
37 | /* If the exec succeeds, we don't get here */ | 37 | /* If the exec succeeds, we don't get here */ |
38 | write(data->fd, &err, sizeof(err)); | 38 | CATCH_EINTR(ret = write(data->fd, &err, sizeof(err))); |
39 | 39 | ||
40 | return 0; | 40 | return 0; |
41 | } | 41 | } |
diff --git a/arch/um/os-Linux/main.c b/arch/um/os-Linux/main.c index fb2a97a75fb..8471b817d94 100644 --- a/arch/um/os-Linux/main.c +++ b/arch/um/os-Linux/main.c | |||
@@ -21,6 +21,8 @@ | |||
21 | #define STACKSIZE (8 * 1024 * 1024) | 21 | #define STACKSIZE (8 * 1024 * 1024) |
22 | #define THREAD_NAME_LEN (256) | 22 | #define THREAD_NAME_LEN (256) |
23 | 23 | ||
24 | long elf_aux_hwcap; | ||
25 | |||
24 | static void set_stklim(void) | 26 | static void set_stklim(void) |
25 | { | 27 | { |
26 | struct rlimit lim; | 28 | struct rlimit lim; |
@@ -143,7 +145,9 @@ int __init main(int argc, char **argv, char **envp) | |||
143 | install_fatal_handler(SIGINT); | 145 | install_fatal_handler(SIGINT); |
144 | install_fatal_handler(SIGTERM); | 146 | install_fatal_handler(SIGTERM); |
145 | 147 | ||
148 | #ifdef CONFIG_ARCH_REUSE_HOST_VSYSCALL_AREA | ||
146 | scan_elf_aux(envp); | 149 | scan_elf_aux(envp); |
150 | #endif | ||
147 | 151 | ||
148 | do_uml_initcalls(); | 152 | do_uml_initcalls(); |
149 | ret = linux_main(argc, argv); | 153 | ret = linux_main(argc, argv); |
diff --git a/arch/um/os-Linux/mem.c b/arch/um/os-Linux/mem.c index e696144d2be..62878cf1d33 100644 --- a/arch/um/os-Linux/mem.c +++ b/arch/um/os-Linux/mem.c | |||
@@ -176,7 +176,7 @@ static int __init make_tempfile(const char *template, char **out_tempname, | |||
176 | 176 | ||
177 | find_tempdir(); | 177 | find_tempdir(); |
178 | if ((tempdir == NULL) || (strlen(tempdir) >= MAXPATHLEN)) | 178 | if ((tempdir == NULL) || (strlen(tempdir) >= MAXPATHLEN)) |
179 | return -1; | 179 | goto out; |
180 | 180 | ||
181 | if (template[0] != '/') | 181 | if (template[0] != '/') |
182 | strcpy(tempname, tempdir); | 182 | strcpy(tempname, tempdir); |
@@ -191,13 +191,15 @@ static int __init make_tempfile(const char *template, char **out_tempname, | |||
191 | } | 191 | } |
192 | if (do_unlink && (unlink(tempname) < 0)) { | 192 | if (do_unlink && (unlink(tempname) < 0)) { |
193 | perror("unlink"); | 193 | perror("unlink"); |
194 | goto out; | 194 | goto close; |
195 | } | 195 | } |
196 | if (out_tempname) { | 196 | if (out_tempname) { |
197 | *out_tempname = tempname; | 197 | *out_tempname = tempname; |
198 | } else | 198 | } else |
199 | free(tempname); | 199 | free(tempname); |
200 | return fd; | 200 | return fd; |
201 | close: | ||
202 | close(fd); | ||
201 | out: | 203 | out: |
202 | free(tempname); | 204 | free(tempname); |
203 | return -1; | 205 | return -1; |
diff --git a/arch/um/os-Linux/registers.c b/arch/um/os-Linux/registers.c index 830fe6a1518..b866b9e3bef 100644 --- a/arch/um/os-Linux/registers.c +++ b/arch/um/os-Linux/registers.c | |||
@@ -8,6 +8,8 @@ | |||
8 | #include <string.h> | 8 | #include <string.h> |
9 | #include <sys/ptrace.h> | 9 | #include <sys/ptrace.h> |
10 | #include "sysdep/ptrace.h" | 10 | #include "sysdep/ptrace.h" |
11 | #include "sysdep/ptrace_user.h" | ||
12 | #include "registers.h" | ||
11 | 13 | ||
12 | int save_registers(int pid, struct uml_pt_regs *regs) | 14 | int save_registers(int pid, struct uml_pt_regs *regs) |
13 | { | 15 | { |
@@ -32,6 +34,7 @@ int restore_registers(int pid, struct uml_pt_regs *regs) | |||
32 | /* This is set once at boot time and not changed thereafter */ | 34 | /* This is set once at boot time and not changed thereafter */ |
33 | 35 | ||
34 | static unsigned long exec_regs[MAX_REG_NR]; | 36 | static unsigned long exec_regs[MAX_REG_NR]; |
37 | static unsigned long exec_fp_regs[FP_SIZE]; | ||
35 | 38 | ||
36 | int init_registers(int pid) | 39 | int init_registers(int pid) |
37 | { | 40 | { |
@@ -42,10 +45,14 @@ int init_registers(int pid) | |||
42 | return -errno; | 45 | return -errno; |
43 | 46 | ||
44 | arch_init_registers(pid); | 47 | arch_init_registers(pid); |
48 | get_fp_registers(pid, exec_fp_regs); | ||
45 | return 0; | 49 | return 0; |
46 | } | 50 | } |
47 | 51 | ||
48 | void get_safe_registers(unsigned long *regs) | 52 | void get_safe_registers(unsigned long *regs, unsigned long *fp_regs) |
49 | { | 53 | { |
50 | memcpy(regs, exec_regs, sizeof(exec_regs)); | 54 | memcpy(regs, exec_regs, sizeof(exec_regs)); |
55 | |||
56 | if (fp_regs) | ||
57 | memcpy(fp_regs, exec_fp_regs, sizeof(exec_fp_regs)); | ||
51 | } | 58 | } |
diff --git a/arch/um/os-Linux/skas/mem.c b/arch/um/os-Linux/skas/mem.c index d261f170d12..e771398be5f 100644 --- a/arch/um/os-Linux/skas/mem.c +++ b/arch/um/os-Linux/skas/mem.c | |||
@@ -39,7 +39,7 @@ static unsigned long syscall_regs[MAX_REG_NR]; | |||
39 | 39 | ||
40 | static int __init init_syscall_regs(void) | 40 | static int __init init_syscall_regs(void) |
41 | { | 41 | { |
42 | get_safe_registers(syscall_regs); | 42 | get_safe_registers(syscall_regs, NULL); |
43 | syscall_regs[REGS_IP_INDEX] = STUB_CODE + | 43 | syscall_regs[REGS_IP_INDEX] = STUB_CODE + |
44 | ((unsigned long) &batch_syscall_stub - | 44 | ((unsigned long) &batch_syscall_stub - |
45 | (unsigned long) &__syscall_stub_start); | 45 | (unsigned long) &__syscall_stub_start); |
diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c index d6e0a2234b8..dee0e8cf8ad 100644 --- a/arch/um/os-Linux/skas/process.c +++ b/arch/um/os-Linux/skas/process.c | |||
@@ -373,6 +373,9 @@ void userspace(struct uml_pt_regs *regs) | |||
373 | if (ptrace(PTRACE_SETREGS, pid, 0, regs->gp)) | 373 | if (ptrace(PTRACE_SETREGS, pid, 0, regs->gp)) |
374 | fatal_sigsegv(); | 374 | fatal_sigsegv(); |
375 | 375 | ||
376 | if (put_fp_registers(pid, regs->fp)) | ||
377 | fatal_sigsegv(); | ||
378 | |||
376 | /* Now we set local_using_sysemu to be used for one loop */ | 379 | /* Now we set local_using_sysemu to be used for one loop */ |
377 | local_using_sysemu = get_using_sysemu(); | 380 | local_using_sysemu = get_using_sysemu(); |
378 | 381 | ||
@@ -399,6 +402,12 @@ void userspace(struct uml_pt_regs *regs) | |||
399 | fatal_sigsegv(); | 402 | fatal_sigsegv(); |
400 | } | 403 | } |
401 | 404 | ||
405 | if (get_fp_registers(pid, regs->fp)) { | ||
406 | printk(UM_KERN_ERR "userspace - get_fp_registers failed, " | ||
407 | "errno = %d\n", errno); | ||
408 | fatal_sigsegv(); | ||
409 | } | ||
410 | |||
402 | UPT_SYSCALL_NR(regs) = -1; /* Assume: It's not a syscall */ | 411 | UPT_SYSCALL_NR(regs) = -1; /* Assume: It's not a syscall */ |
403 | 412 | ||
404 | if (WIFSTOPPED(status)) { | 413 | if (WIFSTOPPED(status)) { |
@@ -457,10 +466,11 @@ void userspace(struct uml_pt_regs *regs) | |||
457 | } | 466 | } |
458 | 467 | ||
459 | static unsigned long thread_regs[MAX_REG_NR]; | 468 | static unsigned long thread_regs[MAX_REG_NR]; |
469 | static unsigned long thread_fp_regs[FP_SIZE]; | ||
460 | 470 | ||
461 | static int __init init_thread_regs(void) | 471 | static int __init init_thread_regs(void) |
462 | { | 472 | { |
463 | get_safe_registers(thread_regs); | 473 | get_safe_registers(thread_regs, thread_fp_regs); |
464 | /* Set parent's instruction pointer to start of clone-stub */ | 474 | /* Set parent's instruction pointer to start of clone-stub */ |
465 | thread_regs[REGS_IP_INDEX] = STUB_CODE + | 475 | thread_regs[REGS_IP_INDEX] = STUB_CODE + |
466 | (unsigned long) stub_clone_handler - | 476 | (unsigned long) stub_clone_handler - |
@@ -503,6 +513,13 @@ int copy_context_skas0(unsigned long new_stack, int pid) | |||
503 | return err; | 513 | return err; |
504 | } | 514 | } |
505 | 515 | ||
516 | err = put_fp_registers(pid, thread_fp_regs); | ||
517 | if (err < 0) { | ||
518 | printk(UM_KERN_ERR "copy_context_skas0 : put_fp_registers " | ||
519 | "failed, pid = %d, err = %d\n", pid, err); | ||
520 | return err; | ||
521 | } | ||
522 | |||
506 | /* set a well known return code for detection of child write failure */ | 523 | /* set a well known return code for detection of child write failure */ |
507 | child_data->err = 12345678; | 524 | child_data->err = 12345678; |
508 | 525 | ||
diff --git a/arch/um/os-Linux/user_syms.c b/arch/um/os-Linux/user_syms.c index 05f5ea8e83d..45ffe46871e 100644 --- a/arch/um/os-Linux/user_syms.c +++ b/arch/um/os-Linux/user_syms.c | |||
@@ -113,3 +113,8 @@ EXPORT_SYMBOL(__stack_smash_handler); | |||
113 | 113 | ||
114 | extern long __guard __attribute__((weak)); | 114 | extern long __guard __attribute__((weak)); |
115 | EXPORT_SYMBOL(__guard); | 115 | EXPORT_SYMBOL(__guard); |
116 | |||
117 | #ifdef _FORTIFY_SOURCE | ||
118 | extern int __sprintf_chk(char *str, int flag, size_t strlen, const char *format); | ||
119 | EXPORT_SYMBOL(__sprintf_chk); | ||
120 | #endif | ||