Annotation of kernel/machdep/i386/pc_support/PCemulatePROT.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
                      3:  *
                      4:  * @APPLE_LICENSE_HEADER_START@
                      5:  * 
                      6:  * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
                      7:  * Reserved.  This file contains Original Code and/or Modifications of
                      8:  * Original Code as defined in and that are subject to the Apple Public
                      9:  * Source License Version 1.1 (the "License").  You may not use this file
                     10:  * except in compliance with the License.  Please obtain a copy of the
                     11:  * License at http://www.apple.com/publicsource and read it before using
                     12:  * this file.
                     13:  * 
                     14:  * The Original Code and all software distributed under the License are
                     15:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
                     16:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
                     17:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
                     18:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
                     19:  * License for the specific language governing rights and limitations
                     20:  * under the License.
                     21:  * 
                     22:  * @APPLE_LICENSE_HEADER_END@
                     23:  */
                     24: 
                     25: /*
                     26:  * Copyright (c) 1993 NeXT Computer, Inc.
                     27:  *
                     28:  * Protected mode emulation.
                     29:  *
                     30:  * HISTORY
                     31:  *
                     32:  * 8 Apr 1993 ? at NeXT
                     33:  *     Created.
                     34:  */
                     35: 
                     36: #import <mach/mach_types.h>
                     37: 
                     38: #import <architecture/i386/sel.h>
                     39: #import <architecture/i386/table.h>
                     40: 
                     41: #import <machdep/i386/trap.h>
                     42: #import <machdep/i386/desc_inline.h>
                     43: #import <machdep/i386/err_inline.h>
                     44: 
                     45: #import "PCprivate.h"
                     46: #import "PCmiscInline.h"
                     47: #import "PCtaskInline.h"
                     48: 
                     49: static __inline__
                     50: boolean_t
                     51: fetch_LDT_entry(
                     52:     thread_t           thread,
                     53:     unsigned int       index,
                     54:     ldt_entry_t                *desc
                     55: )
                     56: {
                     57:     PCshared_t         shared = threadPCShared(thread);
                     58:     unsigned int       byte_index = index * sizeof (ldt_entry_t);
                     59:     
                     60:     if (shared->LDT.length <= byte_index)
                     61:        return (FALSE);
                     62:        
                     63:     return (fetch8Byte(thread, shared->LDT.address + byte_index, desc));
                     64: }
                     65: 
                     66: static __inline__
                     67: boolean_t
                     68: fetch_IDT_entry(
                     69:     thread_t           thread,
                     70:     unsigned int       index,
                     71:     idt_entry_t                *desc
                     72: )
                     73: {
                     74:     PCshared_t         shared = threadPCShared(thread);
                     75:     unsigned int       byte_index = index * sizeof (ldt_entry_t);
                     76:     
                     77:     if (shared->IDT.length <= byte_index)
                     78:        return (FALSE);
                     79:        
                     80:     return (fetch8Byte(thread, shared->IDT.address + byte_index, desc));
                     81: }
                     82: 
                     83: static
                     84: boolean_t
                     85: fetch_desc(
                     86:     thread_t           thread,
                     87:     sel_t              sel,
                     88:     dt_entry_t         *desc
                     89: )
                     90: {
                     91:     if (sel.ti != SEL_LDT)
                     92:        return (FALSE);
                     93:        
                     94:     return (fetch_LDT_entry(thread, sel.index, (ldt_entry_t *)desc));
                     95: }
                     96: 
                     97: static __inline__
                     98: vm_offset_t
                     99: segment_base(
                    100:     data_desc_t                *desc
                    101: )
                    102: {
                    103:     conv_base_t                _base = { 0 };
                    104:     
                    105:     _base.fields.base00 = desc->base00;
                    106:     _base.fields.base16 = desc->base16;
                    107:     _base.fields.base24 = desc->base24;
                    108:     
                    109:     return (_base.word);
                    110: }
                    111: 
                    112: static __inline__
                    113: boolean_t
                    114: fetch_segment_4byte(
                    115:     thread_t           thread,
                    116:     data_desc_t                *desc,
                    117:     vm_offset_t                offset,
                    118:     boolean_t          offsz,
                    119:     unsigned int       *data
                    120: )
                    121: {
                    122:     vm_offset_t                base = segment_base(desc);
                    123: 
                    124:     if (!offsz)
                    125:        offset &= 0xffff;
                    126:        
                    127:     return (fetch4Byte(thread, base + offset, data));
                    128: }
                    129: 
                    130: static
                    131: boolean_t __inline__
                    132: fetch_segment(
                    133:     thread_t           thread,
                    134:     data_desc_t                *desc,
                    135:     vm_offset_t                offset,
                    136:     boolean_t          offsz,
                    137:     void               *data,
                    138:     unsigned int       length
                    139: )
                    140: {
                    141: #define sdata          ((unsigned short *)data)
                    142:     vm_offset_t                base = segment_base(desc);
                    143:     unsigned int       offmsk;
                    144:     
                    145:     if (offsz)
                    146:        offmsk = 0xffffffff;
                    147:     else
                    148:        offmsk = 0xffff;
                    149: 
                    150:     thread->recover = (vm_offset_t)&&fault;
                    151:     
                    152:     while (length > 0) {
                    153:        offset &= offmsk;
                    154: 
                    155:        asm volatile(
                    156:            "movw %%fs:%1,%0"
                    157:                    : "=q" (*sdata)
                    158:                    : "m" (*(unsigned short *)(base + offset)));
                    159:                    
                    160:        sdata++; offset += sizeof (*sdata); length -= sizeof (*sdata);
                    161:     }
                    162:     
                    163:     thread->recover = 0;
                    164:     return (TRUE);
                    165:     
                    166: fault:
                    167:     thread->recover = 0;
                    168:     return (FALSE);
                    169: 
                    170: #undef sdata
                    171: }
                    172: 
                    173: static __inline__
                    174: boolean_t
                    175: store_segment(
                    176:     thread_t           thread,
                    177:     data_desc_t                *desc,
                    178:     vm_offset_t                offset,
                    179:     boolean_t          offsz,
                    180:     void               *data,
                    181:     unsigned int       length
                    182: )
                    183: {
                    184: #define sdata          ((unsigned short *)data)
                    185:     vm_offset_t                base = segment_base(desc);
                    186:     unsigned int       offmsk;
                    187:     
                    188:     if (offsz)
                    189:        offmsk = 0xffffffff;
                    190:     else
                    191:        offmsk = 0xffff;
                    192: 
                    193:     thread->recover = (vm_offset_t)&&fault;
                    194:     
                    195:     while (length > 0) {
                    196:        offset &= offmsk;
                    197: 
                    198:        asm volatile(
                    199:            "movw %0,%%fs:%1"
                    200:                    :
                    201:                    : "r" (*sdata), "m" (*(unsigned short *)(base + offset)));
                    202:                    
                    203:        sdata++; offset += sizeof (*sdata); length -= sizeof (*sdata);
                    204:     }
                    205:     
                    206:     thread->recover = 0;
                    207:     return (TRUE);
                    208:     
                    209: fault:
                    210:     thread->recover = 0;
                    211:     return (FALSE);
                    212: 
                    213: #undef sdata
                    214: }
                    215: 
                    216: static
                    217: boolean_t
                    218: handle_bop(
                    219:     thread_t                   thread,
                    220:     thread_saved_state_t       *state
                    221: )
                    222: {
                    223:     PCcontext_t                context = threadPCContext(thread);
                    224:     code_desc_t                code;
                    225:     data_desc_t                stack;
                    226:     unsigned int       inst;
                    227:     unsigned char      bbyte;
                    228:     
                    229:     if (!fetch_desc(thread, state->frame.cs, (dt_entry_t *)&code))
                    230:        return (FALSE);
                    231:     
                    232:     if (!fetch_segment_4byte(
                    233:                        thread,
                    234:                        (data_desc_t *)&code, state->frame.eip, code.opsz,
                    235:                        &inst))
                    236:        return (FALSE);
                    237:        
                    238:     if (*(unsigned short *)&inst != 0xC4C4)
                    239:        return (FALSE);
                    240:        
                    241:     bbyte = *((unsigned char *)&inst + 2);
                    242:        
                    243:     if (bbyte == 0xFE) {
                    244:        PCcancelTimers(context);
                    245:        
                    246:        context->callHandler = PC_HANDLE_EXIT;
                    247:        
                    248:        PCcallMonitor(thread, state);
                    249:        /* NOTREACHED */
                    250:     }
                    251:     else if (bbyte == 0xFA) {
                    252:        PCbopFA_t       args;
                    253: 
                    254:        if (!fetch_desc(thread, state->frame.ss, (dt_entry_t *)&stack))
                    255:            return (FALSE);
                    256:        
                    257:        if (!fetch_segment(
                    258:                        thread,
                    259:                        &stack, state->frame.esp, stack.stksz,
                    260:                        &args, sizeof (args)))
                    261:            return (FALSE);
                    262:            
                    263:        return (PCbopFA(thread, state, &args));
                    264:     }
                    265:     else if (bbyte == 0xFC) {
                    266:        PCbopFC_t       args;
                    267: 
                    268:        if (!fetch_desc(thread, state->frame.ss, (dt_entry_t *)&stack))
                    269:            return (FALSE);
                    270:        
                    271:        if (!fetch_segment(
                    272:                        thread,
                    273:                        &stack, state->frame.esp, stack.stksz,
                    274:                        &args, sizeof (args)))
                    275:            return (FALSE);
                    276:            
                    277:        return (PCbopFC(thread, state, &args));
                    278:        /* NOTREACHED */
                    279:     }
                    280:     else if (bbyte == 0xFD) {
                    281:        PCbopFD_t       args;
                    282: 
                    283:        if (!fetch_desc(thread, state->frame.ss, (dt_entry_t *)&stack))
                    284:            return (FALSE);
                    285:        
                    286:        if (!fetch_segment(
                    287:                        thread,
                    288:                        &stack, state->frame.esp, stack.stksz,
                    289:                        &args, sizeof (args)))
                    290:            return (FALSE);
                    291:            
                    292:        PCbopFD(thread, state, &args);
                    293:        /* NOTREACHED */
                    294:     }  
                    295:     else {
                    296:        context->trapNum = bbyte;
                    297:        context->callHandler = PC_HANDLE_BOP;
                    298:        
                    299:        PCcallMonitor(thread, state);
                    300:        /* NOTREACHED */
                    301:     }
                    302: }
                    303: 
                    304: static
                    305: boolean_t
                    306: emulate_CLI(
                    307:     thread_t                   thread,
                    308:     thread_saved_state_t       *state,
                    309:     code_desc_t                        *desc
                    310: )
                    311: {
                    312:     PCcontext_t                context = threadPCContext(thread);
                    313: 
                    314:     if (desc->opsz)    
                    315:        state->frame.eip += 1;
                    316:     else
                    317:        (unsigned short)state->frame.eip += 1;
                    318:        
                    319:     context->IF_flag = FALSE;
                    320:     
                    321:     return (TRUE);
                    322: }
                    323: 
                    324: static
                    325: boolean_t
                    326: emulate_STI(
                    327:     thread_t                   thread,
                    328:     thread_saved_state_t       *state,
                    329:     code_desc_t                        *desc
                    330: )
                    331: {
                    332:     PCcontext_t                context = threadPCContext(thread);
                    333: 
                    334:     if (desc->opsz)    
                    335:        state->frame.eip += 1;
                    336:     else
                    337:        (unsigned short)state->frame.eip += 1;
                    338:     
                    339:     if (!context->IF_flag) {
                    340:        context->IF_flag = TRUE;
                    341:        
                    342:        context->pendingCallbacks |= (context->runOptions & PC_RUN_IF_SET);
                    343:     }
                    344:     
                    345:     return (TRUE);
                    346: }
                    347: 
                    348: static
                    349: boolean_t
                    350: push_frame16_err_code(
                    351:     thread_t                   thread,
                    352:     thread_saved_state_t       *state,
                    353:     boolean_t                  IF_flag,
                    354:     err_code_t                 err
                    355: )
                    356: {
                    357:     struct {
                    358:        unsigned short  err;
                    359:        unsigned short  ip;
                    360:        sel_t           cs;
                    361:        unsigned short  flags;
                    362:     }                          frame;    
                    363:     data_desc_t                        stack;
                    364:        
                    365:     if (!fetch_desc(thread, state->frame.ss, (dt_entry_t *)&stack))
                    366:        return (FALSE);         /* not possible */
                    367:        
                    368:     frame.err = err_to_error_code(err);
                    369: 
                    370:     frame.ip = state->frame.eip;
                    371:     frame.cs = state->frame.cs;
                    372:     
                    373:     frame.flags = state->frame.eflags;
                    374:     if (IF_flag)
                    375:        frame.flags |= EFL_IF;
                    376:     else
                    377:        frame.flags &= ~EFL_IF;
                    378:        
                    379:     if (!store_segment(
                    380:                    thread,
                    381:                    &stack,
                    382:                    state->frame.esp - sizeof (frame), stack.stksz,
                    383:                    &frame, sizeof (frame)))
                    384:        return (FALSE);
                    385: 
                    386:     if (stack.stksz)
                    387:        state->frame.esp -= sizeof (frame);
                    388:     else 
                    389:        (unsigned short)state->frame.esp -= sizeof (frame);
                    390:     
                    391:     return (TRUE);
                    392: }
                    393: 
                    394: static
                    395: boolean_t
                    396: push_frame16(
                    397:     thread_t                   thread,
                    398:     thread_saved_state_t       *state,
                    399:     boolean_t                  IF_flag
                    400: )
                    401: {
                    402:     struct {
                    403:        unsigned short  ip;
                    404:        sel_t           cs;
                    405:        unsigned short  flags;
                    406:     }                          frame;    
                    407:     data_desc_t                        stack;
                    408:        
                    409:     if (!fetch_desc(thread, state->frame.ss, (dt_entry_t *)&stack))
                    410:        return (FALSE);         /* not possible */
                    411: 
                    412:     frame.ip = state->frame.eip;
                    413:     frame.cs = state->frame.cs;
                    414:     
                    415:     frame.flags = state->frame.eflags;
                    416:     if (IF_flag)
                    417:        frame.flags |= EFL_IF;
                    418:     else
                    419:        frame.flags &= ~EFL_IF;
                    420:        
                    421:     if (!store_segment(
                    422:                    thread,
                    423:                    &stack,
                    424:                    state->frame.esp - sizeof (frame), stack.stksz,
                    425:                    &frame, sizeof (frame)))
                    426:        return (FALSE);
                    427: 
                    428:     if (stack.stksz)
                    429:        state->frame.esp -= sizeof (frame);
                    430:     else 
                    431:        (unsigned short)state->frame.esp -= sizeof (frame);
                    432:     
                    433:     return (TRUE);
                    434: }
                    435: 
                    436: static
                    437: boolean_t
                    438: push_frame32_err_code(
                    439:     thread_t                   thread,
                    440:     thread_saved_state_t       *state,
                    441:     boolean_t                  IF_flag,
                    442:     err_code_t                 err
                    443: )
                    444: {
                    445:     struct {
                    446:        err_code_t      err;
                    447:        unsigned int    eip;
                    448:        sel_t           cs;
                    449:        unsigned short          :16;
                    450:        unsigned int    eflags;
                    451:     }                          frame;    
                    452:     data_desc_t                        stack;
                    453:        
                    454:     if (!fetch_desc(thread, state->frame.ss, (dt_entry_t *)&stack))
                    455:        return (FALSE);         /* not possible */
                    456:        
                    457:     frame.err = err;
                    458: 
                    459:     frame.eip = state->frame.eip;
                    460:     frame.cs = state->frame.cs;
                    461:     
                    462:     frame.eflags = state->frame.eflags;
                    463:     if (IF_flag)
                    464:        frame.eflags |= EFL_IF;
                    465:     else
                    466:        frame.eflags &= ~EFL_IF;
                    467: 
                    468:     if (!store_segment(
                    469:                    thread,
                    470:                    &stack,
                    471:                    state->frame.esp - sizeof (frame), stack.stksz,
                    472:                    &frame, sizeof (frame)))
                    473:        return (FALSE);
                    474: 
                    475:     if (stack.stksz)
                    476:        state->frame.esp -= sizeof (frame);
                    477:     else 
                    478:        (unsigned short)state->frame.esp -= sizeof (frame);
                    479:     
                    480:     return (TRUE);
                    481: }
                    482: 
                    483: static
                    484: boolean_t
                    485: push_frame32(
                    486:     thread_t                   thread,
                    487:     thread_saved_state_t       *state,
                    488:     boolean_t                  IF_flag
                    489: )
                    490: {
                    491:     struct {
                    492:        unsigned int    eip;
                    493:        sel_t           cs;
                    494:        unsigned short          :16;
                    495:        unsigned int    eflags;
                    496:     }                          frame;    
                    497:     data_desc_t                        stack;
                    498:        
                    499:     if (!fetch_desc(thread, state->frame.ss, (dt_entry_t *)&stack))
                    500:        return (FALSE);         /* not possible */
                    501: 
                    502:     frame.eip = state->frame.eip;
                    503:     frame.cs = state->frame.cs;
                    504:     
                    505:     frame.eflags = state->frame.eflags;
                    506:     if (IF_flag)
                    507:        frame.eflags |= EFL_IF;
                    508:     else
                    509:        frame.eflags &= ~EFL_IF;
                    510:        
                    511:     if (!store_segment(
                    512:                    thread,
                    513:                    &stack,
                    514:                    state->frame.esp - sizeof (frame), stack.stksz,
                    515:                    &frame, sizeof (frame)))
                    516:        return (FALSE);
                    517:        
                    518:     if (stack.stksz)
                    519:        state->frame.esp -= sizeof (frame);
                    520:     else 
                    521:        (unsigned short)state->frame.esp -= sizeof (frame);
                    522:     
                    523:     return (TRUE);
                    524: }
                    525: 
                    526: static __inline__
                    527: void
                    528: enter_gate(
                    529:     except_frame_t     *frame,
                    530:     trap_gate_t                *gate,
                    531:     boolean_t          preserve_trace
                    532: )
                    533: {
                    534:     conv_offset_t              _offset = { 0 };
                    535:     
                    536:     _offset.fields.offset00 = gate->offset00;
                    537:     _offset.fields.offset16 = gate->offset16;
                    538:     
                    539:     frame->eip = _offset.word;
                    540:     frame->cs = gate->seg;
                    541: 
                    542:     if (!preserve_trace)       
                    543:        frame->eflags &= ~EFL_TF;
                    544: }
                    545: 
                    546: static
                    547: boolean_t
                    548: emulate_exception(
                    549:     thread_t                   thread,
                    550:     thread_saved_state_t       *state,
                    551:     int                                trapno,
                    552:     err_code_t                 err,
                    553:     boolean_t                  inhibit_err_code
                    554: )
                    555: {
                    556:     PCcontext_t                        context;
                    557:     trap_gate_t                        gate;
                    558:     boolean_t                  is_intr, is_32bit;
                    559:     code_desc_t                        code;
                    560:     
                    561:     context = threadPCContext(thread);
                    562:     
                    563:     if (!fetch_IDT_entry(thread, trapno, (idt_entry_t *)&gate))
                    564:        return (FALSE);         /* GP(trapno*8+2+EXT) */
                    565: 
                    566:     switch (gate.type) {
                    567:        
                    568:     case DESC_INTR_GATE:
                    569:        is_32bit = TRUE;
                    570:        is_intr = TRUE;
                    571:        break;
                    572:     
                    573:     case DESC_TRAP_GATE:
                    574:        is_32bit = TRUE;
                    575:        is_intr = FALSE;
                    576:        break;
                    577:        
                    578:     case 0x06:
                    579:        is_32bit = FALSE;
                    580:        is_intr = TRUE;
                    581:        break;
                    582:        
                    583:     case 0x07:
                    584:        is_32bit = FALSE;
                    585:        is_intr = FALSE;
                    586:        break;
                    587:        
                    588:     default:
                    589:        return (FALSE);         /* GP(trapno*8+2+EXT) */
                    590:     }
                    591:        
                    592:     if (!gate.present)
                    593:        return (FALSE);         /* NP(trapno*8+2+EXT) */
                    594:        
                    595:     if (!fetch_desc(thread, gate.seg, (dt_entry_t *)&code))
                    596:        return (FALSE);         /* GP(selector+EXT) */
                    597:        
                    598:     if ((code.type & 0x18) != 0x18) // if (!code)
                    599:        return (FALSE);         /* GP(selector+EXT) */
                    600:        
                    601:     if (!code.present)
                    602:        return (FALSE);         /* NP(selector+EXT) */
                    603:        
                    604:     if (inhibit_err_code || (trapno < 8) || trapno == 16 || (trapno > 17)) {
                    605:        if (is_32bit) {
                    606:            if (!push_frame32(thread, state, context->IF_flag))
                    607:                return (FALSE);
                    608:        }
                    609:        else {
                    610:            if (!push_frame16(thread, state, context->IF_flag))
                    611:                return (FALSE);
                    612:        }
                    613:     }
                    614:     else
                    615:     {
                    616:        if (is_32bit) {
                    617:            if (!push_frame32_err_code(thread, state, context->IF_flag, err))
                    618:                return (FALSE);
                    619:        }
                    620:        else {
                    621:            if (!push_frame16_err_code(thread, state, context->IF_flag, err))
                    622:                return (FALSE);
                    623:        }
                    624:     }
                    625: 
                    626: #define preserveTrace ((context->debugOptions & PC_DEBUG_PRESERVE_TRACE) != 0)
                    627:     enter_gate(&state->frame, &gate, preserveTrace);
                    628: #undef preserveTrace
                    629:     
                    630:     if (is_intr)
                    631:        context->IF_flag = FALSE;
                    632: 
                    633:     return (TRUE);
                    634: }
                    635: 
                    636: static
                    637: boolean_t
                    638: handle_exception(
                    639:     thread_t                   thread,
                    640:     thread_saved_state_t       *state
                    641: )
                    642: {
                    643:     PCshared_t                 shared;
                    644:     PCcontext_t                        context;
                    645:     
                    646:     shared = threadPCShared(thread);
                    647:     context = currentContext(shared);
                    648:     
                    649:     if (maskIsSet(&shared->faultMask, state->trapno)) {
                    650:        context->trapNum = state->trapno;
                    651:        context->errCode = err_to_error_code(state->frame.err);
                    652:        context->callHandler = PC_HANDLE_FAULT;
                    653:        
                    654:        PCcallMonitor(thread, state);
                    655:        /* NOTREACHED */
                    656:     }
                    657:        
                    658:     if (!emulate_exception(
                    659:                        thread,
                    660:                        state, state->trapno, state->frame.err,
                    661:                        FALSE))
                    662:        return (FALSE);
                    663:     
                    664:     return (TRUE);
                    665: }
                    666: 
                    667: static
                    668: boolean_t
                    669: emulate_INTn(
                    670:     thread_t                   thread,
                    671:     thread_saved_state_t       *state,
                    672:     code_desc_t                        *desc,
                    673:     unsigned int               inst
                    674: )
                    675: {
                    676:     PCshared_t                 shared;
                    677:     PCcontext_t                        context;
                    678:     unsigned char              trapno;
                    679:     err_code_t                 err = { 0 };
                    680: 
                    681:     shared = threadPCShared(thread);
                    682:     context = currentContext(shared);
                    683:     
                    684:     trapno = *((unsigned char *)&inst + 1);
                    685:        
                    686:     if (maskIsSet(&shared->intNMask, trapno)) {
                    687:        context->trapNum = trapno;
                    688:        context->errCode = 0;
                    689:        if (trapno <= 7)
                    690:            context->callHandler = PC_HANDLE_FAULT;
                    691:        else
                    692:            context->callHandler = PC_HANDLE_INTN;
                    693:        
                    694:        PCcallMonitor(thread, state);
                    695:        /* NOTREACHED */
                    696:     }
                    697: 
                    698:     if (desc->opsz)    
                    699:        state->frame.eip += 2;
                    700:     else
                    701:        (unsigned short)state->frame.eip += 2;
                    702:     
                    703:     if (!emulate_exception(thread, state, trapno, err, TRUE)) {
                    704:        if (desc->opsz) 
                    705:            state->frame.eip -= 2;
                    706:        else
                    707:            (unsigned short)state->frame.eip -= 2;
                    708:        return (FALSE);
                    709:     }
                    710:     
                    711:     return (TRUE);
                    712: }
                    713: 
                    714: static
                    715: boolean_t
                    716: emulate_instruction(
                    717:     thread_t                   thread,
                    718:     thread_saved_state_t       *state
                    719: )
                    720: {
                    721:     code_desc_t                code;
                    722:     unsigned int       inst;
                    723:     unsigned char      ibyte;
                    724:     
                    725:     if (!fetch_desc(thread, state->frame.cs, (dt_entry_t *)&code))
                    726:        return (FALSE);
                    727:        
                    728:     if (!fetch_segment_4byte(
                    729:                        thread,
                    730:                        (data_desc_t *)&code, state->frame.eip, code.opsz,
                    731:                        &inst))
                    732:        return (FALSE);
                    733:        
                    734:     ibyte = *(unsigned char *)&inst;
                    735:        
                    736:     if (ibyte == 0xCD)
                    737:        return (emulate_INTn(thread, state, &code, inst));
                    738:        
                    739:     if (ibyte == 0xFA)
                    740:        return (emulate_CLI(thread, state, &code));
                    741:        
                    742:     if (ibyte == 0xFB)
                    743:        return (emulate_STI(thread, state, &code));
                    744:        
                    745:     return (FALSE);
                    746: }
                    747: 
                    748: boolean_t
                    749: PCemulatePROT(
                    750:     thread_t                   thread,
                    751:     thread_saved_state_t       *state
                    752: )
                    753: {
                    754:     if (state->trapno == T_GENERAL_PROTECTION) {
                    755:        if (!emulate_instruction(thread,state))
                    756:            return handle_exception(thread, state);
                    757:        else
                    758:            return TRUE;
                    759:     }
                    760:     else
                    761:     if (state->trapno == T_INVALID_OPCODE) {
                    762:        if (!handle_bop(thread, state))
                    763:            return handle_exception(thread, state);
                    764:        else
                    765:            return TRUE;
                    766:     }
                    767:     else
                    768:        return handle_exception(thread, state);
                    769: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.