sigtrap support
authorbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>
Sat, 10 May 2003 15:10:36 +0000 (15:10 +0000)
committerbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>
Sat, 10 May 2003 15:10:36 +0000 (15:10 +0000)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@147 c046a42c-6fe2-441c-8c8c-71466251a162

linux-user/main.c
linux-user/qemu.h
linux-user/signal.c
linux-user/vm86.c
syscall-i386.h

index c9d0c98..00dc271 100644 (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;
index 5613c3e..0f004ff 100644 (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);
index 9873071..145dc29 100644 (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++)
index 8316117..f243af8 100644 (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)) \
index 30e8bc3..fbe8610 100644 (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)