Revision b56dad1c exec-i386.c

b/exec-i386.c
149 149

  
150 150
/* exception support */
151 151
/* NOTE: not static to force relocation generation by GCC */
152
void raise_exception(int exception_index)
152
void raise_exception_err(int exception_index, int error_code)
153 153
{
154 154
    /* NOTE: the register at this point must be saved by hand because
155 155
       longjmp restore them */
......
178 178
    env->regs[R_EDI] = EDI;
179 179
#endif
180 180
    env->exception_index = exception_index;
181
    env->error_code = error_code;
181 182
    longjmp(env->jmp_env, 1);
182 183
}
183 184

  
185
/* short cut if error_code is 0 or not present */
186
void raise_exception(int exception_index)
187
{
188
    raise_exception_err(exception_index, 0);
189
}
190

  
184 191
#if defined(DEBUG_EXEC)
185 192
static const char *cc_op_str[] = {
186 193
    "DYNAMIC",
......
218 225
static void cpu_x86_dump_state(FILE *f)
219 226
{
220 227
    int eflags;
228
    char cc_op_name[32];
221 229
    eflags = cc_table[CC_OP].compute_all();
222 230
    eflags |= (DF & DF_MASK);
231
    if ((unsigned)env->cc_op < CC_OP_NB)
232
        strcpy(cc_op_name, cc_op_str[env->cc_op]);
233
    else
234
        snprintf(cc_op_name, sizeof(cc_op_name), "[%d]", env->cc_op);
223 235
    fprintf(f, 
224 236
            "EAX=%08x EBX=%08X ECX=%08x EDX=%08x\n"
225 237
            "ESI=%08x EDI=%08X EBP=%08x ESP=%08x\n"
......
227 239
            "EIP=%08x\n",
228 240
            env->regs[R_EAX], env->regs[R_EBX], env->regs[R_ECX], env->regs[R_EDX], 
229 241
            env->regs[R_ESI], env->regs[R_EDI], env->regs[R_EBP], env->regs[R_ESP], 
230
            env->cc_src, env->cc_dst, cc_op_str[env->cc_op],
242
            env->cc_src, env->cc_dst, cc_op_name,
231 243
            eflags & DF_MASK ? 'D' : '-',
232 244
            eflags & CC_O ? 'O' : '-',
233 245
            eflags & CC_S ? 'S' : '-',
......
280 292
 
281 293
    h = pc & (CODE_GEN_HASH_SIZE - 1);
282 294
    ptb = &tb_hash[h];
283
    for(;;) {
284
        tb = *ptb;
285
        if (!tb)
286
            break;
287
        if (tb->pc == pc && tb->cs_base == cs_base && tb->flags == flags)
295
#if 0
296
    /* XXX: hack to handle 16 bit modyfing code */
297
    if (flags & (1 << GEN_FLAG_CODE32_SHIFT))
298
#endif
299
        for(;;) {
300
            tb = *ptb;
301
            if (!tb)
302
                break;
303
            if (tb->pc == pc && tb->cs_base == cs_base && tb->flags == flags)
288 304
            return tb;
289
        ptb = &tb->hash_next;
290
    }
305
            ptb = &tb->hash_next;
306
        }
291 307
    *pptb = ptb;
292 308
    return NULL;
293 309
}
......
404 420
                       (unsigned long)env->seg_cache[R_SS].base) != 0) << 
405 421
                GEN_FLAG_ADDSEG_SHIFT;
406 422
            flags |= (env->eflags & VM_MASK) >> (17 - GEN_FLAG_VM_SHIFT);
423
            flags |= (env->eflags & IOPL_MASK) >> (12 - GEN_FLAG_IOPL_SHIFT);
424
            flags |= (env->segs[R_CS] & 3) << GEN_FLAG_CPL_SHIFT;
407 425
            cs_base = env->seg_cache[R_CS].base;
408 426
            pc = cs_base + env->eip;
409 427
            tb = tb_find(&ptb, (unsigned long)pc, (unsigned long)cs_base, 
......
508 526
#include <signal.h>
509 527
#include <sys/ucontext.h>
510 528

  
529
/* 'pc' is the host PC at which the exception was raised. 'address' is
530
   the effective address of the memory exception */
511 531
static inline int handle_cpu_signal(unsigned long pc,
532
                                    unsigned long address,
512 533
                                    sigset_t *old_set)
513 534
{
514 535
#ifdef DEBUG_SIGNAL
......
524 545
        sigprocmask(SIG_SETMASK, old_set, NULL);
525 546
        /* XXX: need to compute virtual pc position by retranslating
526 547
           code. The rest of the CPU state should be correct. */
527
        raise_exception(EXCP0D_GPF);
548
        env->cr2 = address;
549
        /* XXX: more precise exception code */
550
        raise_exception_err(EXCP0E_PAGE, 4);
528 551
        /* never comes here */
529 552
        return 1;
530 553
    } else {
......
546 569
#endif
547 570
    pc = uc->uc_mcontext.gregs[REG_EIP];
548 571
    pold_set = &uc->uc_sigmask;
549
    return handle_cpu_signal(pc, pold_set);
572
    return handle_cpu_signal(pc, (unsigned long)info->si_addr, pold_set);
550 573
#else
551 574
#warning No CPU specific signal handler: cannot handle target SIGSEGV events
552 575
    return 0;

Also available in: Unified diff