sigtrap support
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@147 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
parent
564c8f9978
commit
447db2139a
@ -166,7 +166,7 @@ void cpu_loop(CPUX86State *env)
|
|||||||
break;
|
break;
|
||||||
case EXCP00_DIVZ:
|
case EXCP00_DIVZ:
|
||||||
if (env->eflags & VM_MASK) {
|
if (env->eflags & VM_MASK) {
|
||||||
do_int(env, trapnr);
|
handle_vm86_trap(env, trapnr);
|
||||||
} else {
|
} else {
|
||||||
/* division by zero */
|
/* division by zero */
|
||||||
info.si_signo = SIGFPE;
|
info.si_signo = SIGFPE;
|
||||||
@ -176,10 +176,27 @@ void cpu_loop(CPUX86State *env)
|
|||||||
queue_signal(info.si_signo, &info);
|
queue_signal(info.si_signo, &info);
|
||||||
}
|
}
|
||||||
break;
|
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 EXCP04_INTO:
|
||||||
case EXCP05_BOUND:
|
case EXCP05_BOUND:
|
||||||
if (env->eflags & VM_MASK) {
|
if (env->eflags & VM_MASK) {
|
||||||
do_int(env, trapnr);
|
handle_vm86_trap(env, trapnr);
|
||||||
} else {
|
} else {
|
||||||
info.si_signo = SIGSEGV;
|
info.si_signo = SIGSEGV;
|
||||||
info.si_errno = 0;
|
info.si_errno = 0;
|
||||||
|
@ -83,7 +83,7 @@ extern FILE *logfile;
|
|||||||
|
|
||||||
/* vm86.c */
|
/* vm86.c */
|
||||||
void save_v86_state(CPUX86State *env);
|
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);
|
void handle_vm86_fault(CPUX86State *env);
|
||||||
int do_vm86(CPUX86State *env, long subfunction,
|
int do_vm86(CPUX86State *env, long subfunction,
|
||||||
struct target_vm86plus_struct * target_v86);
|
struct target_vm86plus_struct * target_v86);
|
||||||
|
@ -110,7 +110,8 @@ static inline void host_to_target_siginfo_noswap(target_siginfo_t *tinfo,
|
|||||||
tinfo->si_signo = sig;
|
tinfo->si_signo = sig;
|
||||||
tinfo->si_errno = 0;
|
tinfo->si_errno = 0;
|
||||||
tinfo->si_code = 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
|
/* should never come here, but who knows. The information for
|
||||||
the target is irrelevant */
|
the target is irrelevant */
|
||||||
tinfo->_sifields._sigfault._addr = 0;
|
tinfo->_sifields._sigfault._addr = 0;
|
||||||
@ -131,7 +132,8 @@ static void tswap_siginfo(target_siginfo_t *tinfo,
|
|||||||
tinfo->si_signo = tswap32(sig);
|
tinfo->si_signo = tswap32(sig);
|
||||||
tinfo->si_errno = tswap32(info->si_errno);
|
tinfo->si_errno = tswap32(info->si_errno);
|
||||||
tinfo->si_code = tswap32(info->si_code);
|
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 =
|
tinfo->_sifields._sigfault._addr =
|
||||||
tswapl(info->_sifields._sigfault._addr);
|
tswapl(info->_sifields._sigfault._addr);
|
||||||
} else if (sig >= TARGET_SIGRTMIN) {
|
} else if (sig >= TARGET_SIGRTMIN) {
|
||||||
@ -788,6 +790,9 @@ long do_sigreturn(CPUX86State *env)
|
|||||||
sigset_t set;
|
sigset_t set;
|
||||||
int eax, i;
|
int eax, i;
|
||||||
|
|
||||||
|
#if defined(DEBUG_SIGNAL)
|
||||||
|
fprintf(stderr, "do_sigreturn\n");
|
||||||
|
#endif
|
||||||
/* set blocked signals */
|
/* set blocked signals */
|
||||||
target_set.sig[0] = frame->sc.oldmask;
|
target_set.sig[0] = frame->sc.oldmask;
|
||||||
for(i = 1; i < TARGET_NSIG_WORDS; i++)
|
for(i = 1; i < TARGET_NSIG_WORDS; i++)
|
||||||
|
@ -178,7 +178,7 @@ static inline unsigned int get_vflags(CPUX86State *env)
|
|||||||
|
|
||||||
/* handle VM86 interrupt (NOTE: the CPU core currently does not
|
/* handle VM86 interrupt (NOTE: the CPU core currently does not
|
||||||
support TSS interrupt revectoring, so this code is always executed) */
|
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;
|
TaskState *ts = env->opaque;
|
||||||
uint32_t *int_ptr, segoffs;
|
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));
|
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) \
|
#define CHECK_IF_IN_TRAP(disp) \
|
||||||
if ((tswap32(ts->target_v86->vm86plus.flags) & TARGET_vm86dbg_active) && \
|
if ((tswap32(ts->target_v86->vm86plus.flags) & TARGET_vm86dbg_active) && \
|
||||||
(tswap32(ts->target_v86->vm86plus.flags) & TARGET_vm86dbg_TFpendig)) \
|
(tswap32(ts->target_v86->vm86plus.flags) & TARGET_vm86dbg_TFpendig)) \
|
||||||
|
@ -480,6 +480,12 @@ typedef struct target_siginfo {
|
|||||||
#define TARGET_SEGV_MAPERR (1) /* address not mapped to object */
|
#define TARGET_SEGV_MAPERR (1) /* address not mapped to object */
|
||||||
#define TARGET_SEGV_ACCERR (2) /* invalid permissions for mapped 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 */
|
/* default linux values for the selectors */
|
||||||
#define __USER_CS (0x23)
|
#define __USER_CS (0x23)
|
||||||
#define __USER_DS (0x2B)
|
#define __USER_DS (0x2B)
|
||||||
|
Loading…
Reference in New Issue
Block a user