vx32

Local 9vx git repository for patches.
git clone git://r-36.net/vx32
Log | Files | Refs

commit c82f48a95967c71d4f81debf6ae9c15a3b60ebe9
parent d2d43ccb6890cbd0afaaa45a24db7b8d6b05129c
Author: Russ Cox <rsc@swtch.com>
Date:   Sun, 29 Jun 2008 21:46:25 -0400

libvx32/FreeBSD: better handling of segmentation fault, breakpoint

Diffstat:
src/libvx32/freebsd.c | 41++++++++++++++++++++++-------------------
1 file changed, 22 insertions(+), 19 deletions(-)

diff --git a/src/libvx32/freebsd.c b/src/libvx32/freebsd.c @@ -157,13 +157,10 @@ int vx32_sighandler(int signo, siginfo_t *si, void *v) vxemu *emu; ucontext_t *uc; mcontext_t *mc; - uint32_t cr2; uc = v; mc = &uc->uc_mcontext; - cr2 = (uint32_t)si->si_addr; - // We can't be sure that vxemu is running, // and thus that %VSEG is actually mapped to a // valid vxemu. The only way to tell is to look at %VSEG. @@ -207,39 +204,45 @@ int vx32_sighandler(int signo, siginfo_t *si, void *v) // so that thread-local storage and such works. vxrun_cleanup(emu); - // dumpmcontext(mc, cr2); + // dumpmcontext(mc, (uint32_t)si->si_addr); + uint32_t addr; int newtrap; + addr = 0; switch(signo){ case SIGSEGV: + newtrap = VXTRAP_PAGEFAULT; + addr = (uint32_t)si->si_addr; + break; case SIGBUS: + /* + * On FreeBSD, SIGBUS means segmentation limit fault. + * The supplied address is bogus. + */ newtrap = VXTRAP_PAGEFAULT; + addr = 0; break; case SIGFPE: - // iprint("fpe %d\n", si->si_code); + // vxprint("fpe %d\n", si->si_code); newtrap = VXTRAP_FLOAT; + addr = 0; break; case SIGVTALRM: newtrap = VXTRAP_IRQ + VXIRQ_TIMER; + addr = 0; break; case SIGTRAP: -#warning "FreeBSD: need to test single-stepping" - // Linux sends SIGTRAP when it gets a processor + // FreeBSD sends SIGTRAP when it gets a processor // debug exception, which is caused by single-stepping - // with the TF bit, among other things. The processor - // turns off the TF bit before generating the trap, but - // it appears that Linux turns it back on for us. - // Let's use it to confirm that this is a single-step trap. - if (mc->mc_eflags & EFLAGS_TF){ - newtrap = VXTRAP_SINGLESTEP; - mc->mc_eflags &= ~EFLAGS_TF; - }else{ - vxprint("Unexpected sigtrap eflags=%#x\n", mc->mc_eflags); - newtrap = VXTRAP_SIGNAL + signo; - } + // with the TF bit, among other things. + // It appears that FreeBSD does not turn the flag back on + // before entering the signal handler. + addr = 0; + newtrap = VXTRAP_SINGLESTEP; + mc->mc_eflags &= ~EFLAGS_TF; // Just in case. break; default: @@ -323,7 +326,7 @@ int vx32_sighandler(int signo, siginfo_t *si, void *v) if (emu->trapenv == NULL) return 0; emu->cpu.traperr = mc->mc_err; - emu->cpu.trapva = cr2; + emu->cpu.trapva = addr; memmove(&mc->mc_gs, &emu->trapenv->mc_gs, 19*4); return 1; }