diff options
-rw-r--r-- | arch/um/os-Linux/signal.c | 6 | ||||
-rw-r--r-- | arch/um/os-Linux/sys-x86/Makefile | 2 | ||||
-rw-r--r-- | arch/um/os-Linux/sys-x86/mcontext.c | 31 | ||||
-rw-r--r-- | arch/um/sys-x86/shared/sysdep/mcontext.h | 31 | ||||
-rw-r--r-- | arch/um/sys-x86/shared/sysdep/sigcontext.h | 5 | ||||
-rw-r--r-- | arch/um/sys-x86/shared/sysdep/sigcontext_32.h | 32 | ||||
-rw-r--r-- | arch/um/sys-x86/shared/sysdep/sigcontext_64.h | 32 | ||||
-rw-r--r-- | arch/um/sys-x86/stub_segv.c | 2 | ||||
-rw-r--r-- | arch/um/sys-x86/user-offsets.c | 7 |
9 files changed, 67 insertions, 81 deletions
diff --git a/arch/um/os-Linux/signal.c b/arch/um/os-Linux/signal.c index 07d9905e44e..9f2c2228f7a 100644 --- a/arch/um/os-Linux/signal.c +++ b/arch/um/os-Linux/signal.c @@ -14,7 +14,7 @@ #include "os.h" #include "process.h" #include "sysdep/barrier.h" -#include "sysdep/sigcontext.h" +#include "sysdep/mcontext.h" void (*sig_info[NSIG])(int, struct uml_pt_regs *) = { [SIGTRAP] = relay_signal, @@ -34,7 +34,7 @@ static void sig_handler_common(int sig, mcontext_t *mc) r.is_user = 0; if (sig == SIGSEGV) { /* For segfaults, we want the data from the sigcontext. */ - copy_sc(&r, (struct sigcontext *)mc); + get_regs_from_mc(&r, mc); GET_FAULTINFO_FROM_MC(r.faultinfo, mc); } @@ -84,7 +84,7 @@ static void real_alarm_handler(mcontext_t *mc) struct uml_pt_regs regs; if (mc != NULL) - copy_sc(®s, (struct sigcontext *)mc); + get_regs_from_mc(®s, mc); regs.is_user = 0; unblock_signals(); timer_handler(SIGVTALRM, ®s); diff --git a/arch/um/os-Linux/sys-x86/Makefile b/arch/um/os-Linux/sys-x86/Makefile index 22cc5073c02..253bfb8cb70 100644 --- a/arch/um/os-Linux/sys-x86/Makefile +++ b/arch/um/os-Linux/sys-x86/Makefile @@ -3,7 +3,7 @@ # Licensed under the GPL # -obj-y = registers.o task_size.o +obj-y = registers.o task_size.o mcontext.o obj-$(CONFIG_X86_32) += tls.o obj-$(CONFIG_64BIT) += prctl.o diff --git a/arch/um/os-Linux/sys-x86/mcontext.c b/arch/um/os-Linux/sys-x86/mcontext.c new file mode 100644 index 00000000000..1d33d72c628 --- /dev/null +++ b/arch/um/os-Linux/sys-x86/mcontext.c @@ -0,0 +1,31 @@ +#include <sys/ucontext.h> +#define __FRAME_OFFSETS +#include <asm/ptrace.h> +#include <sysdep/ptrace.h> + +void get_regs_from_mc(struct uml_pt_regs *regs, mcontext_t *mc) +{ +#ifdef __i386__ +#define COPY2(X,Y) regs->gp[X] = mc->gregs[REG_##Y] +#define COPY(X) regs->gp[X] = mc->gregs[REG_##X] +#define COPY_SEG(X) regs->gp[X] = mc->gregs[REG_##X] & 0xffff; +#define COPY_SEG_CPL3(X) regs->gp[X] = (mc->gregs[REG_##X] & 0xffff) | 3; + COPY_SEG(GS); COPY_SEG(FS); COPY_SEG(ES); COPY_SEG(DS); + COPY(EDI); COPY(ESI); COPY(EBP); + COPY2(UESP, ESP); /* sic */ + COPY(EBX); COPY(EDX); COPY(ECX); COPY(EAX); + COPY(EIP); COPY_SEG_CPL3(CS); COPY(EFL); COPY_SEG_CPL3(SS); +#else +#define COPY2(X,Y) regs->gp[X/sizeof(unsigned long)] = mc->gregs[REG_##Y] +#define COPY(X) regs->gp[X/sizeof(unsigned long)] = mc->gregs[REG_##X] + COPY(R8); COPY(R9); COPY(R10); COPY(R11); + COPY(R12); COPY(R13); COPY(R14); COPY(R15); + COPY(RDI); COPY(RSI); COPY(RBP); COPY(RBX); + COPY(RDX); COPY(RAX); COPY(RCX); COPY(RSP); + COPY(RIP); + COPY2(EFLAGS, EFL); + COPY2(CS, CSGSFS); + regs->gp[CS / sizeof(unsigned long)] &= 0xffff; + regs->gp[CS / sizeof(unsigned long)] |= 3; +#endif +} diff --git a/arch/um/sys-x86/shared/sysdep/mcontext.h b/arch/um/sys-x86/shared/sysdep/mcontext.h new file mode 100644 index 00000000000..b724c54da31 --- /dev/null +++ b/arch/um/sys-x86/shared/sysdep/mcontext.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) + * Licensed under the GPL + */ + +#ifndef __SYS_SIGCONTEXT_X86_H +#define __SYS_SIGCONTEXT_X86_H + +extern void get_regs_from_mc(struct uml_pt_regs *, mcontext_t *); + +#ifdef __i386__ + +#define GET_FAULTINFO_FROM_MC(fi, mc) \ + { \ + (fi).cr2 = (mc)->cr2; \ + (fi).error_code = (mc)->gregs[REG_ERR]; \ + (fi).trap_no = (mc)->gregs[REG_TRAPNO]; \ + } + +#else + +#define GET_FAULTINFO_FROM_MC(fi, mc) \ + { \ + (fi).cr2 = (mc)->gregs[REG_CR2]; \ + (fi).error_code = (mc)->gregs[REG_ERR]; \ + (fi).trap_no = (mc)->gregs[REG_TRAPNO]; \ + } + +#endif + +#endif diff --git a/arch/um/sys-x86/shared/sysdep/sigcontext.h b/arch/um/sys-x86/shared/sysdep/sigcontext.h deleted file mode 100644 index f7f49f46c23..00000000000 --- a/arch/um/sys-x86/shared/sysdep/sigcontext.h +++ /dev/null @@ -1,5 +0,0 @@ -#ifdef __i386__ -#include "sigcontext_32.h" -#else -#include "sigcontext_64.h" -#endif diff --git a/arch/um/sys-x86/shared/sysdep/sigcontext_32.h b/arch/um/sys-x86/shared/sysdep/sigcontext_32.h deleted file mode 100644 index 548c3cdb743..00000000000 --- a/arch/um/sys-x86/shared/sysdep/sigcontext_32.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) - * Licensed under the GPL - */ - -#ifndef __SYS_SIGCONTEXT_I386_H -#define __SYS_SIGCONTEXT_I386_H - -#include <generated/user_constants.h> - -#define SC_OFFSET(sc, field) \ - *((unsigned long *) &(((char *) (sc))[HOST_##field])) - -#define SC_TRAPNO(sc) SC_OFFSET(sc, SC_TRAPNO) -#define SC_ERR(sc) SC_OFFSET(sc, SC_ERR) -#define SC_CR2(sc) SC_OFFSET(sc, SC_CR2) - -#define GET_FAULTINFO_FROM_SC(fi, sc) \ - { \ - (fi).cr2 = SC_CR2(sc); \ - (fi).error_code = SC_ERR(sc); \ - (fi).trap_no = SC_TRAPNO(sc); \ - } - -#define GET_FAULTINFO_FROM_MC(fi, mc) \ - { \ - (fi).cr2 = (mc)->cr2; \ - (fi).error_code = (mc)->gregs[REG_ERR]; \ - (fi).trap_no = (mc)->gregs[REG_TRAPNO]; \ - } - -#endif diff --git a/arch/um/sys-x86/shared/sysdep/sigcontext_64.h b/arch/um/sys-x86/shared/sysdep/sigcontext_64.h deleted file mode 100644 index 5c4a6a35914..00000000000 --- a/arch/um/sys-x86/shared/sysdep/sigcontext_64.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright 2003 PathScale, Inc. - * - * Licensed under the GPL - */ - -#ifndef __SYSDEP_X86_64_SIGCONTEXT_H -#define __SYSDEP_X86_64_SIGCONTEXT_H - -#include <generated/user_constants.h> - -#define SC_OFFSET(sc, field) \ - *((unsigned long *) &(((char *) (sc))[HOST_##field])) -#define SC_CR2(sc) SC_OFFSET(sc, SC_CR2) -#define SC_ERR(sc) SC_OFFSET(sc, SC_ERR) -#define SC_TRAPNO(sc) SC_OFFSET(sc, SC_TRAPNO) - -#define GET_FAULTINFO_FROM_SC(fi, sc) \ - { \ - (fi).cr2 = SC_CR2(sc); \ - (fi).error_code = SC_ERR(sc); \ - (fi).trap_no = SC_TRAPNO(sc); \ - } - -#define GET_FAULTINFO_FROM_MC(fi, mc) \ - { \ - (fi).cr2 = (mc)->gregs[REG_CR2]; \ - (fi).error_code = (mc)->gregs[REG_ERR]; \ - (fi).trap_no = (mc)->gregs[REG_TRAPNO]; \ - } - -#endif diff --git a/arch/um/sys-x86/stub_segv.c b/arch/um/sys-x86/stub_segv.c index bd2eaf69103..b7450bd22e7 100644 --- a/arch/um/sys-x86/stub_segv.c +++ b/arch/um/sys-x86/stub_segv.c @@ -5,7 +5,7 @@ #include "sysdep/stub.h" #include "sysdep/faultinfo.h" -#include "sysdep/sigcontext.h" +#include "sysdep/mcontext.h" void __attribute__ ((__section__ (".__syscall_stub"))) stub_segv_handler(int sig, siginfo_t *info, void *p) diff --git a/arch/um/sys-x86/user-offsets.c b/arch/um/sys-x86/user-offsets.c index 718f0c0f0b0..3c19c48a1d4 100644 --- a/arch/um/sys-x86/user-offsets.c +++ b/arch/um/sys-x86/user-offsets.c @@ -14,15 +14,8 @@ #define DEFINE_LONGS(sym, val) \ asm volatile("\n->" #sym " %0 " #val : : "i" (val/sizeof(unsigned long))) -#define OFFSET(sym, str, mem) \ - DEFINE(sym, offsetof(struct str, mem)); - void foo(void) { - OFFSET(HOST_SC_TRAPNO, sigcontext, trapno); - OFFSET(HOST_SC_ERR, sigcontext, err); - OFFSET(HOST_SC_CR2, sigcontext, cr2); - #ifdef __i386__ DEFINE_LONGS(HOST_FP_SIZE, sizeof(struct user_fpregs_struct)); DEFINE_LONGS(HOST_FPX_SIZE, sizeof(struct user_fpxregs_struct)); |