diff --git a/arch/um/os-Linux/signal.c b/arch/um/os-Linux/signal.c index 07d9905e44ef0184682097417e72dbf100c7c25b..9f2c2228f7ae349cf3ec66d0f81af5d170a04996 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 22cc5073c020e7e98161489339eb80b792de020c..253bfb8cb702da1d30e10b1c3e36ff5a7e90926c 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 0000000000000000000000000000000000000000..1d33d72c6284d73e0078fd3ba7c38bee07f207db --- /dev/null +++ b/arch/um/os-Linux/sys-x86/mcontext.c @@ -0,0 +1,31 @@ +#include +#define __FRAME_OFFSETS +#include +#include + +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 0000000000000000000000000000000000000000..b724c54da316012bdc7cd6642b74bab0f6b9223a --- /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 f7f49f46c23d1a2b970f1341bfd9d114df8e0b69..0000000000000000000000000000000000000000 --- 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 548c3cdb743b637aab1e1a1ca545a5a1e68eca62..0000000000000000000000000000000000000000 --- 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 - -#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 5c4a6a359141a2b7f94080cf6acc3724a67b106b..0000000000000000000000000000000000000000 --- 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 - -#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 bd2eaf69103f90f14770dacaff4a2686c603c694..b7450bd22e7d1dae1c2f4d4d77f4ed53a636e5b6 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 718f0c0f0b0c231011e7efb014ca3471f3289830..3c19c48a1d4869dd348f948da15bcfd273cf54fb 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));