Revision a513fe19 exec-i386.c

b/exec-i386.c
39 39
    spin_unlock(&global_cpu_lock);
40 40
}
41 41

  
42
/* exception support */
43
/* NOTE: not static to force relocation generation by GCC */
44
void raise_exception_err(int exception_index, int error_code)
42
void cpu_loop_exit(void)
45 43
{
46 44
    /* NOTE: the register at this point must be saved by hand because
47 45
       longjmp restore them */
......
76 74
#ifdef reg_EDI
77 75
    env->regs[R_EDI] = EDI;
78 76
#endif
79
    env->exception_index = exception_index;
80
    env->error_code = error_code;
81 77
    longjmp(env->jmp_env, 1);
82 78
}
83 79

  
84
/* short cut if error_code is 0 or not present */
85
void raise_exception(int exception_index)
86
{
87
    raise_exception_err(exception_index, 0);
88
}
89

  
90 80
int cpu_x86_exec(CPUX86State *env1)
91 81
{
92 82
    int saved_T0, saved_T1, saved_A0;
......
115 105
#ifdef reg_EDI
116 106
    int saved_EDI;
117 107
#endif
118
    int code_gen_size, ret, code_size;
108
    int code_gen_size, ret;
119 109
    void (*gen_func)(void);
120 110
    TranslationBlock *tb, **ptb;
121 111
    uint8_t *tc_ptr, *cs_base, *pc;
......
172 162
        T0 = 0; /* force lookup of first TB */
173 163
        for(;;) {
174 164
            if (env->interrupt_request) {
175
                raise_exception(EXCP_INTERRUPT);
165
                env->exception_index = EXCP_INTERRUPT;
166
                cpu_loop_exit();
176 167
            }
177 168
#ifdef DEBUG_EXEC
178 169
            if (loglevel) {
......
226 217
                }
227 218
                tc_ptr = code_gen_ptr;
228 219
                tb->tc_ptr = tc_ptr;
229
                ret = cpu_x86_gen_code(code_gen_ptr, CODE_GEN_MAX_SIZE, 
230
                                       &code_gen_size, pc, cs_base, flags,
231
                                       &code_size, tb);
220
                tb->cs_base = (unsigned long)cs_base;
221
                tb->flags = flags;
222
                ret = cpu_x86_gen_code(tb, CODE_GEN_MAX_SIZE, &code_gen_size);
232 223
                /* if invalid instruction, signal it */
233 224
                if (ret != 0) {
234 225
                    /* NOTE: the tb is allocated but not linked, so we
......
237 228
                    raise_exception(EXCP06_ILLOP);
238 229
                }
239 230
                *ptb = tb;
240
                tb->size = code_size;
241
                tb->cs_base = (unsigned long)cs_base;
242
                tb->flags = flags;
243 231
                tb->hash_next = NULL;
244 232
                tb_link(tb);
245 233
                code_gen_ptr = (void *)(((unsigned long)code_gen_ptr + code_gen_size + CODE_GEN_ALIGN - 1) & ~(CODE_GEN_ALIGN - 1));
......
323 311

  
324 312
    saved_env = env;
325 313
    env = s;
326
    load_seg(seg_reg, selector);
314
    if (env->eflags & VM_MASK) {
315
        SegmentCache *sc;
316
        selector &= 0xffff;
317
        sc = &env->seg_cache[seg_reg];
318
        /* NOTE: in VM86 mode, limit and seg_32bit are never reloaded,
319
           so we must load them here */
320
        sc->base = (void *)(selector << 4);
321
        sc->limit = 0xffff;
322
        sc->seg_32bit = 0;
323
        env->segs[seg_reg] = selector;
324
    } else {
325
        load_seg(seg_reg, selector, 0);
326
    }
327 327
    env = saved_env;
328 328
}
329 329

  
......
346 346
static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
347 347
                                    int is_write, sigset_t *old_set)
348 348
{
349
    TranslationBlock *tb;
350
    int ret;
351
    uint32_t found_pc;
352
    
349 353
#if defined(DEBUG_SIGNAL)
350 354
    printf("qemu: SIGSEGV pc=0x%08lx address=%08lx wr=%d oldset=0x%08lx\n", 
351 355
           pc, address, is_write, *(unsigned long *)old_set);
......
354 358
    if (is_write && page_unprotect(address)) {
355 359
        return 1;
356 360
    }
357
    if (pc >= (unsigned long)code_gen_buffer &&
358
        pc < (unsigned long)code_gen_buffer + CODE_GEN_BUFFER_SIZE) {
361
    tb = tb_find_pc(pc);
362
    if (tb) {
359 363
        /* the PC is inside the translated code. It means that we have
360 364
           a virtual CPU fault */
365
        ret = cpu_x86_search_pc(tb, &found_pc, pc);
366
        if (ret < 0)
367
            return 0;
368
        env->eip = found_pc - tb->cs_base;
369
        env->cr2 = address;
361 370
        /* we restore the process signal mask as the sigreturn should
362
           do it */
371
           do it (XXX: use sigsetjmp) */
363 372
        sigprocmask(SIG_SETMASK, old_set, NULL);
364
        /* XXX: need to compute virtual pc position by retranslating
365
           code. The rest of the CPU state should be correct. */
366
        env->cr2 = address;
367 373
        raise_exception_err(EXCP0E_PAGE, 4 | (is_write << 1));
368 374
        /* never comes here */
369 375
        return 1;

Also available in: Unified diff