sigtrap support

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@147 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
bellard 2003-05-10 15:10:36 +00:00
parent 564c8f9978
commit 447db2139a
5 changed files with 43 additions and 6 deletions

View file

@ -166,7 +166,7 @@ void cpu_loop(CPUX86State *env)
break;
case EXCP00_DIVZ:
if (env->eflags & VM_MASK) {
do_int(env, trapnr);
handle_vm86_trap(env, trapnr);
} else {
/* division by zero */
info.si_signo = SIGFPE;
@ -176,10 +176,27 @@ void cpu_loop(CPUX86State *env)
queue_signal(info.si_signo, &info);
}
break;
case EXCP01_SSTP:
case EXCP03_INT3:
if (env->eflags & VM_MASK) {
handle_vm86_trap(env, trapnr);
} else {
info.si_signo = SIGTRAP;
info.si_errno = 0;
if (trapnr == EXCP01_SSTP) {
info.si_code = TARGET_TRAP_BRKPT;
info._sifields._sigfault._addr = env->eip;
} else {
info.si_code = TARGET_SI_KERNEL;
info._sifields._sigfault._addr = 0;
}
queue_signal(info.si_signo, &info);
}
break;
case EXCP04_INTO:
case EXCP05_BOUND:
if (env->eflags & VM_MASK) {
do_int(env, trapnr);
handle_vm86_trap(env, trapnr);
} else {
info.si_signo = SIGSEGV;
info.si_errno = 0;

View file

@ -83,7 +83,7 @@ extern FILE *logfile;
/* vm86.c */
void save_v86_state(CPUX86State *env);
void do_int(CPUX86State *env, int intno);
void handle_vm86_trap(CPUX86State *env, int trapno);
void handle_vm86_fault(CPUX86State *env);
int do_vm86(CPUX86State *env, long subfunction,
struct target_vm86plus_struct * target_v86);

View file

@ -110,7 +110,8 @@ static inline void host_to_target_siginfo_noswap(target_siginfo_t *tinfo,
tinfo->si_signo = sig;
tinfo->si_errno = 0;
tinfo->si_code = 0;
if (sig == SIGILL || sig == SIGFPE || sig == SIGSEGV || sig == SIGBUS) {
if (sig == SIGILL || sig == SIGFPE || sig == SIGSEGV ||
sig == SIGBUS || sig == SIGTRAP) {
/* should never come here, but who knows. The information for
the target is irrelevant */
tinfo->_sifields._sigfault._addr = 0;
@ -131,7 +132,8 @@ static void tswap_siginfo(target_siginfo_t *tinfo,
tinfo->si_signo = tswap32(sig);
tinfo->si_errno = tswap32(info->si_errno);
tinfo->si_code = tswap32(info->si_code);
if (sig == SIGILL || sig == SIGFPE || sig == SIGSEGV || sig == SIGBUS) {
if (sig == SIGILL || sig == SIGFPE || sig == SIGSEGV ||
sig == SIGBUS || sig == SIGTRAP) {
tinfo->_sifields._sigfault._addr =
tswapl(info->_sifields._sigfault._addr);
} else if (sig >= TARGET_SIGRTMIN) {
@ -788,6 +790,9 @@ long do_sigreturn(CPUX86State *env)
sigset_t set;
int eax, i;
#if defined(DEBUG_SIGNAL)
fprintf(stderr, "do_sigreturn\n");
#endif
/* set blocked signals */
target_set.sig[0] = frame->sc.oldmask;
for(i = 1; i < TARGET_NSIG_WORDS; i++)

View file

@ -178,7 +178,7 @@ static inline unsigned int get_vflags(CPUX86State *env)
/* handle VM86 interrupt (NOTE: the CPU core currently does not
support TSS interrupt revectoring, so this code is always executed) */
void do_int(CPUX86State *env, int intno)
static void do_int(CPUX86State *env, int intno)
{
TaskState *ts = env->opaque;
uint32_t *int_ptr, segoffs;
@ -225,6 +225,15 @@ void do_int(CPUX86State *env, int intno)
return_to_32bit(env, TARGET_VM86_INTx | (intno << 8));
}
void handle_vm86_trap(CPUX86State *env, int trapno)
{
if (trapno == 1 || trapno == 3) {
return_to_32bit(env, TARGET_VM86_TRAP + (trapno << 8));
} else {
do_int(env, trapno);
}
}
#define CHECK_IF_IN_TRAP(disp) \
if ((tswap32(ts->target_v86->vm86plus.flags) & TARGET_vm86dbg_active) && \
(tswap32(ts->target_v86->vm86plus.flags) & TARGET_vm86dbg_TFpendig)) \

View file

@ -480,6 +480,12 @@ typedef struct target_siginfo {
#define TARGET_SEGV_MAPERR (1) /* address not mapped to object */
#define TARGET_SEGV_ACCERR (2) /* invalid permissions for mapped object */
/*
* SIGTRAP si_codes
*/
#define TARGET_TRAP_BRKPT (1) /* process breakpoint */
#define TARGET_TRAP_TRACE (2) /* process trace trap */
/* default linux values for the selectors */
#define __USER_CS (0x23)
#define __USER_DS (0x2B)