aboutsummaryrefslogtreecommitdiffstats
path: root/arch/um/os-Linux
diff options
context:
space:
mode:
Diffstat (limited to 'arch/um/os-Linux')
-rw-r--r--arch/um/os-Linux/Makefile4
-rw-r--r--arch/um/os-Linux/elf_aux.c7
-rw-r--r--arch/um/os-Linux/helper.c4
-rw-r--r--arch/um/os-Linux/main.c4
-rw-r--r--arch/um/os-Linux/mem.c6
-rw-r--r--arch/um/os-Linux/registers.c9
-rw-r--r--arch/um/os-Linux/skas/mem.c2
-rw-r--r--arch/um/os-Linux/skas/process.c19
-rw-r--r--arch/um/os-Linux/user_syms.c5
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
6obj-y = aio.o elf_aux.o execvp.o file.o helper.o irq.o main.o mem.o process.o \ 6obj-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
10obj-$(CONFIG_ARCH_REUSE_HOST_VSYSCALL_AREA) += elf_aux.o
11
10USER_OBJS := $(user-objs-y) aio.o elf_aux.o execvp.o file.o helper.o irq.o \ 12USER_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
19typedef Elf32_auxv_t elf_auxv_t; 17typedef Elf32_auxv_t elf_auxv_t;
20#else
21typedef 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 */
25char * elf_aux_platform; 20char * elf_aux_platform;
26long elf_aux_hwcap; 21extern long elf_aux_hwcap;
27unsigned long vsyscall_ehdr; 22unsigned long vsyscall_ehdr;
28unsigned long vsyscall_end; 23unsigned long vsyscall_end;
29unsigned long __kernel_vsyscall; 24unsigned 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
24long elf_aux_hwcap;
25
24static void set_stklim(void) 26static 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;
201close:
202 close(fd);
201out: 203out:
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
12int save_registers(int pid, struct uml_pt_regs *regs) 14int 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
34static unsigned long exec_regs[MAX_REG_NR]; 36static unsigned long exec_regs[MAX_REG_NR];
37static unsigned long exec_fp_regs[FP_SIZE];
35 38
36int init_registers(int pid) 39int 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
48void get_safe_registers(unsigned long *regs) 52void 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
40static int __init init_syscall_regs(void) 40static 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
459static unsigned long thread_regs[MAX_REG_NR]; 468static unsigned long thread_regs[MAX_REG_NR];
469static unsigned long thread_fp_regs[FP_SIZE];
460 470
461static int __init init_thread_regs(void) 471static 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
114extern long __guard __attribute__((weak)); 114extern long __guard __attribute__((weak));
115EXPORT_SYMBOL(__guard); 115EXPORT_SYMBOL(__guard);
116
117#ifdef _FORTIFY_SOURCE
118extern int __sprintf_chk(char *str, int flag, size_t strlen, const char *format);
119EXPORT_SYMBOL(__sprintf_chk);
120#endif