Annotation of lucent/sys/src/libmach/machdata.c, revision 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.