/[qemu]/qemu/exec-i386.c
ViewVC logotype

Diff of /qemu/exec-i386.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.24 by bellard, Sun May 25 19:20:31 2003 UTC revision 1.25 by bellard, Tue May 27 23:29:24 2003 UTC
# Line 39  void cpu_unlock(void) Line 39  void cpu_unlock(void)
39      spin_unlock(&global_cpu_lock);      spin_unlock(&global_cpu_lock);
40  }  }
41    
42  /* exception support */  void cpu_loop_exit(void)
 /* NOTE: not static to force relocation generation by GCC */  
 void raise_exception_err(int exception_index, int error_code)  
43  {  {
44      /* NOTE: the register at this point must be saved by hand because      /* NOTE: the register at this point must be saved by hand because
45         longjmp restore them */         longjmp restore them */
# Line 76  void raise_exception_err(int exception_i Line 74  void raise_exception_err(int exception_i
74  #ifdef reg_EDI  #ifdef reg_EDI
75      env->regs[R_EDI] = EDI;      env->regs[R_EDI] = EDI;
76  #endif  #endif
     env->exception_index = exception_index;  
     env->error_code = error_code;  
77      longjmp(env->jmp_env, 1);      longjmp(env->jmp_env, 1);
78  }  }
79    
 /* short cut if error_code is 0 or not present */  
 void raise_exception(int exception_index)  
 {  
     raise_exception_err(exception_index, 0);  
 }  
   
80  int cpu_x86_exec(CPUX86State *env1)  int cpu_x86_exec(CPUX86State *env1)
81  {  {
82      int saved_T0, saved_T1, saved_A0;      int saved_T0, saved_T1, saved_A0;
# Line 115  int cpu_x86_exec(CPUX86State *env1) Line 105  int cpu_x86_exec(CPUX86State *env1)
105  #ifdef reg_EDI  #ifdef reg_EDI
106      int saved_EDI;      int saved_EDI;
107  #endif  #endif
108      int code_gen_size, ret, code_size;      int code_gen_size, ret;
109      void (*gen_func)(void);      void (*gen_func)(void);
110      TranslationBlock *tb, **ptb;      TranslationBlock *tb, **ptb;
111      uint8_t *tc_ptr, *cs_base, *pc;      uint8_t *tc_ptr, *cs_base, *pc;
# Line 172  int cpu_x86_exec(CPUX86State *env1) Line 162  int cpu_x86_exec(CPUX86State *env1)
162          T0 = 0; /* force lookup of first TB */          T0 = 0; /* force lookup of first TB */
163          for(;;) {          for(;;) {
164              if (env->interrupt_request) {              if (env->interrupt_request) {
165                  raise_exception(EXCP_INTERRUPT);                  env->exception_index = EXCP_INTERRUPT;
166                    cpu_loop_exit();
167              }              }
168  #ifdef DEBUG_EXEC  #ifdef DEBUG_EXEC
169              if (loglevel) {              if (loglevel) {
# Line 226  int cpu_x86_exec(CPUX86State *env1) Line 217  int cpu_x86_exec(CPUX86State *env1)
217                  }                  }
218                  tc_ptr = code_gen_ptr;                  tc_ptr = code_gen_ptr;
219                  tb->tc_ptr = tc_ptr;                  tb->tc_ptr = tc_ptr;
220                  ret = cpu_x86_gen_code(code_gen_ptr, CODE_GEN_MAX_SIZE,                  tb->cs_base = (unsigned long)cs_base;
221                                         &code_gen_size, pc, cs_base, flags,                  tb->flags = flags;
222                                         &code_size, tb);                  ret = cpu_x86_gen_code(tb, CODE_GEN_MAX_SIZE, &code_gen_size);
223                  /* if invalid instruction, signal it */                  /* if invalid instruction, signal it */
224                  if (ret != 0) {                  if (ret != 0) {
225                      /* NOTE: the tb is allocated but not linked, so we                      /* NOTE: the tb is allocated but not linked, so we
# Line 237  int cpu_x86_exec(CPUX86State *env1) Line 228  int cpu_x86_exec(CPUX86State *env1)
228                      raise_exception(EXCP06_ILLOP);                      raise_exception(EXCP06_ILLOP);
229                  }                  }
230                  *ptb = tb;                  *ptb = tb;
                 tb->size = code_size;  
                 tb->cs_base = (unsigned long)cs_base;  
                 tb->flags = flags;  
231                  tb->hash_next = NULL;                  tb->hash_next = NULL;
232                  tb_link(tb);                  tb_link(tb);
233                  code_gen_ptr = (void *)(((unsigned long)code_gen_ptr + code_gen_size + CODE_GEN_ALIGN - 1) & ~(CODE_GEN_ALIGN - 1));                  code_gen_ptr = (void *)(((unsigned long)code_gen_ptr + code_gen_size + CODE_GEN_ALIGN - 1) & ~(CODE_GEN_ALIGN - 1));
# Line 323  void cpu_x86_load_seg(CPUX86State *s, in Line 311  void cpu_x86_load_seg(CPUX86State *s, in
311    
312      saved_env = env;      saved_env = env;
313      env = s;      env = s;
314      load_seg(seg_reg, selector);      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      env = saved_env;      env = saved_env;
328  }  }
329    
# Line 346  void cpu_x86_load_seg(CPUX86State *s, in Line 346  void cpu_x86_load_seg(CPUX86State *s, in
346  static inline int handle_cpu_signal(unsigned long pc, unsigned long address,  static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
347                                      int is_write, sigset_t *old_set)                                      int is_write, sigset_t *old_set)
348  {  {
349        TranslationBlock *tb;
350        int ret;
351        uint32_t found_pc;
352        
353  #if defined(DEBUG_SIGNAL)  #if defined(DEBUG_SIGNAL)
354      printf("qemu: SIGSEGV pc=0x%08lx address=%08lx wr=%d oldset=0x%08lx\n",      printf("qemu: SIGSEGV pc=0x%08lx address=%08lx wr=%d oldset=0x%08lx\n",
355             pc, address, is_write, *(unsigned long *)old_set);             pc, address, is_write, *(unsigned long *)old_set);
# Line 354  static inline int handle_cpu_signal(unsi Line 358  static inline int handle_cpu_signal(unsi
358      if (is_write && page_unprotect(address)) {      if (is_write && page_unprotect(address)) {
359          return 1;          return 1;
360      }      }
361      if (pc >= (unsigned long)code_gen_buffer &&      tb = tb_find_pc(pc);
362          pc < (unsigned long)code_gen_buffer + CODE_GEN_BUFFER_SIZE) {      if (tb) {
363          /* the PC is inside the translated code. It means that we have          /* the PC is inside the translated code. It means that we have
364             a virtual CPU fault */             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;
370          /* we restore the process signal mask as the sigreturn should          /* we restore the process signal mask as the sigreturn should
371             do it */             do it (XXX: use sigsetjmp) */
372          sigprocmask(SIG_SETMASK, old_set, NULL);          sigprocmask(SIG_SETMASK, old_set, NULL);
         /* XXX: need to compute virtual pc position by retranslating  
            code. The rest of the CPU state should be correct. */  
         env->cr2 = address;  
373          raise_exception_err(EXCP0E_PAGE, 4 | (is_write << 1));          raise_exception_err(EXCP0E_PAGE, 4 | (is_write << 1));
374          /* never comes here */          /* never comes here */
375          return 1;          return 1;

Legend:
Removed from v.1.24  
changed lines
  Added in v.1.25

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26