Public bug reported:

Here is interrupt handler in the decode.c file:

static void x86emu_intr_handle(void)
{
        u8      intno;

        if (M.x86.intr & INTR_SYNCH) {
                intno = M.x86.intno;
                if (_X86EMU_intrTab[intno]) {
                        (*_X86EMU_intrTab[intno])(intno);
                } else {
                        push_word((u16)M.x86.R_FLG);
                        CLEAR_FLAG(F_IF);
                        CLEAR_FLAG(F_TF);
                        push_word(M.x86.R_CS);
                        M.x86.R_CS = mem_access_word(intno * 4 + 2);
                        push_word(M.x86.R_IP);
                        M.x86.R_IP = mem_access_word(intno * 4);
                        M.x86.intr = 0;
                }
        }
}

If execution goes in the first branch,  
(_X86EMU_intrTab[intno]) {
                        (*_X86EMU_intrTab[intno])(intno);

M.x86.intr flag is not cleared in the interrupt preparation function in
the table ( file thunk.c ):

static void x86emu_do_int(int num)
{
        u32 eflags;
        
        /*      fprintf(stderr, "Calling INT 0x%X (%04X:%04X)\n", num,
                        (read_b((num << 2) + 3) << 8) + read_b((num << 2) + 2),
                        (read_b((num << 2) + 1) << 8) + read_b((num << 2)));
        
        fprintf(stderr, " EAX is %X\n", (int) X86_EAX);
        */

        eflags = X86_EFLAGS;
        eflags = eflags | X86_IF_MASK;
        pushw(eflags);
        pushw(X86_CS);
        pushw(X86_IP);
        X86_EFLAGS = X86_EFLAGS & ~(X86_VIF_MASK | X86_TF_MASK);
        X86_CS = (read_b((num << 2) + 3) << 8) + read_b((num << 2) + 2);
        X86_IP = (read_b((num << 2) + 1) << 8) + read_b((num << 2));

        /*      fprintf(stderr, "Leaving interrupt call.\n"); */
}

thus, the handler is getting called at every iteration in the main
emulation processor loop (decode.c ) since having been initially raised.
Loop turns into indefinite one.  Verified today.

void X86EMU_exec(void)
{
        u8 op1;

        M.x86.intr = 0;
        DB(x86emu_end_instr();)

    for (;;) {
DB(             if (CHECK_IP_FETCH())
                  x86emu_check_ip_access();)
                /* If debugging, save the IP and CS values. */
                SAVE_IP_CS(M.x86.R_CS, M.x86.R_IP);
                INC_DECODED_INST_LEN(1);
                if (M.x86.intr) {     
                        if (M.x86.intr & INTR_HALTED) {      // ENTERED EVERY 
TIME after interrupt is raised - DK !!!
DB(                     
                                X86EMU_trace_regs();)
                                return;
            }
                        if (((M.x86.intr & INTR_SYNCH) && (M.x86.intno == 0 || 
M.x86.intno == 2)) ||
                                !ACCESS_FLAG(F_IF)) {
                                x86emu_intr_handle();
                        }
                }
                if ((M.x86.R_CS == 0) && (M.x86.R_IP == 0)) {
DB(                             
                                X86EMU_trace_regs();)
                                return;
                }

                op1 = (*sys_rdb)(((u32)M.x86.R_CS << 4) + (M.x86.R_IP++));
                //              fprintf (stderr, "%s", M.x86.decoded_buf);
                //              x86emu_dump_regs();
                (*x86emu_optab[op1])(op1);
    }
}


Package - Libx86_1.1, x86 Emulation part.
UBUNTU 10.04 LTS

** Affects: libx86 (Ubuntu)
     Importance: Undecided
         Status: New

-- 
You received this bug notification because you are a member of Ubuntu
Bugs, which is subscribed to Ubuntu.
https://bugs.launchpad.net/bugs/1041403

Title:
  In the x86 emu raised interrupt can be processed indefinitely over and
  over again under certain condition.

To manage notifications about this bug go to:
https://bugs.launchpad.net/ubuntu/+source/libx86/+bug/1041403/+subscriptions

-- 
ubuntu-bugs mailing list
[email protected]
https://lists.ubuntu.com/mailman/listinfo/ubuntu-bugs

Reply via email to