Annotation of lucent/sys/src/libmach/machdata.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Debugger utilities shared by at least two architectures
                      3:  */
                      4: 
                      5: #include <u.h>
                      6: #include <libc.h>
                      7: #include <bio.h>
                      8: #include <mach.h>
                      9: 
                     10: #define STARTSYM       "_main"
                     11: #define PROFSYM                "_mainp"
                     12: #define        FRAMENAME       ".frame"
                     13: 
                     14: extern Machdata        mipsmach;
                     15: 
                     16: int    asstype = AMIPS;                /* disassembler type */
                     17: Machdata *machdata;            /* machine-dependent functions */
                     18: 
                     19: int
                     20: localaddr(Map *map, char *fn, char *var, long *r, Rgetter rget)
                     21: {
                     22:        Symbol s;
                     23:        ulong fp;
                     24:        ulong pc, sp, link;
                     25: 
                     26:        if (!lookup(fn, 0, &s)) {
                     27:                werrstr("function not found");
                     28:                return -1;
                     29:        }
                     30:        pc = rget(map, mach->pc);
                     31:        sp = rget(map, mach->sp);
                     32:        if(mach->link)
                     33:                link = rget(map, mach->link);
                     34:        else
                     35:                link = 0;
                     36:        fp = machdata->findframe(map, s.value, pc, sp, link);
                     37:        if (fp == 0) {
                     38:                werrstr("stack frame not found");
                     39:                return -1;
                     40:        }
                     41: 
                     42:        if (!var || !var[0]) {
                     43:                *r = fp;
                     44:                return 1;
                     45:        }
                     46: 
                     47:        if (findlocal(&s, var, &s) == 0) {
                     48:                werrstr("local variable not found");
                     49:                return -1;
                     50:        }
                     51: 
                     52:        switch (s.class) {
                     53:        case CAUTO:
                     54:                *r = fp - s.value;
                     55:                break;
                     56:        case CPARAM:            /* assume address size is stack width */
                     57:                *r = fp + s.value + mach->szaddr;
                     58:                break;
                     59:        default:
                     60:                werrstr("local variable not found: %d", s.class);
                     61:                return -1;
                     62:        }
                     63:        return 1;
                     64: }
                     65: 
                     66: /*
                     67:  * Print value v as name[+offset] and then the string s.
                     68:  */
                     69: int
                     70: symoff(char *buf, int n, long v, int space)
                     71: {
                     72:        Symbol s;
                     73:        int r;
                     74:        long delta;
                     75: 
                     76:        r = delta = 0;          /* to shut compiler up */
                     77:        if (v) {
                     78:                r = findsym(v, space, &s);
                     79:                if (r)
                     80:                        delta = v-s.value;
                     81:                if (delta < 0)
                     82:                        delta = -delta;
                     83:        }
                     84:        if (v == 0 || r == 0)
                     85:                return snprint(buf, n, "%lux", v);
                     86:        if (s.type != 't' && s.type != 'T' && delta >= 4096)
                     87:                return snprint(buf, n, "%lux", v);
                     88:        else if (delta)
                     89:                return snprint(buf, n, "%s+%lux", s.name, delta);
                     90:        else
                     91:                return snprint(buf, n, "%s", s.name);
                     92: }
                     93: /*
                     94:  *     Format floating point registers
                     95:  *
                     96:  *     Register codes in format field:
                     97:  *     'X' - print as 32-bit hexadecimal value
                     98:  *     'F' - 64-bit double register when modif == 'F'; else 32-bit single reg
                     99:  *     'f' - 32-bit ieee float
                    100:  *     '8' - big endian 80-bit ieee extended float
                    101:  *     '3' - little endian 80-bit ieee extended float with hole in bytes 8&9
                    102:  */
                    103: int
                    104: fpformat(Map *map, Reglist *rp, char *buf, int n, int modif)
                    105: {
                    106:        char reg[12];
                    107:        long r;
                    108: 
                    109:        switch(rp->rformat)
                    110:        {
                    111:        case 'X':
                    112:                if (get4(map, rp->raddr, &r) < 0)
                    113:                        return -1;
                    114:                snprint(buf, n, "%lux", r+rp->rdelta);
                    115:                break;
                    116:        case 'F':       /* first reg of double reg pair */
                    117:                if (modif == 'F')
                    118:                if (((rp+1)->rflags&RFLT) && (rp+1)->rformat == 'f') {
                    119:                        if (get1(map, rp->raddr, (uchar *)reg, 8) < 0)
                    120:                                return -1;
                    121:                        machdata->dftos(buf, n, reg);
                    122:                        return 2;
                    123:                }       
                    124:                        /* treat it like 'f' */
                    125:                if (get1(map, rp->raddr, (uchar *)reg, 4) < 0)
                    126:                        return -1;
                    127:                machdata->sftos(buf, n, reg);
                    128:                break;
                    129:        case 'f':       /* 32 bit float */
                    130:                if (get1(map, rp->raddr, (uchar *)reg, 4) < 0)
                    131:                        return -1;
                    132:                machdata->sftos(buf, n, reg);
                    133:                break;
                    134:        case '3':       /* little endian ieee 80 with hole in bytes 8&9 */
                    135:                if (get1(map, rp->raddr, (uchar *)reg, 10) < 0)
                    136:                        return -1;
                    137:                memmove(reg+10, reg+8, 2);      /* open hole */
                    138:                memset(reg+8, 0, 2);            /* fill it */
                    139:                leieee80ftos(buf, n, reg);
                    140:                break;
                    141:        case '8':       /* big-endian ieee 80 */
                    142:                if (get1(map, rp->raddr, (uchar *)reg, 10) < 0)
                    143:                        return -1;
                    144:                beieee80ftos(buf, n, reg);
                    145:                break;
                    146:        default:        /* unknown */
                    147:                break;
                    148:        }
                    149:        return 1;
                    150: }
                    151: 
                    152: char *
                    153: _hexify(char *buf, ulong p, int zeros)
                    154: {
                    155:        ulong d;
                    156: 
                    157:        d = p/16;
                    158:        if(d)
                    159:                buf = _hexify(buf, d, zeros-1);
                    160:        else
                    161:                while(zeros--)
                    162:                        *buf++ = '0';
                    163:        *buf++ = "0123456789abcdef"[p&0x0f];
                    164:        return buf;
                    165: }
                    166: 
                    167: /*
                    168:  * These routines assume that if the number is representable
                    169:  * in IEEE floating point, it will be representable in the native
                    170:  * double format.  Naive but workable, probably.
                    171:  */
                    172: int
                    173: ieeedftos(char *buf, int n, ulong h, ulong l)
                    174: {
                    175:        double fr;
                    176:        int exp;
                    177: 
                    178:        if (n <= 0)
                    179:                return 0;
                    180: 
                    181: 
                    182:        if(h & (1L<<31)){
                    183:                *buf++ = '-';
                    184:                h &= ~(1L<<31);
                    185:        }else
                    186:                *buf++ = ' ';
                    187:        n--;
                    188:        if(l == 0 && h == 0)
                    189:                return snprint(buf, n, "0.");
                    190:        exp = (h>>20) & ((1L<<11)-1L);
                    191:        if(exp == 0)
                    192:                return snprint(buf, n, "DeN(%.8lux%.8lux)", h, l);
                    193:        if(exp == ((1L<<11)-1L)){
                    194:                if(l==0 && (h&((1L<<20)-1L)) == 0)
                    195:                        return snprint(buf, n, "Inf");
                    196:                else
                    197:                        return snprint(buf, n, "NaN(%.8lux%.8lux)", h&((1L<<20)-1L), l);
                    198:        }
                    199:        exp -= (1L<<10) - 2L;
                    200:        fr = l & ((1L<<16)-1L);
                    201:        fr /= 1L<<16;
                    202:        fr += (l>>16) & ((1L<<16)-1L);
                    203:        fr /= 1L<<16;
                    204:        fr += (h & (1L<<20)-1L) | (1L<<20);
                    205:        fr /= 1L<<21;
                    206:        fr = ldexp(fr, exp);
                    207:        return snprint(buf, n, "%.18g", fr);
                    208: }
                    209: 
                    210: int
                    211: ieeesftos(char *buf, int n, ulong h)
                    212: {
                    213:        double fr;
                    214:        int exp;
                    215: 
                    216:        if (n <= 0)
                    217:                return 0;
                    218: 
                    219:        if(h & (1L<<31)){
                    220:                *buf++ = '-';
                    221:                h &= ~(1L<<31);
                    222:        }else
                    223:                *buf++ = ' ';
                    224:        n--;
                    225:        if(h == 0)
                    226:                return snprint(buf, n, "0.");
                    227:        exp = (h>>23) & ((1L<<8)-1L);
                    228:        if(exp == 0)
                    229:                return snprint(buf, n, "DeN(%.8lux)", h);
                    230:        if(exp == ((1L<<8)-1L)){
                    231:                if((h&((1L<<23)-1L)) == 0)
                    232:                        return snprint(buf, n, "Inf");
                    233:                else
                    234:                        return snprint(buf, n, "NaN(%.8lux)", h&((1L<<23)-1L));
                    235:        }
                    236:        exp -= (1L<<7) - 2L;
                    237:        fr = (h & ((1L<<23)-1L)) | (1L<<23);
                    238:        fr /= 1L<<24;
                    239:        fr = ldexp(fr, exp);
                    240:        return snprint(buf, n, "%.9g", fr);
                    241: }
                    242: 
                    243: int
                    244: beieeesftos(char *buf, int n, void *s)
                    245: {
                    246:        return ieeesftos(buf, n, beswal(*(ulong*)s));
                    247: }
                    248: 
                    249: int
                    250: beieeedftos(char *buf, int n, void *s)
                    251: {
                    252:        return ieeedftos(buf, n, beswal(*(ulong*)s), beswal(((ulong*)(s))[1]));
                    253: }
                    254: 
                    255: int
                    256: leieeesftos(char *buf, int n, void *s)
                    257: {
                    258:        return ieeesftos(buf, n, leswal(*(ulong*)s));
                    259: }
                    260: 
                    261: int
                    262: leieeedftos(char *buf, int n, void *s)
                    263: {
                    264:        return ieeedftos(buf, n, leswal(((ulong*)(s))[1]), leswal(*(ulong*)s));
                    265: }
                    266: 
                    267: /* packed in 12 bytes, with s[2]==s[3]==0; mantissa starts at s[4]*/
                    268: int
                    269: beieee80ftos(char *buf, int n, void *s)
                    270: {
                    271:        uchar *reg = (uchar*)s;
                    272:        int i;
                    273:        ulong x;
                    274:        uchar ieee[8+8];        /* room for slop */
                    275:        uchar *p, *q;
                    276: 
                    277:        memset(ieee, 0, sizeof(ieee));
                    278:        /* sign */
                    279:        if(reg[0] & 0x80)
                    280:                ieee[0] |= 0x80;
                    281: 
                    282:        /* exponent */
                    283:        x = ((reg[0]&0x7F)<<8) | reg[1];
                    284:        if(x == 0)              /* number is ±0 */
                    285:                goto done;
                    286:        if(x == 0x7FFF){
                    287:                if(memcmp(reg+4, ieee+1, 8) == 0){ /* infinity */
                    288:                        x = 2047;
                    289:                }else{                          /* NaN */
                    290:                        x = 2047;
                    291:                        ieee[7] = 0x1;          /* make sure */
                    292:                }
                    293:                ieee[0] |= x>>4;
                    294:                ieee[1] |= (x&0xF)<<4;
                    295:                goto done;
                    296:        }
                    297:        x -= 0x3FFF;            /* exponent bias */
                    298:        x += 1023;
                    299:        if(x >= (1<<11) || ((reg[4]&0x80)==0 && x!=0))
                    300:                return snprint(buf, n, "not in range");
                    301:        ieee[0] |= x>>4;
                    302:        ieee[1] |= (x&0xF)<<4;
                    303: 
                    304:        /* mantissa */
                    305:        p = reg+4;
                    306:        q = ieee+1;
                    307:        for(i=0; i<56; i+=8, p++, q++){ /* move one byte */
                    308:                x = (p[0]&0x7F) << 1;
                    309:                if(p[1] & 0x80)
                    310:                        x |= 1;
                    311:                q[0] |= x>>4;
                    312:                q[1] |= (x&0xF)<<4;
                    313:        }
                    314:     done:
                    315:        return beieeedftos(buf, n, (void*)ieee);
                    316: }
                    317: 
                    318: 
                    319: int
                    320: leieee80ftos(char *buf, int n, void *s)
                    321: {
                    322:        int i;
                    323:        char *cp;
                    324:        char b[12];
                    325: 
                    326:        cp = (char*) s;
                    327:        for(i=0; i<12; i++)
                    328:                b[11-i] = *cp++;
                    329:        return beieee80ftos(buf, n, b);
                    330: }
                    331: 
                    332: int
                    333: cisctrace(Map *map, ulong pc, ulong sp, ulong link, Tracer trace)
                    334: {
                    335:        Symbol s;
                    336:        int found;
                    337:        ulong opc;
                    338:        long moved, j;
                    339: 
                    340:        USED(link);
                    341:        j = 0;
                    342:        opc = 0;
                    343:        while(pc && opc != pc) {
                    344:                moved = pc2sp(pc);
                    345:                if (moved == -1)
                    346:                        break;
                    347:                found = findsym(pc, CTEXT, &s);
                    348:                if (!found)
                    349:                        break;
                    350:                if(strcmp(STARTSYM, s.name) == 0 || strcmp(PROFSYM, s.name) == 0)
                    351:                        break;
                    352: 
                    353:                sp += moved;
                    354:                opc = pc;
                    355:                if (get4(map, sp, (long *)&pc) < 0)
                    356:                        break;
                    357:                (*trace)(map, pc, sp, &s);
                    358:                sp += mach->szaddr;     /*assumes address size = stack width*/
                    359:                if(++j > 40)
                    360:                        break;
                    361:        }
                    362:        return j;
                    363: }
                    364: 
                    365: int
                    366: risctrace(Map *map, ulong pc, ulong sp, ulong link, Tracer trace)
                    367: {
                    368:        int i;
                    369:        Symbol s, f;
                    370:        ulong oldpc;
                    371: 
                    372:        i = 0;
                    373:        while(findsym(pc, CTEXT, &s)) {
                    374:                if(strcmp(STARTSYM, s.name) == 0 || strcmp(PROFSYM, s.name) == 0)
                    375:                        break;
                    376: 
                    377:                if(pc == s.value)       /* at first instruction */
                    378:                        f.value = 0;
                    379:                else if(findlocal(&s, FRAMENAME, &f) == 0)
                    380:                        break;
                    381: 
                    382:                oldpc = pc;
                    383:                if(s.type == 'L' || s.type == 'l' || pc <= s.value+mach->pcquant)
                    384:                        pc = link;
                    385:                else
                    386:                        if (get4(map, sp, (long *) &pc) < 0)
                    387:                                break;
                    388: 
                    389:                if(pc == 0 || (pc == oldpc && f.value == 0))
                    390:                        break;
                    391: 
                    392:                sp += f.value;
                    393:                (*trace)(map, pc-8, sp, &s);
                    394: 
                    395:                if(++i > 40)
                    396:                        break;
                    397:        }
                    398:        return i;
                    399: }
                    400: 
                    401: ulong
                    402: ciscframe(Map *map, ulong addr, ulong pc, ulong sp, ulong link)
                    403: {
                    404:        Symbol s;
                    405:        int moved;
                    406: 
                    407:        USED(link);
                    408:        for(;;) {
                    409:                moved = pc2sp(pc);
                    410:                if (moved  == -1)
                    411:                        break;
                    412:                sp += moved;
                    413:                findsym(pc, CTEXT, &s);
                    414:                if (addr == s.value)
                    415:                        return sp;
                    416:                if (get4(map, sp, (long *) &pc) < 0)
                    417:                        break;
                    418:                sp += mach->szaddr;     /*assumes sizeof(addr) = stack width*/
                    419:        }
                    420:        return 0;
                    421: }
                    422: 
                    423: ulong
                    424: riscframe(Map *map, ulong addr, ulong pc, ulong sp, ulong link)
                    425: {
                    426:        Symbol s, f;
                    427: 
                    428:        while (findsym(pc, CTEXT, &s)) {
                    429:                if(strcmp(STARTSYM, s.name) == 0 || strcmp(PROFSYM, s.name) == 0)
                    430:                        break;
                    431: 
                    432:                if(pc == s.value)       /* at first instruction */
                    433:                        f.value = 0;
                    434:                else
                    435:                if(findlocal(&s, FRAMENAME, &f) == 0)
                    436:                        break;
                    437: 
                    438:                sp += f.value;
                    439:                if (s.value == addr)
                    440:                        return sp;
                    441: 
                    442:                if (s.type == 'L' || s.type == 'l' || pc-s.value <= mach->szaddr*2)
                    443:                        pc = link;
                    444:                else
                    445:                if (get4(map, sp-f.value, (long *)&pc) < 0)
                    446:                        break;
                    447:        }
                    448:        return 0;
                    449: }

unix.superglobalmegacorp.com

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