Don't abuse tf_err to pass the faulting virtual address to signal handlers

on i386.  Instead, add a new field to 'struct mdthread' to hold the address
and preserve the tf_err value.  This corrects the 'sc_err' value in signal
frames which wine needs.

Tested by:	wine-freebsd @ hub org
This commit is contained in:
jhb 2007-08-14 15:46:35 +00:00
parent 9d37aaecac
commit 2a667e66b3
4 changed files with 9 additions and 8 deletions

View File

@ -319,7 +319,7 @@ osendsig(catcher, sig, mask, code)
} else {
/* Old FreeBSD-style arguments. */
sf.sf_arg2 = code;
sf.sf_addr = regs->tf_err;
sf.sf_addr = td->td_md.md_fault_addr;
sf.sf_ahu.sf_handler = catcher;
}
mtx_unlock(&psp->ps_mtx);
@ -458,11 +458,11 @@ freebsd4_sendsig(catcher, sig, mask, code)
/* Fill in POSIX parts */
sf.sf_si.si_signo = sig;
sf.sf_si.si_code = code;
sf.sf_si.si_addr = (void *)regs->tf_err;
sf.sf_si.si_addr = (void *)td->td_md.md_fault_addr;
} else {
/* Old FreeBSD-style arguments. */
sf.sf_siginfo = code;
sf.sf_addr = regs->tf_err;
sf.sf_addr = td->td_md.md_fault_addr;
sf.sf_ahu.sf_handler = catcher;
}
mtx_unlock(&psp->ps_mtx);
@ -597,11 +597,11 @@ sendsig(catcher, sig, mask, code)
/* Fill in POSIX parts */
sf.sf_si.si_signo = sig;
sf.sf_si.si_code = code;
sf.sf_si.si_addr = (void *)regs->tf_err;
sf.sf_si.si_addr = (void *)td->td_md.md_fault_addr;
} else {
/* Old FreeBSD-style arguments. */
sf.sf_siginfo = code;
sf.sf_addr = regs->tf_err;
sf.sf_addr = td->td_md.md_fault_addr;
sf.sf_ahu.sf_handler = catcher;
}
mtx_unlock(&psp->ps_mtx);
@ -675,7 +675,7 @@ cpu_thread_siginfo(int sig, u_long code, siginfo_t *si)
bzero(si, sizeof(*si));
si->si_signo = sig;
si->si_code = code;
si->si_addr = (void *)td->td_frame->tf_err;
si->si_addr = (void *)td->td_md.md_fault_addr;
/* XXXKSE fill other fields */
}

View File

@ -747,7 +747,7 @@ nogo:
}
/* kludge to pass faulting virtual address to sendsig */
frame->tf_err = eva;
td->td_md.md_fault_addr = eva;
return((rv == KERN_PROTECTION_FAILURE) ? SIGBUS : SIGSEGV);
}

View File

@ -49,6 +49,7 @@ struct proc_ldt {
struct mdthread {
int md_spinlock_count; /* (k) */
register_t md_saved_flags; /* (k) */
register_t md_fault_addr; /* (k) */
};
struct mdproc {

View File

@ -324,7 +324,7 @@ linux_rt_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
/* Fill in POSIX parts */
frame.sf_si.lsi_signo = sig;
frame.sf_si.lsi_code = code;
frame.sf_si.lsi_addr = (void *)regs->tf_err;
frame.sf_si.lsi_addr = (void *)td->td_md.md_fault_addr;
/*
* Build the signal context to be used by sigreturn.