Commit eccc45bf authored by Jeff Dike's avatar Jeff Dike

Applied the sigcontext changes in the skas code.

parent 8133aaa1
...@@ -9,8 +9,6 @@ ...@@ -9,8 +9,6 @@
#include "sysdep/sigcontext.h" #include "sysdep/sigcontext.h"
extern int sc_size(void *data); extern int sc_size(void *data);
extern int copy_sc_to_user(void *to_ptr, void *from_ptr, void *data);
extern int copy_sc_from_user(void *to_ptr, void *from_ptr, void *data);
extern void sc_to_sc(void *to_ptr, void *from_ptr); extern void sc_to_sc(void *to_ptr, void *from_ptr);
#endif #endif
......
...@@ -9,6 +9,8 @@ ...@@ -9,6 +9,8 @@
#include "frame_kern.h" #include "frame_kern.h"
#include "sigcontext.h" #include "sigcontext.h"
#include "sysdep/ptrace.h" #include "sysdep/ptrace.h"
#include "choose-mode.h"
#include "mode.h"
static int copy_restorer(void (*restorer)(void), unsigned long start, static int copy_restorer(void (*restorer)(void), unsigned long start,
unsigned long sr_index, int sr_relative) unsigned long sr_index, int sr_relative)
...@@ -25,6 +27,15 @@ static int copy_restorer(void (*restorer)(void), unsigned long start, ...@@ -25,6 +27,15 @@ static int copy_restorer(void (*restorer)(void), unsigned long start,
sizeof(restorer))); sizeof(restorer)));
} }
static int copy_sc_to_user(void *to, struct pt_regs *from)
{
return(CHOOSE_MODE(copy_sc_to_user_tt(to, from->regs.mode.tt,
&signal_frame_sc_sr.arch),
copy_sc_to_user_skas(to, &from->regs,
current->thread.cr2,
current->thread.err)));
}
int setup_signal_stack_si(unsigned long stack_top, int sig, int setup_signal_stack_si(unsigned long stack_top, int sig,
unsigned long handler, void (*restorer)(void), unsigned long handler, void (*restorer)(void),
struct pt_regs *regs, siginfo_t *info, struct pt_regs *regs, siginfo_t *info,
...@@ -43,8 +54,7 @@ int setup_signal_stack_si(unsigned long stack_top, int sig, ...@@ -43,8 +54,7 @@ int setup_signal_stack_si(unsigned long stack_top, int sig,
if(restorer == NULL) if(restorer == NULL)
panic("setup_signal_stack_si - no restorer"); panic("setup_signal_stack_si - no restorer");
if(copy_sc_to_user((void *) sc, regs->regs.mode.tt, if(copy_sc_to_user((void *) sc, regs) ||
&signal_frame_sc.arch) ||
copy_to_user((void *) start, signal_frame_si.common.data, copy_to_user((void *) start, signal_frame_si.common.data,
signal_frame_si.common.len) || signal_frame_si.common.len) ||
copy_to_user((void *) (start + signal_frame_si.common.sig_index), copy_to_user((void *) (start + signal_frame_si.common.sig_index),
...@@ -86,8 +96,7 @@ int setup_signal_stack_sc(unsigned long stack_top, int sig, ...@@ -86,8 +96,7 @@ int setup_signal_stack_sc(unsigned long stack_top, int sig,
if(copy_to_user((void *) start, frame->data, frame->len) || if(copy_to_user((void *) start, frame->data, frame->len) ||
copy_to_user((void *) (start + frame->sig_index), &sig, copy_to_user((void *) (start + frame->sig_index), &sig,
sizeof(sig)) || sizeof(sig)) ||
copy_sc_to_user(user_sc, regs->regs.mode.tt, copy_sc_to_user(user_sc, regs) ||
&signal_frame_sc.arch) ||
copy_to_user(sc_sigmask(user_sc), mask, sizeof(mask->sig[0])) || copy_to_user(sc_sigmask(user_sc), mask, sizeof(mask->sig[0])) ||
copy_to_user((void *) sigs, &mask->sig[1], sig_size) || copy_to_user((void *) sigs, &mask->sig[1], sig_size) ||
copy_restorer(restorer, start, frame->sr_index, frame->sr_relative)) copy_restorer(restorer, start, frame->sr_index, frame->sr_relative))
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include "kern.h" #include "kern.h"
#include "frame_kern.h" #include "frame_kern.h"
#include "sigcontext.h" #include "sigcontext.h"
#include "mode.h"
EXPORT_SYMBOL(block_signals); EXPORT_SYMBOL(block_signals);
EXPORT_SYMBOL(unblock_signals); EXPORT_SYMBOL(unblock_signals);
...@@ -171,7 +172,7 @@ static int kern_do_signal(struct pt_regs *regs, sigset_t *oldset, int error) ...@@ -171,7 +172,7 @@ static int kern_do_signal(struct pt_regs *regs, sigset_t *oldset, int error)
*/ */
if((current->ptrace & PT_DTRACE) && if((current->ptrace & PT_DTRACE) &&
is_syscall(PT_REGS_IP(&current->thread.regs))) is_syscall(PT_REGS_IP(&current->thread.regs)))
current->thread.mode.tt.singlestep_syscall = 1; (void) CHOOSE_MODE(current->thread.mode.tt.singlestep_syscall = 1, 0);
return(0); return(0);
} }
...@@ -228,6 +229,16 @@ int sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize) ...@@ -228,6 +229,16 @@ int sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize)
} }
} }
static int copy_sc_from_user(struct pt_regs *to, void *from)
{
int ret;
ret = CHOOSE_MODE(copy_sc_from_user_tt(to->regs.mode.tt, from,
&signal_frame_sc.arch),
copy_sc_from_user_skas(&to->regs, from));
return(ret);
}
int sys_sigreturn(struct pt_regs regs) int sys_sigreturn(struct pt_regs regs)
{ {
void *sc = sp_to_sc(PT_REGS_SP(&regs)); void *sc = sp_to_sc(PT_REGS_SP(&regs));
...@@ -241,8 +252,7 @@ int sys_sigreturn(struct pt_regs regs) ...@@ -241,8 +252,7 @@ int sys_sigreturn(struct pt_regs regs)
sigdelsetmask(&current->blocked, ~_BLOCKABLE); sigdelsetmask(&current->blocked, ~_BLOCKABLE);
recalc_sigpending(); recalc_sigpending();
spin_unlock_irq(&current->sig->siglock); spin_unlock_irq(&current->sig->siglock);
copy_sc_from_user(current->thread.regs.regs.mode.tt, sc, copy_sc_from_user(current->thread.regs, sc);
&signal_frame_sc.arch);
return(PT_REGS_SYSCALL_RET(&current->thread.regs)); return(PT_REGS_SYSCALL_RET(&current->thread.regs));
} }
...@@ -257,8 +267,7 @@ int sys_rt_sigreturn(struct pt_regs regs) ...@@ -257,8 +267,7 @@ int sys_rt_sigreturn(struct pt_regs regs)
sigdelsetmask(&current->blocked, ~_BLOCKABLE); sigdelsetmask(&current->blocked, ~_BLOCKABLE);
recalc_sigpending(); recalc_sigpending();
spin_unlock_irq(&current->sig->siglock); spin_unlock_irq(&current->sig->siglock);
copy_sc_from_user(current->thread.regs.regs.mode.tt, sc, copy_sc_from_user(current->thread.regs, sc);
&signal_frame_sc.arch);
return(PT_REGS_SYSCALL_RET(&current->thread.regs)); return(PT_REGS_SYSCALL_RET(&current->thread.regs));
} }
......
...@@ -3,10 +3,10 @@ ...@@ -3,10 +3,10 @@
# Licensed under the GPL # Licensed under the GPL
# #
obj-y = exec_kern.o exec_user.o mem_user.o mmu.o process.o process_kern.o \ subdir-y = sys-$(SUBARCH)/
syscall_user.o trap_user.o
obj-y += $(join $(subdir-y),$(subdir-y:%=/%.o)) obj-y = exec_kern.o exec_user.o mem_user.o mmu.o process.o process_kern.o \
syscall_user.o trap_user.o $(subdir-y)
USER_OBJS = $(filter %_user.o,$(obj-y)) process.o time.o USER_OBJS = $(filter %_user.o,$(obj-y)) process.o time.o
USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file)) USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file))
......
#
# Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
# Licensed under the GPL
#
O_TARGET = sys-i386.o
obj-y = sigcontext.o
USER_OBJS = sigcontext.o
include $(TOPDIR)/Rules.make
$(USER_OBJS) : %.o: %.c
$(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $<
clean :
/*
* Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
* Licensed under the GPL
*/
#include <errno.h>
#include <asm/sigcontext.h>
#include <sys/ptrace.h>
#include <linux/ptrace.h>
#include "sysdep/ptrace.h"
#include "sysdep/ptrace_user.h"
#include "kern_util.h"
#include "user.h"
#include "sigcontext.h"
extern int userspace_pid;
int copy_sc_from_user_skas(struct uml_pt_regs *regs, void *from_ptr)
{
struct sigcontext sc, *from = from_ptr;
unsigned long fpregs[FP_FRAME_SIZE];
int err;
err = copy_from_user_proc(&sc, from, sizeof(sc));
err |= copy_from_user_proc(fpregs, sc.fpstate, sizeof(fpregs));
if(err)
return(err);
regs->mode.skas.regs[GS] = sc.gs;
regs->mode.skas.regs[FS] = sc.fs;
regs->mode.skas.regs[ES] = sc.es;
regs->mode.skas.regs[DS] = sc.ds;
regs->mode.skas.regs[EDI] = sc.edi;
regs->mode.skas.regs[ESI] = sc.esi;
regs->mode.skas.regs[EBP] = sc.ebp;
regs->mode.skas.regs[UESP] = sc.esp;
regs->mode.skas.regs[EBX] = sc.ebx;
regs->mode.skas.regs[EDX] = sc.edx;
regs->mode.skas.regs[ECX] = sc.ecx;
regs->mode.skas.regs[EAX] = sc.eax;
regs->mode.skas.regs[EIP] = sc.eip;
regs->mode.skas.regs[CS] = sc.cs;
regs->mode.skas.regs[EFL] = sc.eflags;
regs->mode.skas.regs[UESP] = sc.esp_at_signal;
regs->mode.skas.regs[SS] = sc.ss;
regs->mode.skas.fault_addr = sc.cr2;
regs->mode.skas.fault_type = FAULT_WRITE(sc.err);
regs->mode.skas.trap_type = sc.trapno;
err = ptrace(PTRACE_SETFPREGS, userspace_pid, 0, fpregs);
if(err < 0){
printk("copy_sc_to_user - PTRACE_SETFPREGS failed, "
"errno = %d\n", errno);
return(1);
}
return(0);
}
int copy_sc_to_user_skas(void *to_ptr, struct uml_pt_regs *regs,
unsigned long fault_addr, int fault_type)
{
struct sigcontext sc, *to = to_ptr;
struct _fpstate *to_fp;
unsigned long fpregs[FP_FRAME_SIZE];
int err;
sc.gs = regs->mode.skas.regs[GS];
sc.fs = regs->mode.skas.regs[FS];
sc.es = regs->mode.skas.regs[ES];
sc.ds = regs->mode.skas.regs[DS];
sc.edi = regs->mode.skas.regs[EDI];
sc.esi = regs->mode.skas.regs[ESI];
sc.ebp = regs->mode.skas.regs[EBP];
sc.esp = regs->mode.skas.regs[UESP];
sc.ebx = regs->mode.skas.regs[EBX];
sc.edx = regs->mode.skas.regs[EDX];
sc.ecx = regs->mode.skas.regs[ECX];
sc.eax = regs->mode.skas.regs[EAX];
sc.eip = regs->mode.skas.regs[EIP];
sc.cs = regs->mode.skas.regs[CS];
sc.eflags = regs->mode.skas.regs[EFL];
sc.esp_at_signal = regs->mode.skas.regs[UESP];
sc.ss = regs->mode.skas.regs[SS];
sc.cr2 = fault_addr;
sc.err = TO_SC_ERR(fault_type);
sc.trapno = regs->mode.skas.trap_type;
err = ptrace(PTRACE_GETFPREGS, userspace_pid, 0, fpregs);
if(err < 0){
printk("copy_sc_to_user - PTRACE_GETFPREGS failed, "
"errno = %d\n", errno);
return(1);
}
to_fp = (struct _fpstate *)((unsigned long) to + sizeof(*to));
sc.fpstate = to_fp;
if(err)
return(err);
return(copy_to_user_proc(to, &sc, sizeof(sc)) ||
copy_to_user_proc(to_fp, fpregs, sizeof(fpregs)));
}
/*
* Overrides for Emacs so that we follow Linus's tabbing style.
* Emacs will notice this stuff at the end of the file and automatically
* adjust the settings for this buffer only. This must remain at the end
* of the file.
* ---------------------------------------------------------------------------
* Local variables:
* c-file-style: "linux"
* End:
*/
...@@ -3,10 +3,13 @@ ...@@ -3,10 +3,13 @@
# Licensed under the GPL # Licensed under the GPL
# #
subdir-y = sys-$(SUBARCH)/
subdir-$(CONFIG_PT_PROXY) += ptproxy/
obj-y = exec_kern.o exec_user.o gdb.o gdb_kern.o mem.o process_kern.o \ obj-y = exec_kern.o exec_user.o gdb.o gdb_kern.o mem.o process_kern.o \
syscall_user.o tracer.o uaccess_user.o syscall_user.o tracer.o uaccess_user.o $(subdir-y)
obj-$(CONFIG_PT_PROXY) += ptproxy/
USER_OBJS := $(filter %_user.o,$(obj-y)) gdb.o tracer.o USER_OBJS := $(filter %_user.o,$(obj-y)) gdb.o tracer.o
USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file)) USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file))
......
#
# Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
# Licensed under the GPL
#
O_TARGET = sys-i386.o
obj-y = sigcontext.o
USER_OBJS = sigcontext.o
include $(TOPDIR)/Rules.make
$(USER_OBJS) : %.o: %.c
$(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $<
clean :
/*
* Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
* Licensed under the GPL
*/
#include <stdlib.h>
#include <asm/sigcontext.h>
#include "kern_util.h"
#include "sysdep/frame.h"
int copy_sc_from_user_tt(void *to_ptr, void *from_ptr, void *data)
{
struct arch_frame_data *arch = data;
struct sigcontext *to = to_ptr, *from = from_ptr;
struct _fpstate *to_fp, *from_fp;
unsigned long sigs;
int err;
to_fp = to->fpstate;
from_fp = from->fpstate;
sigs = to->oldmask;
err = copy_from_user_proc(to, from, sizeof(*to));
to->oldmask = sigs;
if(to_fp != NULL){
err |= copy_from_user_proc(&to->fpstate, &to_fp,
sizeof(to->fpstate));
err |= copy_from_user_proc(to_fp, from_fp, arch->fpstate_size);
}
return(err);
}
int copy_sc_to_user_tt(void *to_ptr, void *from_ptr, void *data)
{
struct arch_frame_data *arch = data;
struct sigcontext *to = to_ptr, *from = from_ptr;
struct _fpstate *to_fp, *from_fp;
int err;
to_fp = (struct _fpstate *)((unsigned long) to + sizeof(*to));
from_fp = from->fpstate;
err = copy_to_user_proc(to, from, sizeof(*to));
if(from_fp != NULL){
err |= copy_to_user_proc(&to->fpstate, &to_fp,
sizeof(to->fpstate));
err |= copy_to_user_proc(to_fp, from_fp, arch->fpstate_size);
}
return(err);
}
/*
* Overrides for Emacs so that we follow Linus's tabbing style.
* Emacs will notice this stuff at the end of the file and automatically
* adjust the settings for this buffer only. This must remain at the end
* of the file.
* ---------------------------------------------------------------------------
* Local variables:
* c-file-style: "linux"
* End:
*/
...@@ -18,45 +18,6 @@ int sc_size(void *data) ...@@ -18,45 +18,6 @@ int sc_size(void *data)
return(sizeof(struct sigcontext) + arch->fpstate_size); return(sizeof(struct sigcontext) + arch->fpstate_size);
} }
int copy_sc_to_user(void *to_ptr, void *from_ptr, void *data)
{
struct arch_frame_data *arch = data;
struct sigcontext *to = to_ptr, *from = from_ptr;
struct _fpstate *to_fp, *from_fp;
int err;
to_fp = (struct _fpstate *)((unsigned long) to + sizeof(*to));
from_fp = from->fpstate;
err = copy_to_user_proc(to, from, sizeof(*to));
if(from_fp != NULL){
err |= copy_to_user_proc(&to->fpstate, &to_fp,
sizeof(to->fpstate));
err |= copy_to_user_proc(to_fp, from_fp, arch->fpstate_size);
}
return(err);
}
int copy_sc_from_user(void *to_ptr, void *from_ptr, void *data)
{
struct arch_frame_data *arch = data;
struct sigcontext *to = to_ptr, *from = from_ptr;
struct _fpstate *to_fp, *from_fp;
unsigned long sigs;
int err;
to_fp = to->fpstate;
from_fp = from->fpstate;
sigs = to->oldmask;
err = copy_from_user_proc(to, from, sizeof(*to));
to->oldmask = sigs;
if(to_fp != NULL){
err |= copy_from_user_proc(&to->fpstate, &to_fp,
sizeof(to->fpstate));
err |= copy_from_user_proc(to_fp, from_fp, arch->fpstate_size);
}
return(err);
}
void sc_to_sc(void *to_ptr, void *from_ptr) void sc_to_sc(void *to_ptr, void *from_ptr)
{ {
struct sigcontext *to = to_ptr, *from = from_ptr; struct sigcontext *to = to_ptr, *from = from_ptr;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment