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 166 break;
167 167 case EXCP00_DIVZ:
168 168 if (env->eflags & VM_MASK) {
169   - do_int(env, trapnr);
  169 + handle_vm86_trap(env, trapnr);
170 170 } else {
171 171 /* division by zero */
172 172 info.si_signo = SIGFPE;
... ... @@ -176,10 +176,27 @@ void cpu_loop(CPUX86State *env)
176 176 queue_signal(info.si_signo, &info);
177 177 }
178 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 196 case EXCP04_INTO:
180 197 case EXCP05_BOUND:
181 198 if (env->eflags & VM_MASK) {
182   - do_int(env, trapnr);
  199 + handle_vm86_trap(env, trapnr);
183 200 } else {
184 201 info.si_signo = SIGSEGV;
185 202 info.si_errno = 0;
... ...
linux-user/qemu.h
... ... @@ -83,7 +83,7 @@ extern FILE *logfile;
83 83  
84 84 /* vm86.c */
85 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 87 void handle_vm86_fault(CPUX86State *env);
88 88 int do_vm86(CPUX86State *env, long subfunction,
89 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 110 tinfo->si_signo = sig;
111 111 tinfo->si_errno = 0;
112 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 115 /* should never come here, but who knows. The information for
115 116 the target is irrelevant */
116 117 tinfo->_sifields._sigfault._addr = 0;
... ... @@ -131,7 +132,8 @@ static void tswap_siginfo(target_siginfo_t *tinfo,
131 132 tinfo->si_signo = tswap32(sig);
132 133 tinfo->si_errno = tswap32(info->si_errno);
133 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 137 tinfo->_sifields._sigfault._addr =
136 138 tswapl(info->_sifields._sigfault._addr);
137 139 } else if (sig >= TARGET_SIGRTMIN) {
... ... @@ -788,6 +790,9 @@ long do_sigreturn(CPUX86State *env)
788 790 sigset_t set;
789 791 int eax, i;
790 792  
  793 +#if defined(DEBUG_SIGNAL)
  794 + fprintf(stderr, "do_sigreturn\n");
  795 +#endif
791 796 /* set blocked signals */
792 797 target_set.sig[0] = frame->sc.oldmask;
793 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 178  
179 179 /* handle VM86 interrupt (NOTE: the CPU core currently does not
180 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 183 TaskState *ts = env->opaque;
184 184 uint32_t *int_ptr, segoffs;
... ... @@ -225,6 +225,15 @@ void do_int(CPUX86State *env, int intno)
225 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 237 #define CHECK_IF_IN_TRAP(disp) \
229 238 if ((tswap32(ts->target_v86->vm86plus.flags) & TARGET_vm86dbg_active) && \
230 239 (tswap32(ts->target_v86->vm86plus.flags) & TARGET_vm86dbg_TFpendig)) \
... ...
syscall-i386.h
... ... @@ -480,6 +480,12 @@ typedef struct target_siginfo {
480 480 #define TARGET_SEGV_MAPERR (1) /* address not mapped to object */
481 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 489 /* default linux values for the selectors */
484 490 #define __USER_CS (0x23)
485 491 #define __USER_DS (0x2B)
... ...