Annotation of Gnu-Mach/ddb/db_examine.c, revision 1.1

1.1     ! root        1: /* 
        !             2:  * Mach Operating System
        !             3:  * Copyright (c) 1992,1991,1990 Carnegie Mellon University
        !             4:  * All Rights Reserved.
        !             5:  * 
        !             6:  * Permission to use, copy, modify and distribute this software and its
        !             7:  * documentation is hereby granted, provided that both the copyright
        !             8:  * notice and this permission notice appear in all copies of the
        !             9:  * software, derivative works or modified versions, and any portions
        !            10:  * thereof, and that both notices appear in supporting documentation.
        !            11:  * 
        !            12:  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
        !            13:  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
        !            14:  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
        !            15:  * 
        !            16:  * Carnegie Mellon requests users of this software to return to
        !            17:  * 
        !            18:  *  Software Distribution Coordinator  or  [email protected]
        !            19:  *  School of Computer Science
        !            20:  *  Carnegie Mellon University
        !            21:  *  Pittsburgh PA 15213-3890
        !            22:  * 
        !            23:  * any improvements or extensions that they make and grant Carnegie Mellon
        !            24:  * the rights to redistribute these changes.
        !            25:  */
        !            26: /*
        !            27:  *     Author: David B. Golub, Carnegie Mellon University
        !            28:  *     Date:   7/90
        !            29:  */
        !            30: #include "mach_kdb.h"
        !            31: #if MACH_KDB
        !            32: 
        !            33: #include <mach/boolean.h>
        !            34: #include <machine/db_machdep.h>
        !            35: 
        !            36: #include <ddb/db_access.h>
        !            37: #include <ddb/db_lex.h>
        !            38: #include <ddb/db_output.h>
        !            39: #include <ddb/db_command.h>
        !            40: #include <ddb/db_sym.h>
        !            41: #include <ddb/db_task_thread.h>
        !            42: #include <kern/thread.h>
        !            43: #include <kern/task.h>
        !            44: #include <mach/vm_param.h>
        !            45: 
        !            46: #define db_thread_to_task(thread)      ((thread)? thread->task: TASK_NULL)
        !            47: 
        !            48: char           db_examine_format[TOK_STRING_SIZE] = "x";
        !            49: int            db_examine_count = 1;
        !            50: db_addr_t      db_examine_prev_addr = 0;
        !            51: thread_t       db_examine_thread = THREAD_NULL;
        !            52: 
        !            53: extern db_addr_t db_disasm(db_addr_t pc, boolean_t altform, task_t task);
        !            54:                        /* instruction disassembler */
        !            55: 
        !            56: void db_examine();/*forwards*/
        !            57: void db_strcpy();
        !            58: 
        !            59: /*
        !            60:  * Examine (print) data.
        !            61:  */
        !            62: /*ARGSUSED*/
        !            63: void
        !            64: db_examine_cmd(addr, have_addr, count, modif)
        !            65:        db_expr_t       addr;
        !            66:        int             have_addr;
        !            67:        db_expr_t       count;
        !            68:        char *          modif;
        !            69: {
        !            70:        thread_t        thread;
        !            71:        boolean_t       db_option();
        !            72: 
        !            73:        if (modif[0] != '\0')
        !            74:            db_strcpy(db_examine_format, modif);
        !            75: 
        !            76:        if (count == -1)
        !            77:            count = 1;
        !            78:        db_examine_count = count;
        !            79:        if (db_option(modif, 't')) 
        !            80:          {
        !            81:            if (!db_get_next_thread(&thread, 0))
        !            82:              return;
        !            83:          }
        !            84:        else 
        !            85:          if (db_option(modif,'u'))
        !            86:            thread = current_thread();
        !            87:          else
        !            88:            thread = THREAD_NULL;
        !            89:        
        !            90:        db_examine_thread = thread;
        !            91:        db_examine((db_addr_t) addr, db_examine_format, count, 
        !            92:                                        db_thread_to_task(thread));
        !            93: }
        !            94: 
        !            95: /* ARGSUSED */
        !            96: void
        !            97: db_examine_forward(addr, have_addr, count, modif)
        !            98:        db_expr_t       addr;
        !            99:        int             have_addr;
        !           100:        db_expr_t       count;
        !           101:        char *          modif;
        !           102: {
        !           103:        db_examine(db_next, db_examine_format, db_examine_count,
        !           104:                                db_thread_to_task(db_examine_thread));
        !           105: }
        !           106: 
        !           107: /* ARGSUSED */
        !           108: void
        !           109: db_examine_backward(addr, have_addr, count, modif)
        !           110:        db_expr_t       addr;
        !           111:        int             have_addr;
        !           112:        db_expr_t       count;
        !           113:        char *          modif;
        !           114: {
        !           115: 
        !           116:        db_examine(db_examine_prev_addr - (db_next - db_examine_prev_addr),
        !           117:                         db_examine_format, db_examine_count,
        !           118:                                db_thread_to_task(db_examine_thread));
        !           119: }
        !           120: 
        !           121: void
        !           122: db_examine(addr, fmt, count, task)
        !           123:        register
        !           124:        db_addr_t       addr;
        !           125:        char *          fmt;    /* format string */
        !           126:        int             count;  /* repeat count */
        !           127:        task_t          task;
        !           128: {
        !           129:        int             c;
        !           130:        db_expr_t       value;
        !           131:        int             size;   /* in bytes */
        !           132:        int             width;
        !           133:        char *          fp;
        !           134: 
        !           135:        db_examine_prev_addr = addr;
        !           136:        while (--count >= 0) {
        !           137:            fp = fmt;
        !           138:            size = sizeof(int);
        !           139:            width = 4*size;
        !           140:            while ((c = *fp++) != 0) {
        !           141:                switch (c) {
        !           142:                    case 'b':
        !           143:                        size = sizeof(char);
        !           144:                        width = 4*size;
        !           145:                        break;
        !           146:                    case 'h':
        !           147:                        size = sizeof(short);
        !           148:                        width = 4*size;
        !           149:                        break;
        !           150:                    case 'l':
        !           151:                        size = sizeof(long);
        !           152:                        width = 4*size;
        !           153:                        break;
        !           154:                    case 'a':   /* address */
        !           155:                    case 'A':   /* function address */
        !           156:                        /* always forces a new line */
        !           157:                        if (db_print_position() != 0)
        !           158:                            db_printf("\n");
        !           159:                        db_prev = addr;
        !           160:                        db_task_printsym(addr, 
        !           161:                                        (c == 'a')?DB_STGY_ANY:DB_STGY_PROC,
        !           162:                                        task);
        !           163:                        db_printf(":\t");
        !           164:                        break;
        !           165:                    case 'm':
        !           166:                        db_next = db_xcdump(addr, size, count+1, task);
        !           167:                        return;
        !           168:                    default:
        !           169:                        if (db_print_position() == 0) {
        !           170:                            /* If we hit a new symbol, print it */
        !           171:                            char *      name;
        !           172:                            db_addr_t   off;
        !           173: 
        !           174:                            db_find_task_sym_and_offset(addr,&name,&off,task);
        !           175:                            if (off == 0)
        !           176:                                db_printf("%s:\t", name);
        !           177:                            else
        !           178:                                db_printf("\t\t");
        !           179: 
        !           180:                            db_prev = addr;
        !           181:                        }
        !           182: 
        !           183:                        switch (c) {
        !           184:                            case ',':   /* skip one unit w/o printing */
        !           185:                                addr += size;
        !           186:                                break;
        !           187: 
        !           188:                            case 'r':   /* signed, current radix */
        !           189:                                value = db_get_task_value(addr,size,TRUE,task);
        !           190:                                addr += size;
        !           191:                                db_printf("%-*R", width, value);
        !           192:                                break;
        !           193:                            case 'x':   /* unsigned hex */
        !           194:                                value = db_get_task_value(addr,size,FALSE,task);
        !           195:                                addr += size;
        !           196:                                db_printf("%-*X", width, value);
        !           197:                                break;
        !           198:                            case 'z':   /* signed hex */
        !           199:                                value = db_get_task_value(addr,size,TRUE,task);
        !           200:                                addr += size;
        !           201:                                db_printf("%-*Z", width, value);
        !           202:                                break;
        !           203:                            case 'd':   /* signed decimal */
        !           204:                                value = db_get_task_value(addr,size,TRUE,task);
        !           205:                                addr += size;
        !           206:                                db_printf("%-*D", width, value);
        !           207:                                break;
        !           208:                            case 'U':   /* unsigned decimal */
        !           209:                                value = db_get_task_value(addr,size,FALSE,task);
        !           210:                                addr += size;
        !           211:                                db_printf("%-*U", width, value);
        !           212:                                break;
        !           213:                            case 'o':   /* unsigned octal */
        !           214:                                value = db_get_task_value(addr,size,FALSE,task);
        !           215:                                addr += size;
        !           216:                                db_printf("%-*O", width, value);
        !           217:                                break;
        !           218:                            case 'c':   /* character */
        !           219:                                value = db_get_task_value(addr,1,FALSE,task);
        !           220:                                addr += 1;
        !           221:                                if (value >= ' ' && value <= '~')
        !           222:                                    db_printf("%c", value);
        !           223:                                else
        !           224:                                    db_printf("\\%03o", value);
        !           225:                                break;
        !           226:                            case 's':   /* null-terminated string */
        !           227:                                for (;;) {
        !           228:                                    value = db_get_task_value(addr,1,FALSE,task);
        !           229:                                    addr += 1;
        !           230:                                    if (value == 0)
        !           231:                                        break;
        !           232:                                    if (value >= ' ' && value <= '~')
        !           233:                                        db_printf("%c", value);
        !           234:                                    else
        !           235:                                        db_printf("\\%03o", value);
        !           236:                                }
        !           237:                                break;
        !           238:                            case 'i':   /* instruction */
        !           239:                                addr = db_disasm(addr, FALSE, task);
        !           240:                                break;
        !           241:                            case 'I':   /* instruction, alternate form */
        !           242:                                addr = db_disasm(addr, TRUE, task);
        !           243:                                break;
        !           244:                            default:
        !           245:                                break;
        !           246:                        }
        !           247:                        if (db_print_position() != 0)
        !           248:                            db_end_line();
        !           249:                        break;
        !           250:                }
        !           251:            }
        !           252:        }
        !           253:        db_next = addr;
        !           254: }
        !           255: 
        !           256: /*
        !           257:  * Print value.
        !           258:  */
        !           259: char   db_print_format = 'x';
        !           260: 
        !           261: /*ARGSUSED*/
        !           262: void
        !           263: db_print_cmd()
        !           264: {
        !           265:        db_expr_t       value;
        !           266:        int             t;
        !           267:        task_t          task = TASK_NULL;
        !           268: 
        !           269:        if ((t = db_read_token()) == tSLASH) {
        !           270:            if (db_read_token() != tIDENT) {
        !           271:                db_printf("Bad modifier \"/%s\"\n", db_tok_string);
        !           272:                db_error(0);
        !           273:                /* NOTREACHED */
        !           274:            }
        !           275:            if (db_tok_string[0])
        !           276:                db_print_format = db_tok_string[0];
        !           277:            if (db_option(db_tok_string, 't') && db_default_thread)
        !           278:                task = db_default_thread->task;
        !           279:        } else
        !           280:            db_unread_token(t);
        !           281:        
        !           282:        for ( ; ; ) {
        !           283:            t = db_read_token();
        !           284:            if (t == tSTRING) {
        !           285:                db_printf("%s", db_tok_string);
        !           286:                continue;
        !           287:            }
        !           288:            db_unread_token(t);
        !           289:            if (!db_expression(&value))
        !           290:                break;
        !           291:            switch (db_print_format) {
        !           292:            case 'a':
        !           293:                db_task_printsym((db_addr_t)value, DB_STGY_ANY, task);
        !           294:                break;
        !           295:            case 'r':
        !           296:                db_printf("%*r", 3+2*sizeof(db_expr_t), value);
        !           297:                break;
        !           298:            case 'x':
        !           299:                db_printf("%*x", 2*sizeof(db_expr_t), value);
        !           300:                break;
        !           301:            case 'z':
        !           302:                db_printf("%*z", 2*sizeof(db_expr_t), value);
        !           303:                break;
        !           304:            case 'd':
        !           305:                db_printf("%*d", 3+2*sizeof(db_expr_t), value);
        !           306:                break;
        !           307:            case 'u':
        !           308:                db_printf("%*u", 3+2*sizeof(db_expr_t), value);
        !           309:                break;
        !           310:            case 'o':
        !           311:                db_printf("%o", 4*sizeof(db_expr_t), value);
        !           312:                break;
        !           313:            case 'c':
        !           314:                value = value & 0xFF;
        !           315:                if (value >= ' ' && value <= '~')
        !           316:                    db_printf("%c", value);
        !           317:                else
        !           318:                    db_printf("\\%03o", value);
        !           319:                break;
        !           320:            default:
        !           321:                db_printf("Unknown format %c\n", db_print_format);
        !           322:                db_print_format = 'x';
        !           323:                db_error(0);
        !           324:            }
        !           325:        }
        !           326: }
        !           327: 
        !           328: void
        !           329: db_print_loc_and_inst(loc, task)
        !           330:        db_addr_t       loc;
        !           331:        task_t          task;
        !           332: {
        !           333:        db_task_printsym(loc, DB_STGY_PROC, task);
        !           334:        db_printf(":\t");
        !           335:        (void) db_disasm(loc, TRUE, task);
        !           336: }
        !           337: 
        !           338: void
        !           339: db_strcpy(dst, src)
        !           340:        register char *dst;
        !           341:        register char *src;
        !           342: {
        !           343:        while (*dst++ = *src++)
        !           344:            ;
        !           345: }
        !           346: 
        !           347: void db_search(); /*forward*/
        !           348: /*
        !           349:  * Search for a value in memory.
        !           350:  * Syntax: search [/bhl] addr value [mask] [,count] [thread]
        !           351:  */
        !           352: void
        !           353: db_search_cmd()
        !           354: {
        !           355:        int             t;
        !           356:        db_addr_t       addr;
        !           357:        int             size = 0;
        !           358:        db_expr_t       value;
        !           359:        db_expr_t       mask;
        !           360:        db_addr_t       count;
        !           361:        thread_t        thread;
        !           362:        boolean_t       thread_flag = FALSE;
        !           363:        register char   *p;
        !           364: 
        !           365:        t = db_read_token();
        !           366:        if (t == tSLASH) {
        !           367:            t = db_read_token();
        !           368:            if (t != tIDENT) {
        !           369:              bad_modifier:
        !           370:                db_printf("Bad modifier \"/%s\"\n", db_tok_string);
        !           371:                db_flush_lex();
        !           372:                return;
        !           373:            }
        !           374: 
        !           375:            for (p = db_tok_string; *p; p++) {
        !           376:                switch(*p) {
        !           377:                case 'b':
        !           378:                    size = sizeof(char);
        !           379:                    break;
        !           380:                case 'h':
        !           381:                    size = sizeof(short);
        !           382:                    break;
        !           383:                case 'l':
        !           384:                    size = sizeof(long);
        !           385:                    break;
        !           386:                case 't':
        !           387:                    thread_flag = TRUE;
        !           388:                    break;
        !           389:                default:
        !           390:                    goto bad_modifier;
        !           391:                }
        !           392:            }
        !           393:        } else {
        !           394:            db_unread_token(t);
        !           395:            size = sizeof(int);
        !           396:        }
        !           397: 
        !           398:        if (!db_expression(&addr)) {
        !           399:            db_printf("Address missing\n");
        !           400:            db_flush_lex();
        !           401:            return;
        !           402:        }
        !           403: 
        !           404:        if (!db_expression(&value)) {
        !           405:            db_printf("Value missing\n");
        !           406:            db_flush_lex();
        !           407:            return;
        !           408:        }
        !           409: 
        !           410:        if (!db_expression(&mask))
        !           411:            mask = ~0;
        !           412: 
        !           413:        t = db_read_token();
        !           414:        if (t == tCOMMA) {
        !           415:            if (!db_expression(&count)) {
        !           416:                db_printf("Count missing\n");
        !           417:                db_flush_lex();
        !           418:                return;
        !           419:            }
        !           420:        } else {
        !           421:            db_unread_token(t);
        !           422:            count = -1;         /* effectively forever */
        !           423:        }
        !           424:        if (thread_flag) {
        !           425:            if (!db_get_next_thread(&thread, 0))
        !           426:                return;
        !           427:        } else
        !           428:            thread = THREAD_NULL;
        !           429: 
        !           430:        db_search(addr, size, value, mask, count, db_thread_to_task(thread));
        !           431: }
        !           432: 
        !           433: void
        !           434: db_search(addr, size, value, mask, count, task)
        !           435:        register
        !           436:        db_addr_t       addr;
        !           437:        int             size;
        !           438:        db_expr_t       value;
        !           439:        db_expr_t       mask;
        !           440:        unsigned int    count;
        !           441:        task_t          task;
        !           442: {
        !           443:        while (count-- != 0) {
        !           444:                db_prev = addr;
        !           445:                if ((db_get_task_value(addr,size,FALSE,task) & mask) == value)
        !           446:                        break;
        !           447:                addr += size;
        !           448:        }
        !           449:        db_next = addr;
        !           450: }
        !           451: 
        !           452: #define DB_XCDUMP_NC   16
        !           453: 
        !           454: int
        !           455: db_xcdump(addr, size, count, task)
        !           456:        db_addr_t       addr;
        !           457:        int             size;
        !           458:        int             count;
        !           459:        task_t          task;
        !           460: {
        !           461:        register        i, n;
        !           462:        db_expr_t       value;
        !           463:        int             bcount;
        !           464:        db_addr_t       off;
        !           465:        char            *name;
        !           466:        char            data[DB_XCDUMP_NC];
        !           467: 
        !           468:        db_find_task_sym_and_offset(addr, &name, &off, task);
        !           469:        for (n = count*size; n > 0; n -= bcount) {
        !           470:            db_prev = addr;
        !           471:            if (off == 0) {
        !           472:                db_printf("%s:\n", name);
        !           473:                off = -1;
        !           474:            }
        !           475:            db_printf("%0*X:%s", 2*sizeof(db_addr_t), addr,
        !           476:                        (size != 1)? " ": "");
        !           477:            bcount = ((n > DB_XCDUMP_NC)? DB_XCDUMP_NC: n);
        !           478:            if (trunc_page(addr) != trunc_page(addr+bcount-1)) {
        !           479:                db_addr_t next_page_addr = trunc_page(addr+bcount-1);
        !           480:                if (!DB_CHECK_ACCESS(next_page_addr, sizeof(int), task))
        !           481:                    bcount = next_page_addr - addr;
        !           482:            }
        !           483:            db_read_bytes((char *)addr, bcount, data, task);
        !           484:            for (i = 0; i < bcount && off != 0; i += size) {
        !           485:                if (i % 4 == 0)
        !           486:                        db_printf(" ");
        !           487:                value = db_get_task_value(addr, size, FALSE, task);
        !           488:                db_printf("%0*x ", size*2, value);
        !           489:                addr += size;
        !           490:                db_find_task_sym_and_offset(addr, &name, &off, task);
        !           491:            }
        !           492:            db_printf("%*s",
        !           493:                        ((DB_XCDUMP_NC-i)/size)*(size*2+1)+(DB_XCDUMP_NC-i)/4,
        !           494:                         "");
        !           495:            bcount = i;
        !           496:            db_printf("%s*", (size != 1)? " ": "");
        !           497:            for (i = 0; i < bcount; i++) {
        !           498:                value = data[i];
        !           499:                db_printf("%c", (value >= ' ' && value <= '~')? value: '.');
        !           500:            }
        !           501:            db_printf("*\n");
        !           502:        }
        !           503:        return(addr);
        !           504: }
        !           505: 
        !           506: #endif MACH_KDB

unix.superglobalmegacorp.com

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