Annotation of coherent/b/bin/db/i386/i386db2.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * db/i386/i386db2.c
                      3:  * A debugger.
                      4:  * i386 disassembler.
                      5:  * Table-driven, using tables in i386db4.c.
                      6:  * A hearty thank-you to the architectural geniuses at Intel Corporation
                      7:  * who produced this simple and elegant design -- NOT.
                      8:  */
                      9: 
                     10: #include "i386db.h"
                     11: 
                     12: #define        MAX_INST_LEN    50      /* Max expanded opcode string length    */
                     13: #define        MAX_DISP_SIZE   6       /* Max displacement size in bytes       */
                     14: 
                     15: /* Instruction prefix codes. */
                     16: #define        ESC2    0x0F            /* Escape to 2-byte opcode      */
                     17: #define REP    0xF3
                     18: #define REPNE  0xF2
                     19: #define LOCK   0xF0
                     20: #define AD_PRE 0x67            /* Address size prefix          */
                     21: #define OP_PRE 0x66            /* Operand size prefix          */
                     22: #define CS_PRE 0x2E            /* CS: segment override prefix  */
                     23: #define DS_PRE 0x3E
                     24: #define ES_PRE 0x26
                     25: #define FS_PRE 0x64
                     26: #define GS_PRE 0x65
                     27: #define SS_PRE 0x36
                     28: 
                     29: #define EBP_SIB        5
                     30: 
                     31: /* Is_signed arg for get_value() et al.: unsigned or signed displacement. */
                     32: #define UNSIGNED       0
                     33: #define SIGNED         1
                     34: 
                     35: /* Flag arg for get_value(): absolute or PC-relative address. */
                     36: #define ABSOLUTE       0
                     37: #define PCREL          1
                     38: 
                     39: #define ADDRINDEX(x)   (x==32 ? 1 : 0) /* first index for modRMtab[]   */
                     40: #define TOLSYM         0x100           /* print symbol if greater      */
                     41: #define TOLHEX         0x10            /* print hexidecimal if greater */
                     42:                                        /* print decimal if less        */
                     43: 
                     44: /* Disassembler static data. */
                     45: static int             ad_pre_flag;    /* address size prefix flag     */
                     46: static long            delta;          /* displacement                 */
                     47: static unsigned char   ibp[MAX_DISP_SIZE];     /* input buffer         */
                     48: static unsigned char   m;              /* "Mod" field of ModR/M byte   */
                     49: static unsigned char   mRM;            /* "R/M" field of ModR/M byte   */
                     50: static unsigned char   mReg;           /* "REG" field of ModR/M byte   */
                     51: static int             modRM_flag;     /* ModR/M byte has been loaded  */
                     52: static char            *obp;           /* output buffer pointer        */
                     53: static int             op_pre_flag;    /* operand size prefix flag     */
                     54: static char            outbuf[MAX_INST_LEN];   /* output buffer        */
                     55: static int             segn;           /* segment number               */
                     56: static unsigned char   seg_prefix;     /* segment prefix, e.g. "cs:"   */
                     57: static int             sib_flag;       /* SIB byte has been loaded     */
                     58: static unsigned char   sb;             /* "base" field of SIB byte     */
                     59: static unsigned char   sss;            /* "ss" field of SIB byte       */
                     60: static unsigned char   sx;             /* "index" field of SIB byte    */
                     61: 
                     62: /*
                     63:  * Return the current address size.
                     64:  * With no address prefix flag, the address size is aop_size (16 or 32);
                     65:  * with address prefix flag, it is the other (32 or 16).
                     66:  */
                     67: int
                     68: ad_size()
                     69: {
                     70:        return (ad_pre_flag) ? 48 - aop_size : aop_size;
                     71: }
                     72: 
                     73: /*
                     74:  * Adjust argument according to specified operand size (possibly escaped).
                     75:  */
                     76: int
                     77: adj_op_size(c2) int c2;
                     78: {
                     79:        if (op_size()==16) {
                     80:                switch(c2) {                    /* set to addr16 lengths */
                     81:                case 'a':       c2 = 'w';       break;
                     82:                case 'p':       c2 = 'f';       break;
                     83:                case 'v':       c2 = 'w';       break;
                     84:                }
                     85:        } else {
                     86:                switch(c2) {                    /* set to addr32 lengths */
                     87:                case 'a':       c2 = 'd';       break;
                     88:                case 'p':       c2 = 'l';       break;
                     89:                case 'v':       c2 = 'd';       break;
                     90:                }
                     91:        }
                     92:        return c2;
                     93: }
                     94: 
                     95: /*
                     96:  * Disassemble from segment 's' to string 'dest'.
                     97:  * Return a pointer to its terminator.
                     98:  */
                     99: char *
                    100: disassemble(dest, s) char *dest; int s;
                    101: {
                    102:        char     is[MAX_INST_LEN];      /* formatted instruction buffer */
                    103:        char    *isp, *cp;
                    104:        int     loop, useMap2;
                    105: 
                    106:        /*
                    107:         * Initialize.
                    108:         */
                    109:        segn = s;
                    110:        modRM_flag = sib_flag = ad_pre_flag = op_pre_flag = seg_prefix = 0;
                    111:        isp = is;
                    112: 
                    113:        /*
                    114:         * Check whether any prefixes are present.
                    115:         * Treat each prefix like a separate instruction.
                    116:         */
                    117:        for (loop = 1, useMap2 = 0; loop; ) {
                    118:                if (get_code(1) == 0)
                    119:                        return NULL;
                    120:                switch (ibp[0]) {
                    121:                case REP:
                    122:                case REPNE:
                    123:                case LOCK:
                    124:                        loop = 0;
                    125:                        break;
                    126:                case AD_PRE:
                    127:                        ++ad_pre_flag;
                    128:                        continue;
                    129:                case OP_PRE:
                    130:                        ++op_pre_flag;
                    131:                        continue;
                    132:                case CS_PRE:
                    133:                case DS_PRE:
                    134:                case ES_PRE:
                    135:                case FS_PRE:
                    136:                case GS_PRE:
                    137:                case SS_PRE:
                    138:                        seg_prefix = ibp[0];
                    139:                        break;
                    140:                case ESC2:      /* opcode info is in the next byte */
                    141:                        useMap2 = 1;
                    142:                        if (get_code(1) == 0)
                    143:                                return NULL;
                    144:                        loop = 0;
                    145:                        break;
                    146:                default:
                    147:                        loop = 0;
                    148:                }
                    149:        }
                    150: 
                    151:        /* Get formatted opcode string from op_map[12] and store in is[]. */
                    152:        if ((cp = (useMap2) ? op_map_2[ibp[0]] : op_map_1[ibp[0]]) == NULL) {
                    153:                sprintf(dest, "Invalid instruction byte = %02x (op_map_%d)\n",
                    154:                        ibp[0], useMap2 ? 2 : 1);
                    155:                return strchr(dest, '\0') ;
                    156:        }
                    157:        strcpy(isp, cp);
                    158: 
                    159:        /*
                    160:         * Expand the formatted opcode string pointed at by isp to produce an 
                    161:         * assembler mnemonic string.
                    162:         * Make sure dest is pointing to the current
                    163:         * end-of-string after each loop.
                    164:         */
                    165:        for ( ; isp[0]; isp++) {
                    166:                switch (isp[0]) {
                    167:                case '%':
                    168:                        if ((isp = format(isp, dest)) == NULL) {
                    169:                                printr("Invalid opcode string");
                    170:                                return NULL;
                    171:                        }
                    172:                        dest = strchr(dest, '\0');      /* point to end of string */
                    173:                        break;
                    174:                case ' ':
                    175:                        *dest++ = '\t';
                    176:                        *dest = '\0';
                    177:                        break;
                    178:                case ',':
                    179:                        *dest++ = isp[0];
                    180:                        *dest++ = ' ';
                    181:                        *dest = '\0';
                    182:                        break;
                    183:                default:
                    184:                        *dest++ = isp[0];
                    185:                        *dest = '\0';
                    186:                        break;
                    187:                }
                    188:        }
                    189:        return dest;
                    190: }
                    191: 
                    192: /*
                    193:  * Evalute "%c1c2" and store the expanded results in outbuf[].
                    194:  * Then copy outbuf[] into dest[] and return isp pointing
                    195:  * to the next character of the formatted instruction string. 
                    196:  * When doing string manipulations, make sure that obp
                    197:  * is pointing at '\0' before breaking from switch statement!
                    198:  */
                    199: char *
                    200: format(isp, dest) char *isp, *dest;
                    201: {
                    202:        unsigned char   c1, c2;                 /* 1st & 2nd char after '%' */
                    203:        ADDR_T          val;
                    204:        char            **cpp;
                    205:        char            *s1;                    /* temporary string pointer */
                    206: 
                    207:        c1 = *++isp;
                    208:        c2 = *++isp;
                    209:        obp = outbuf;
                    210:        *obp = '\0';
                    211:        
                    212:        switch (c1) {
                    213: 
                    214:        case 'A':
                    215:                c2 = adj_op_size(c2);
                    216:                val = get_value(c2, UNSIGNED, ABSOLUTE);
                    217:                out_disp('a', UNSIGNED, val);
                    218:                break;
                    219: 
                    220:        case 'C':
                    221:                cpp = ctrlReg;
                    222: outreg:
                    223:                get_modRM();
                    224:                output(cpp[mReg]);
                    225:                break;
                    226: 
                    227:        case 'D':
                    228:                cpp = dbgReg;
                    229:                goto outreg;
                    230:                break;
                    231: 
                    232:        case 'E':
                    233:        case 'M':
                    234:        case 'R':
                    235:                if (ad_size() == 16)
                    236:                        out_modRM16(c2);
                    237:                else
                    238:                        out_modRM32(c2);
                    239:                break;
                    240: 
                    241:        case 'G':
                    242:                cpp = &genReg[genRegIndex(c2)][0];
                    243:                goto outreg;
                    244:                break;
                    245: 
                    246:        case 'H':
                    247:        case 'I':
                    248:                *obp++ = '$';
                    249:                c2 = adj_op_size(c2);
                    250:                val = get_value(c2, SIGNED, ABSOLUTE);
                    251:                if (c1 == 'I') {
                    252:                        switch (get_nbytes(c2)) {
                    253:                        case 1: val &= 0xFF;            break;
                    254:                        case 2: val &= 0xFFFF;          break;
                    255:                        }
                    256:                }
                    257:                out_disp('x', SIGNED, val);
                    258:                break;
                    259: 
                    260:        case 'J':
                    261:        case 'K':
                    262:                out_segpre();
                    263:                c2 = adj_op_size(c2);
                    264:                val = get_value(c2, SIGNED, PCREL);
                    265:                seg_prefix = CS_PRE;                    /* CS-relative disp */
                    266:                out_disp((c1=='J') ? 'a': 's', SIGNED, val);
                    267:                break;
                    268: 
                    269:     /* case 'M':       see case 'E' */
                    270: 
                    271:        case 'O':
                    272:                out_segpre();
                    273:                c2 = ad_size() == 16 ? 'w' : 'd';
                    274:                val = get_value(c2, SIGNED, ABSOLUTE);
                    275:                out_disp('s', SIGNED, val);
                    276:                break;
                    277:     /* case 'R':        see case 'E' */ 
                    278: 
                    279:        case 'S':
                    280:                cpp = segReg;
                    281:                goto outreg;
                    282: 
                    283:        case 'T':
                    284:                cpp = tstReg;
                    285:                goto outreg;
                    286:                break;
                    287: 
                    288:        case 'X':
                    289: #if    0
                    290:                sprintf(obp, (ad_size()==16) ? "ds:(%%si)" : "ds:(%%esi)");
                    291:                obp = strchr(obp, '\0');
                    292: #endif
                    293:                break;
                    294: 
                    295:        case 'Y':
                    296: #if    0
                    297:                sprintf(obp, (ad_size()==16) ? "es:(%%di)" : "es:(%%edi)");
                    298:                obp = strchr(obp, '\0');
                    299: #endif
                    300:                break;
                    301: 
                    302:        case 'Z':
                    303:                c2 = adj_op_size(c2);
                    304:                switch(c2) {
                    305:                case 'b':       *obp++ = 'b';                           break;
                    306:                case 'd':       *obp++ = 'l';                           break;
                    307:                case 'w':       *obp++ = 'w';                           break;
                    308:                case 'z':       *obp++ = (op_size()==16 ? 'w': 'l');    break;
                    309:                }
                    310:                *obp = '\0';
                    311:                break;
                    312: 
                    313:        case 'e':
                    314:                *obp++ = '%';
                    315:                if (op_size()!=16)
                    316:                        *obp++ = 'e';
                    317:                *obp++ = c2;
                    318:                *obp = '\0';
                    319:                break;
                    320: 
                    321:        case 'f':
                    322:                /* Handle NDP opcodes. */
                    323:                get_modRM();
                    324:                *obp++ = 'f';           /* leading 'f' implicit in opcode tables */
                    325:                if (m==3) {
                    326:                        register NDPMTAB *mtp;
                    327:                        register int    val;
                    328: 
                    329:                        /* NDP_op_3 gives opcodes with NDP register args. */
                    330:                        if ((s1 = NDP_op_3[c2-'0'][mReg]) != NULL) {
                    331:                                /* Leading 1, 2 or 3 indicates operand type. */
                    332:                                if ((c1 = *s1)=='1' || c1=='2' || c1=='3')
                    333:                                        s1++;
                    334:                                else
                    335:                                        c1 = 0;
                    336:                                output(s1);
                    337:                                if (!c1)
                    338:                                        break;
                    339:                                *obp++ = '\t';
                    340:                                /* Output the NDP operand[s]. */
                    341:                                switch(c1) {
                    342:                                case '1':
                    343:                                        output(NDPReg[mRM]);
                    344:                                        break;
                    345:                                case '2':
                    346:                                        output(NDPReg[0]);
                    347:                                        *obp++ = ',';
                    348:                                        *obp++ = ' ';
                    349:                                        output(NDPReg[mRM]);
                    350:                                        break;
                    351:                                case '3':
                    352:                                        output(NDPReg[mRM]);
                    353:                                        *obp++ = ',';
                    354:                                        *obp++ = ' ';
                    355:                                        output(NDPReg[0]);
                    356:                                        break;
                    357:                                }
                    358:                                break;
                    359:                        }
                    360:                        /* Look for opcode in NDP_misc_op[]. */
                    361:                        val = (c2-'0'+0xD8)*0x100 + ibp[0];
                    362:                        for (mtp = NDP_misc_op; mtp->ndpm_val != 0; ++mtp) {
                    363:                                if (mtp->ndpm_val >= val)
                    364:                                        break;
                    365:                        }
                    366:                        if (mtp->ndpm_val == val) {
                    367:                                output(mtp->ndpm_op);
                    368:                                break;
                    369:                        }
                    370:                } else if ((s1 = NDP_op[c2-'0'][mReg]) != NULL) {
                    371:                        /* NDP opcode with memory operand from mod r/m byte. */
                    372:                        output(s1);
                    373:                        *obp++ = '\t';
                    374:                        if (ad_size() == 16)
                    375:                                out_modRM16(c2);
                    376:                        else
                    377:                                out_modRM32(c2);
                    378:                        break;
                    379:                }
                    380:                printr("Invalid NDP instruction %02x %02x",
                    381:                        c2-'0'+0xD8, ibp[0]);
                    382:                break;
                    383: 
                    384:        case 'g':       /* just inserting the group string into isp */
                    385:                get_modRM();
                    386:                if (grp_map[c2-'0'][mReg] == NULL) {
                    387:                        sprintf(obp, "\nInvalid instruction byte = %02x (grp_map[%d][%d])\n",
                    388:                                ibp[0], c2-'0', mReg);
                    389:                        return strchr(obp, '\0');
                    390:                }
                    391:                {
                    392:                        char buf[MAX_INST_LEN];
                    393: 
                    394:                        s1 = isp+1;                     /* save current pointer */
                    395:                        strcpy(buf, s1);                /* save rest of fmt */
                    396:                        strcpy(s1, grp_map[c2-'0'][mReg]);
                    397:                        s1 = strchr(s1, '\0');          /* copy group string */
                    398:                        strcpy(s1, buf);                /* add remainder */
                    399:                        *obp = '\0';
                    400:                }
                    401:                break;
                    402: 
                    403:        case 'r':
                    404:                if (get_code(1) == 0)
                    405:                        return NULL;
                    406:                break;
                    407: 
                    408:        default:
                    409:                *obp++ = c1;
                    410:                *obp++ = c2;
                    411:                *obp = '\0';
                    412:        }
                    413:        strcpy(dest, outbuf);
                    414:        return isp;
                    415: }
                    416: 
                    417: /*
                    418:  * Return the appropriate first index into genreg[][]:
                    419:  *     0       byte
                    420:  *     1       word
                    421:  *     2       dword
                    422:  */
                    423: int
                    424: genRegIndex(c2) int c2;
                    425: {
                    426:        switch(c2) {
                    427:        case 'a':       return (op_size() == 16) ? 1 : 2;
                    428:        case 'b':       return 0;
                    429:        case 'd':       return 2;
                    430:        case 'v':       return (op_size() == 16) ? 1 : 2;
                    431:        case 'w':       return 1;
                    432:        }
                    433:        return printr("Invalid c2 = %c; a 1 byte reg is shown by default", c2);
                    434: }
                    435: 
                    436: #if    0                       /* covered by macro in i386db.h */
                    437: /*
                    438:  * Read nbytes of code to ibp.
                    439:  */
                    440: int
                    441: get_code(nbytes) int nbytes;
                    442: {
                    443:        return getb(segn, ibp, nbytes);
                    444: }
                    445: #endif
                    446: 
                    447: /*
                    448:  * Read and decode a mod r/m byte.
                    449:  */
                    450: #define mod(x)         (((x)>>6)&3)
                    451: #define modR(x)                (((x)>>3)&7)
                    452: #define modRM(x)       ((x)&7)
                    453: int
                    454: get_modRM()
                    455: {
                    456:        if (!modRM_flag) {
                    457:                if (get_code(1) == 0)
                    458:                        return 0;
                    459:                m = mod(ibp[0]);
                    460:                mRM = modRM(ibp[0]);
                    461:                mReg = modR(ibp[0]);
                    462:                modRM_flag = 1;
                    463:        }
                    464:        return 1;
                    465: }
                    466: 
                    467: /*
                    468:  * Convert a size character to an actual size in bytes.
                    469:  */
                    470: int
                    471: get_nbytes(mysize) int mysize;
                    472: {
                    473:        switch(mysize) {
                    474:        case 'b':       return 1;
                    475:        case 'd':       return 4;
                    476:        case 'f':       return 4;
                    477:        case 'l':       return 6;
                    478:        case 'w':       return 2;
                    479:        case '\0':      return 0;
                    480:        }
                    481:        printr("Invalid nbytes=%c; 1 byte size is chosen by default", mysize);
                    482:        return 1;
                    483: }
                    484: 
                    485: /*
                    486:  * Read and decode a SIB byte.
                    487:  */
                    488: #define sibss(x)       (((x)>>6)&3)
                    489: #define sibx(x)                (((x)>>3)&7)
                    490: #define sibb(x)                ((x)&7)
                    491: int
                    492: get_sib()
                    493: {
                    494:        if (!sib_flag) {
                    495:                if ((get_code(1)) == 0)
                    496:                        return 0;
                    497:                sss = sibss(ibp[0]);
                    498:                sx = sibx(ibp[0]);
                    499:                sb = sibb(ibp[0]);
                    500:                sib_flag = 1;
                    501:        }
                    502:        return 1;
                    503: }
                    504: 
                    505: /*
                    506:  * Get displacement or immediate data and sign- or zero-extend it.
                    507:  * Return the number of bytes read, or 0 on failure.
                    508:  */
                    509: int
                    510: getValData(is_signed, mysize) int is_signed, mysize;
                    511: {
                    512:        register int nbytes, i;
                    513: 
                    514:        if ((nbytes = get_nbytes(mysize)) == 0)
                    515:                return 0;
                    516:        else if ((get_code(nbytes)) == 0)
                    517:                return printr("Cannot read displacement or immediate data");
                    518: 
                    519:        for (i = nbytes; i < MAX_DISP_SIZE; i++)
                    520:                ibp[i] = (is_signed && (ibp[i-1] & 0x80)) ? 0xFF : 0;
                    521:        return nbytes;
                    522: }
                    523: 
                    524: /*
                    525:  * Get immediate or displacement value.
                    526:  */
                    527: ADDR_T
                    528: get_value(mysize, is_signed, flag) int mysize, is_signed, flag;
                    529: {
                    530:        register ADDR_T base;
                    531:        int nbytes;
                    532: 
                    533:        if ((nbytes = getValData(is_signed, mysize)) == 0)
                    534:                return (ADDR_T)0;
                    535:        base = (flag) ? add : (ADDR_T)0;
                    536:        if (mysize == 'f' || mysize == 'l') {
                    537:                /* Output 32-bit or 48-bit pointer segment. */
                    538:                sprintf(obp, "0x%02x%02x:", ibp[nbytes-1], ibp[nbytes-2]);
                    539:                obp = strchr(obp, '\0');
                    540:                nbytes -= 2;
                    541:        }
                    542:        switch (nbytes) {
                    543:        case 1:
                    544:                delta = (is_signed) ? *(char *)ibp : *(unsigned char *)ibp;
                    545:                break;
                    546:        case 2:
                    547:                delta = (is_signed) ? *(short *)ibp : *(unsigned short *)ibp;
                    548:                break;          
                    549:        case 4:
                    550:                delta = *(long *)ibp;
                    551:                break;
                    552:        }
                    553:        return base + (ADDR_T)delta;
                    554: }
                    555: 
                    556: /*
                    557:  * Return the current operand size.
                    558:  * With no operand prefix flag, the address size is aop_size (16 or 32);
                    559:  * with address prefix flag, it is the other (32 or 16).
                    560:  */
                    561: int
                    562: op_size()
                    563: {
                    564:        return (op_pre_flag) ? 48 - aop_size : aop_size;
                    565: }
                    566: 
                    567: /*
                    568:  * Output an address.
                    569:  */
                    570: void
                    571: out_addr(v) ADDR_T v;
                    572: {
                    573:        sprintf(obp, "0x%lX", v);
                    574:        obp = strchr(obp, '\0');
                    575: }
                    576: 
                    577: /*
                    578:  * Output a displacement.
                    579:  */
                    580: void
                    581: out_disp(fmt, is_signed, val) int fmt; int is_signed; ADDR_T val;
                    582: {
                    583:        dbprintf(("out_disp(%c, %d, %lX):\n", fmt, is_signed, val));
                    584:        if (is_signed && delta < 0)
                    585:                delta = -delta;
                    586:        switch(fmt) {
                    587: 
                    588:        case 'd':                                       /* print decimal */
                    589:                if (val == (ADDR_T)0)
                    590:                        break;                          /* huh? */
                    591:                sprintf(obp, "%ld", val);
                    592:                break;
                    593: 
                    594:        case 'x':                                       /* print hex */
                    595:                sprintf(obp, (delta > TOLHEX) ? "0x%lX" : "%ld", val);
                    596:                break;
                    597: 
                    598:        case 'a':                                       /* print address */
                    599:                if (delta <= TOLSYM) {
                    600:                        out_addr(val);                  /* print address in hex */
                    601:                        break;
                    602:                }
                    603:                /* else fall through to print symbolic address... */
                    604: 
                    605:        case 's':       /* print symbol if possible; otherwise print address */
                    606:                cvt_addr(obp, (seg_prefix == CS_PRE) ? ISEG : DSEG, val);
                    607:                break;
                    608: 
                    609:        default:
                    610:                printr("Invalid fmt=%c in out_disp", fmt);
                    611:        }
                    612:        obp = strchr(obp, '\0');
                    613: }
                    614: 
                    615: /*
                    616:  * Output mod r/m info.
                    617:  */
                    618: void
                    619: out_modRM(dispsize, fmt, addrsize, is_signed) int dispsize, fmt, addrsize, is_signed;
                    620: {
                    621:        unsigned long   val;
                    622: 
                    623:        out_segpre();
                    624:        val = get_value(dispsize, is_signed, ABSOLUTE);
                    625:        out_disp(fmt, is_signed, val);
                    626:        output(modRMtab[ADDRINDEX(addrsize)][mRM]);
                    627: }
                    628: 
                    629: /*
                    630:  * Output 1b-bit mod r/m info.
                    631:  */
                    632: void
                    633: out_modRM16(c2) int c2;
                    634: {
                    635:        unsigned long   val;
                    636: 
                    637:        get_modRM();
                    638:        c2 = adj_op_size(c2);
                    639: 
                    640:        switch(m) {
                    641:        case 0:
                    642:                out_segpre();
                    643:                if (mRM==6) {
                    644:                        val = get_value('w', SIGNED, ABSOLUTE);
                    645:                        out_disp('s', SIGNED, val);
                    646:                        break;
                    647:                }
                    648:                output(modRMtab[ADDRINDEX(16)][mRM]);
                    649:                break;
                    650:        case 1:
                    651:        case 2:
                    652:                out_modRM((m==1) ? 'b' : 'w', 'd', 16, SIGNED);
                    653:                break;
                    654:        case 3:
                    655:                output(genReg[genRegIndex(c2)][mRM]);
                    656:                break;
                    657:        }
                    658: }
                    659: 
                    660: /*
                    661:  * Output 32-bit mod r/m info.
                    662:  */
                    663: void
                    664: out_modRM32(c2) int c2;
                    665: {
                    666:        unsigned long   val;
                    667:        char c;
                    668: 
                    669:        get_modRM();
                    670:        c2 = adj_op_size(c2);
                    671: 
                    672:        switch(m) {
                    673:        case 0:
                    674:                if (mRM==4) {
                    675:                        out_sib('\0', m);
                    676:                        break;
                    677:                }
                    678:                out_segpre();
                    679:                if (mRM==5) {
                    680:                        val = get_value('d', SIGNED, ABSOLUTE);
                    681:                        out_disp('s', SIGNED, val);
                    682:                        break;
                    683:                }
                    684:                output(modRMtab[ADDRINDEX(32)][mRM]);
                    685:                break;
                    686:        case 1:
                    687:        case 2:
                    688:                c = (m==1) ? 'b' : 'd';
                    689:                if (mRM==4)
                    690:                        out_sib(c, m);
                    691:                else
                    692:                        out_modRM(c, 'd', 32, 1);
                    693:                break;
                    694:        case 3:
                    695:                output(genReg[genRegIndex(c2)][mRM]);
                    696:                break;
                    697:        }
                    698: }
                    699: 
                    700: /*
                    701:  * Copy src to output buffer outbuf,
                    702:  * updating the output buffer pointer accordingly.
                    703:  */
                    704: void
                    705: output(src) char *src;
                    706: {
                    707:        strcpy(obp, src);
                    708:        obp = strchr(obp, '\0');
                    709: }
                    710: 
                    711: /*
                    712:  * Write a segment escape prefix.
                    713:  */
                    714: void
                    715: out_segpre()
                    716: {
                    717:        if (seg_prefix != 0)
                    718:                output(op_map_1[seg_prefix]);
                    719: }
                    720: 
                    721: /*
                    722:  * Output a SIB indirect address.
                    723:  */
                    724: void
                    725: out_sib(dispsize, m) int dispsize, m;
                    726: {
                    727:        unsigned long   val;
                    728: 
                    729:        get_sib();
                    730:        switch(m) {
                    731:        case 0:
                    732:                out_segpre();
                    733:                if (sb == EBP_SIB) {
                    734:                        val = get_value('d', SIGNED, ABSOLUTE);
                    735:                        out_disp('d', SIGNED, val);
                    736:                } else
                    737:                        output(modRMtab[ADDRINDEX(32)][sb]);
                    738:                break;
                    739:        case 1:
                    740:        case 2:
                    741:                out_segpre();
                    742:                val = get_value(dispsize, SIGNED, ABSOLUTE);
                    743:                out_disp('d', SIGNED, val);
                    744:                output(modRMtab[ADDRINDEX(32)][sb]);
                    745:                break;
                    746:        }
                    747:        if (sibtab[sss][sx] != NULL)
                    748:                output(sibtab[sss][sx]);
                    749: }
                    750: 
                    751: /* end of db/i386/i386db2.c */

unix.superglobalmegacorp.com

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