Annotation of coherent/b/bin/db/i386/i386db2.c, revision 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.