I am trying to write a signal handler that detects a read or write to
a page, and can modify the page before the read or write completes.
It is for a type of user level virtual memory system... So I have
mprotect()ed the page, and I can trap the signal without a problem.
The problem I am having is in figuring out what page caused the fault,
and whether it was on a read or a write. After looking through the
kernel sources, I have determined that if I redefine my signal handler
to the following:
struct sig_stack { /* Derived from arch/i386/kernel/signal.c */
/* the "normal" stack seen by the signal handler (iBCS2) */
uint4 sig_num, gs, fs, es, ds, edi, esi, ebp, *fp, ebx, edx, ecx, eax;
uint4 trap_no, error_code, eip, cs, eflags, esp, ss;
uint4 state_ptr; /* 387 state pointer - not implemented*/
/* non-iBCS2 extensions.. */
uint4 oldmask, cr2;
void sighandler(struct sig_stack siginfo);Quote:};
I can find the fault address in siginfo.cr2 and whether it was caused by a
read or write in siginfo.error_code.
What I am wondering is, is this a defined interface that is not going
to change? Under Solaris, this type of interface is defined in
ucontext.h. On my Linux (Slackware 3.0), ucontext.h is only a dummy
header with no real contents. I am not so worried about the iBCS2
stuff, since I assume this came from some standard defined elsewhere,
but what about the non-iBCS2 extensions? Will they persist?
Also, using the above interface is not portable to non-Intel Linux
platforms. Is there a platform independant way of finding the fault
address and type?
Perhaps the above structure could be added to ucontext.h in order to
standardize the interface.
Thanks for any help,
Chris Colohan
3rd Year Computer Engineering
University of Toronto