Commit 447db2139a6f6883183a7a750c5849145fd29899

Authored by bellard
1 parent 564c8f99

sigtrap support


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@147 c046a42c-6fe2-441c-8c8c-71466251a162
linux-user/main.c
@@ -166,7 +166,7 @@ void cpu_loop(CPUX86State *env) @@ -166,7 +166,7 @@ void cpu_loop(CPUX86State *env)
166 break; 166 break;
167 case EXCP00_DIVZ: 167 case EXCP00_DIVZ:
168 if (env->eflags & VM_MASK) { 168 if (env->eflags & VM_MASK) {
169 - do_int(env, trapnr); 169 + handle_vm86_trap(env, trapnr);
170 } else { 170 } else {
171 /* division by zero */ 171 /* division by zero */
172 info.si_signo = SIGFPE; 172 info.si_signo = SIGFPE;
@@ -176,10 +176,27 @@ void cpu_loop(CPUX86State *env) @@ -176,10 +176,27 @@ void cpu_loop(CPUX86State *env)
176 queue_signal(info.si_signo, &info); 176 queue_signal(info.si_signo, &info);
177 } 177 }
178 break; 178 break;
  179 + case EXCP01_SSTP:
  180 + case EXCP03_INT3:
  181 + if (env->eflags & VM_MASK) {
  182 + handle_vm86_trap(env, trapnr);
  183 + } else {
  184 + info.si_signo = SIGTRAP;
  185 + info.si_errno = 0;
  186 + if (trapnr == EXCP01_SSTP) {
  187 + info.si_code = TARGET_TRAP_BRKPT;
  188 + info._sifields._sigfault._addr = env->eip;
  189 + } else {
  190 + info.si_code = TARGET_SI_KERNEL;
  191 + info._sifields._sigfault._addr = 0;
  192 + }
  193 + queue_signal(info.si_signo, &info);
  194 + }
  195 + break;
179 case EXCP04_INTO: 196 case EXCP04_INTO:
180 case EXCP05_BOUND: 197 case EXCP05_BOUND:
181 if (env->eflags & VM_MASK) { 198 if (env->eflags & VM_MASK) {
182 - do_int(env, trapnr); 199 + handle_vm86_trap(env, trapnr);
183 } else { 200 } else {
184 info.si_signo = SIGSEGV; 201 info.si_signo = SIGSEGV;
185 info.si_errno = 0; 202 info.si_errno = 0;
linux-user/qemu.h
@@ -83,7 +83,7 @@ extern FILE *logfile; @@ -83,7 +83,7 @@ extern FILE *logfile;
83 83
84 /* vm86.c */ 84 /* vm86.c */
85 void save_v86_state(CPUX86State *env); 85 void save_v86_state(CPUX86State *env);
86 -void do_int(CPUX86State *env, int intno); 86 +void handle_vm86_trap(CPUX86State *env, int trapno);
87 void handle_vm86_fault(CPUX86State *env); 87 void handle_vm86_fault(CPUX86State *env);
88 int do_vm86(CPUX86State *env, long subfunction, 88 int do_vm86(CPUX86State *env, long subfunction,
89 struct target_vm86plus_struct * target_v86); 89 struct target_vm86plus_struct * target_v86);
linux-user/signal.c
@@ -110,7 +110,8 @@ static inline void host_to_target_siginfo_noswap(target_siginfo_t *tinfo, @@ -110,7 +110,8 @@ static inline void host_to_target_siginfo_noswap(target_siginfo_t *tinfo,
110 tinfo->si_signo = sig; 110 tinfo->si_signo = sig;
111 tinfo->si_errno = 0; 111 tinfo->si_errno = 0;
112 tinfo->si_code = 0; 112 tinfo->si_code = 0;
113 - if (sig == SIGILL || sig == SIGFPE || sig == SIGSEGV || sig == SIGBUS) { 113 + if (sig == SIGILL || sig == SIGFPE || sig == SIGSEGV ||
  114 + sig == SIGBUS || sig == SIGTRAP) {
114 /* should never come here, but who knows. The information for 115 /* should never come here, but who knows. The information for
115 the target is irrelevant */ 116 the target is irrelevant */
116 tinfo->_sifields._sigfault._addr = 0; 117 tinfo->_sifields._sigfault._addr = 0;
@@ -131,7 +132,8 @@ static void tswap_siginfo(target_siginfo_t *tinfo, @@ -131,7 +132,8 @@ static void tswap_siginfo(target_siginfo_t *tinfo,
131 tinfo->si_signo = tswap32(sig); 132 tinfo->si_signo = tswap32(sig);
132 tinfo->si_errno = tswap32(info->si_errno); 133 tinfo->si_errno = tswap32(info->si_errno);
133 tinfo->si_code = tswap32(info->si_code); 134 tinfo->si_code = tswap32(info->si_code);
134 - if (sig == SIGILL || sig == SIGFPE || sig == SIGSEGV || sig == SIGBUS) { 135 + if (sig == SIGILL || sig == SIGFPE || sig == SIGSEGV ||
  136 + sig == SIGBUS || sig == SIGTRAP) {
135 tinfo->_sifields._sigfault._addr = 137 tinfo->_sifields._sigfault._addr =
136 tswapl(info->_sifields._sigfault._addr); 138 tswapl(info->_sifields._sigfault._addr);
137 } else if (sig >= TARGET_SIGRTMIN) { 139 } else if (sig >= TARGET_SIGRTMIN) {
@@ -788,6 +790,9 @@ long do_sigreturn(CPUX86State *env) @@ -788,6 +790,9 @@ long do_sigreturn(CPUX86State *env)
788 sigset_t set; 790 sigset_t set;
789 int eax, i; 791 int eax, i;
790 792
  793 +#if defined(DEBUG_SIGNAL)
  794 + fprintf(stderr, "do_sigreturn\n");
  795 +#endif
791 /* set blocked signals */ 796 /* set blocked signals */
792 target_set.sig[0] = frame->sc.oldmask; 797 target_set.sig[0] = frame->sc.oldmask;
793 for(i = 1; i < TARGET_NSIG_WORDS; i++) 798 for(i = 1; i < TARGET_NSIG_WORDS; i++)
linux-user/vm86.c
@@ -178,7 +178,7 @@ static inline unsigned int get_vflags(CPUX86State *env) @@ -178,7 +178,7 @@ static inline unsigned int get_vflags(CPUX86State *env)
178 178
179 /* handle VM86 interrupt (NOTE: the CPU core currently does not 179 /* handle VM86 interrupt (NOTE: the CPU core currently does not
180 support TSS interrupt revectoring, so this code is always executed) */ 180 support TSS interrupt revectoring, so this code is always executed) */
181 -void do_int(CPUX86State *env, int intno) 181 +static void do_int(CPUX86State *env, int intno)
182 { 182 {
183 TaskState *ts = env->opaque; 183 TaskState *ts = env->opaque;
184 uint32_t *int_ptr, segoffs; 184 uint32_t *int_ptr, segoffs;
@@ -225,6 +225,15 @@ void do_int(CPUX86State *env, int intno) @@ -225,6 +225,15 @@ void do_int(CPUX86State *env, int intno)
225 return_to_32bit(env, TARGET_VM86_INTx | (intno << 8)); 225 return_to_32bit(env, TARGET_VM86_INTx | (intno << 8));
226 } 226 }
227 227
  228 +void handle_vm86_trap(CPUX86State *env, int trapno)
  229 +{
  230 + if (trapno == 1 || trapno == 3) {
  231 + return_to_32bit(env, TARGET_VM86_TRAP + (trapno << 8));
  232 + } else {
  233 + do_int(env, trapno);
  234 + }
  235 +}
  236 +
228 #define CHECK_IF_IN_TRAP(disp) \ 237 #define CHECK_IF_IN_TRAP(disp) \
229 if ((tswap32(ts->target_v86->vm86plus.flags) & TARGET_vm86dbg_active) && \ 238 if ((tswap32(ts->target_v86->vm86plus.flags) & TARGET_vm86dbg_active) && \
230 (tswap32(ts->target_v86->vm86plus.flags) & TARGET_vm86dbg_TFpendig)) \ 239 (tswap32(ts->target_v86->vm86plus.flags) & TARGET_vm86dbg_TFpendig)) \
syscall-i386.h
@@ -480,6 +480,12 @@ typedef struct target_siginfo { @@ -480,6 +480,12 @@ typedef struct target_siginfo {
480 #define TARGET_SEGV_MAPERR (1) /* address not mapped to object */ 480 #define TARGET_SEGV_MAPERR (1) /* address not mapped to object */
481 #define TARGET_SEGV_ACCERR (2) /* invalid permissions for mapped object */ 481 #define TARGET_SEGV_ACCERR (2) /* invalid permissions for mapped object */
482 482
  483 +/*
  484 + * SIGTRAP si_codes
  485 + */
  486 +#define TARGET_TRAP_BRKPT (1) /* process breakpoint */
  487 +#define TARGET_TRAP_TRACE (2) /* process trace trap */
  488 +
483 /* default linux values for the selectors */ 489 /* default linux values for the selectors */
484 #define __USER_CS (0x23) 490 #define __USER_CS (0x23)
485 #define __USER_DS (0x2B) 491 #define __USER_DS (0x2B)