Add guest support for getting page fault information using PTRACE_GETSIGINFO.
The nastiness at the top of arch/um/os-Linux/skas/process.c is defining the new siginfo_t structure, which requires using CPP to rename the old one out of the way. Index: linux-2.6-skas4/arch/um/os-Linux/skas/process.c =================================================================== --- linux-2.6-skas4.orig/arch/um/os-Linux/skas/process.c 2008-01-09 16:29:10.000000000 -0500 +++ linux-2.6-skas4/arch/um/os-Linux/skas/process.c 2008-01-09 16:44:25.000000000 -0500 @@ -3,6 +3,9 @@ * Licensed under the GPL */ +#define siginfo old_siginfo +#define siginfo_t old_siginfo_t + #include <stdlib.h> #include <unistd.h> #include <sched.h> @@ -26,6 +29,108 @@ #include "user.h" #include "sysdep/stub.h" +#undef siginfo +#undef siginfo_t + +#define __ARCH_SI_TRAPNO +#define __ARCH_SI_ERROR + +/* + * This is the size (including padding) of the part of the + * struct siginfo that is before the union. + */ +#ifndef __ARCH_SI_PREAMBLE_SIZE +#define __ARCH_SI_PREAMBLE_SIZE (3 * sizeof(int)) +#endif + +#define SI_MAX_SIZE 128 +#ifndef SI_PAD_SIZE +#define SI_PAD_SIZE ((SI_MAX_SIZE - __ARCH_SI_PREAMBLE_SIZE) / sizeof(int)) +#endif + +#ifndef __ARCH_SI_UID_T +#define __ARCH_SI_UID_T uid_t +#endif + +/* + * The default "si_band" type is "long", as specified by POSIX. + * However, some architectures want to override this to "int" + * for historical compatibility reasons, so we allow that. + */ +#ifndef __ARCH_SI_BAND_T +#define __ARCH_SI_BAND_T long +#endif + +#define __user + +typedef struct siginfo { + int si_signo; + int si_errno; + int si_code; + + union { + int _pad[SI_PAD_SIZE]; + + /* kill() */ + struct { + pid_t _pid; /* sender's pid */ + __ARCH_SI_UID_T _uid; /* sender's uid */ + } _kill; + + /* POSIX.1b timers */ + struct { + timer_t _tid; /* timer id */ + int _overrun; /* overrun count */ + char _pad[sizeof( __ARCH_SI_UID_T) - sizeof(int)]; + sigval_t _sigval; /* same as below */ + int _sys_private; /* not to be passed to user */ + } _timer; + + /* POSIX.1b signals */ + struct { + pid_t _pid; /* sender's pid */ + __ARCH_SI_UID_T _uid; /* sender's uid */ + sigval_t _sigval; + } _rt; + + /* SIGCHLD */ + struct { + pid_t _pid; /* which child */ + __ARCH_SI_UID_T _uid; /* sender's uid */ + int _status; /* exit code */ + clock_t _utime; + clock_t _stime; + } _sigchld; + + /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */ + struct { + void __user *_addr; /* faulting insn/memory ref. */ +#ifdef __ARCH_SI_TRAPNO + int _trapno; /* TRAP # which caused the signal */ +#endif +#ifdef __ARCH_SI_ERROR + int _error; /* CPU error code */ +#endif + } _sigfault; + + /* SIGPOLL */ + struct { + __ARCH_SI_BAND_T _band; /* POLL_IN, POLL_OUT, POLL_MSG */ + int _fd; + } _sigpoll; + } _sifields; +} siginfo_t; + +#ifdef __ARCH_SI_TRAPNO +#define si_trapno _sifields._sigfault._trapno +#endif +#ifdef __ARCH_SI_ERROR +#define si_error _sifields._sigfault._error +#endif + +#undef si_addr +#define si_addr _sifields._sigfault._addr + int is_skas_winch(int pid, int fd, void *data) { if (pid != getpgrp()) @@ -91,11 +196,25 @@ bad_wait: extern unsigned long current_stub_stack(void); +#ifndef PTRACE_GETSIGINFO +#define PTRACE_GETSIGINFO 0x4202 +#endif + void get_skas_faultinfo(int pid, struct faultinfo * fi) { + siginfo_t si; int err; - if (ptrace_faultinfo) { + if(1){ + err = ptrace(PTRACE_GETSIGINFO, pid, 0, &si); + if(err) + printk("PTRACE_GETSIGINFO failed, err = %d\n", errno); + + fi->cr2 = (unsigned long) si.si_addr; + fi->error_code = si.si_error; + fi->trap_no = si.si_trapno; + } + else if (ptrace_faultinfo) { err = ptrace(PTRACE_FAULTINFO, pid, 0, fi); if (err) panic("get_skas_faultinfo - PTRACE_FAULTINFO failed, " ------------------------------------------------------------------------- Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace _______________________________________________ User-mode-linux-devel mailing list User-mode-linux-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/user-mode-linux-devel