[BACK]Return to db_examine.c CVS log [TXT][DIR] Up to [local] / sys / ddb

Annotation of sys/ddb/db_examine.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: db_examine.c,v 1.13 2007/03/15 17:10:22 miod Exp $    */
                      2: /*     $NetBSD: db_examine.c,v 1.11 1996/03/30 22:30:07 christos Exp $ */
                      3:
                      4: /*
                      5:  * Mach Operating System
                      6:  * Copyright (c) 1993,1992,1991,1990 Carnegie Mellon University
                      7:  * All Rights Reserved.
                      8:  *
                      9:  * Permission to use, copy, modify and distribute this software and its
                     10:  * documentation is hereby granted, provided that both the copyright
                     11:  * notice and this permission notice appear in all copies of the
                     12:  * software, derivative works or modified versions, and any portions
                     13:  * thereof, and that both notices appear in supporting documentation.
                     14:  *
                     15:  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
                     16:  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
                     17:  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
                     18:  *
                     19:  * Carnegie Mellon requests users of this software to return to
                     20:  *
                     21:  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
                     22:  *  School of Computer Science
                     23:  *  Carnegie Mellon University
                     24:  *  Pittsburgh PA 15213-3890
                     25:  *
                     26:  * any improvements or extensions that they make and grant Carnegie Mellon
                     27:  * the rights to redistribute these changes.
                     28:  *
                     29:  *     Author: David B. Golub, Carnegie Mellon University
                     30:  *     Date:   7/90
                     31:  */
                     32:
                     33: #include <sys/param.h>
                     34: #include <sys/proc.h>
                     35:
                     36: #include <uvm/uvm_extern.h>
                     37:
                     38: #include <machine/db_machdep.h>                /* type definitions */
                     39:
                     40: #include <ddb/db_lex.h>
                     41: #include <ddb/db_output.h>
                     42: #include <ddb/db_command.h>
                     43: #include <ddb/db_sym.h>
                     44: #include <ddb/db_access.h>
                     45: #include <ddb/db_extern.h>
                     46: #include <ddb/db_interface.h>
                     47:
                     48: char   db_examine_format[TOK_STRING_SIZE] = "x";
                     49:
                     50: /*
                     51:  * Examine (print) data.  Syntax is:
                     52:  *             x/[bhlq][cdiorsuxz]*
                     53:  * For example, the command:
                     54:  *     x/bxxxx
                     55:  * should print:
                     56:  *     address:  01  23  45  67
                     57:  */
                     58: /*ARGSUSED*/
                     59: void
                     60: db_examine_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
                     61: {
                     62:        if (modif[0] != '\0')
                     63:                db_strlcpy(db_examine_format, modif, sizeof(db_examine_format));
                     64:
                     65:        if (count == -1)
                     66:                count = 1;
                     67:
                     68:        db_examine((db_addr_t)addr, db_examine_format, count);
                     69: }
                     70:
                     71: void
                     72: db_examine(db_addr_t addr, char *fmt, int count)
                     73: {
                     74:        int             c;
                     75:        db_expr_t       value;
                     76:        int             size;
                     77:        int             width;
                     78:        char *          fp;
                     79:
                     80:        while (--count >= 0) {
                     81:                fp = fmt;
                     82:                size = 4;
                     83:                width = 12;
                     84:                while ((c = *fp++) != 0) {
                     85:                        if (db_print_position() == 0) {
                     86:                                /* Always print the address. */
                     87:                                db_printsym(addr, DB_STGY_ANY, db_printf);
                     88:                                db_printf(":\t");
                     89:                                db_prev = addr;
                     90:                        }
                     91:                        switch (c) {
                     92:                        case 'b':       /* byte */
                     93:                                size = 1;
                     94:                                width = 4;
                     95:                                break;
                     96:                        case 'h':       /* half-word */
                     97:                                size = 2;
                     98:                                width = 8;
                     99:                                break;
                    100:                        case 'l':       /* long-word */
                    101:                                size = 4;
                    102:                                width = 12;
                    103:                                break;
                    104: #ifdef __LP64__
                    105:                        case 'q':       /* quad-word */
                    106:                                size = 8;
                    107:                                width = 20;
                    108:                                break;
                    109: #endif
                    110:                        case 'a':       /* address */
                    111:                                db_printf("= 0x%lx\n", (long)addr);
                    112:                                break;
                    113:                        case 'r':       /* signed, current radix */
                    114:                                value = db_get_value(addr, size, TRUE);
                    115:                                addr += size;
                    116:                                db_printf("%-*lr", width, (long)value);
                    117:                                break;
                    118:                        case 'x':       /* unsigned hex */
                    119:                                value = db_get_value(addr, size, FALSE);
                    120:                                addr += size;
                    121:                                db_printf("%-*lx", width, (long)value);
                    122:                                break;
                    123:                        case 'z':       /* signed hex */
                    124:                                value = db_get_value(addr, size, TRUE);
                    125:                                addr += size;
                    126:                                db_printf("%-*lz", width, (long)value);
                    127:                                break;
                    128:                        case 'd':       /* signed decimal */
                    129:                                value = db_get_value(addr, size, TRUE);
                    130:                                addr += size;
                    131:                                db_printf("%-*ld", width, (long)value);
                    132:                                break;
                    133:                        case 'u':       /* unsigned decimal */
                    134:                                value = db_get_value(addr, size, FALSE);
                    135:                                addr += size;
                    136:                                db_printf("%-*lu", width, (long)value);
                    137:                                break;
                    138:                        case 'o':       /* unsigned octal */
                    139:                                value = db_get_value(addr, size, FALSE);
                    140:                                addr += size;
                    141:                                db_printf("%-*lo", width, value);
                    142:                                break;
                    143:                        case 'c':       /* character */
                    144:                                value = db_get_value(addr, 1, FALSE);
                    145:                                addr += 1;
                    146:                                if (value >= ' ' && value <= '~')
                    147:                                        db_printf("%c", value);
                    148:                                else
                    149:                                        db_printf("\\%03o", value);
                    150:                                break;
                    151:                        case 's':       /* null-terminated string */
                    152:                                for (;;) {
                    153:                                        value = db_get_value(addr, 1, FALSE);
                    154:                                        addr += 1;
                    155:                                        if (value == 0)
                    156:                                                break;
                    157:                                        if (value >= ' ' && value <= '~')
                    158:                                                db_printf("%c", value);
                    159:                                        else
                    160:                                                db_printf("\\%03o", value);
                    161:                                }
                    162:                                break;
                    163:                        case 'i':       /* instruction */
                    164:                                addr = db_disasm(addr, FALSE);
                    165:                                break;
                    166:                        case 'I':       /* instruction, alternate form */
                    167:                                addr = db_disasm(addr, TRUE);
                    168:                                break;
                    169:                        default:
                    170:                                break;
                    171:                        }
                    172:                        if (db_print_position() != 0)
                    173:                                db_end_line(width);
                    174:                }
                    175:        }
                    176:        db_next = addr;
                    177: }
                    178:
                    179: /*
                    180:  * Print value.
                    181:  */
                    182: char   db_print_format = 'x';
                    183:
                    184: /*ARGSUSED*/
                    185: void
                    186: db_print_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
                    187: {
                    188:        db_expr_t       value;
                    189:
                    190:        if (modif[0] != '\0')
                    191:                db_print_format = modif[0];
                    192:
                    193:        switch (db_print_format) {
                    194:        case 'a':
                    195:                db_printsym((db_addr_t)addr, DB_STGY_ANY, db_printf);
                    196:                break;
                    197:        case 'r':
                    198:                db_printf("%*r", sizeof(db_expr_t) * 2 * 6 / 5, addr);
                    199:                break;
                    200:        case 'x':
                    201:                db_printf("%*x", sizeof(db_expr_t) * 2, addr);
                    202:                break;
                    203:        case 'z':
                    204:                db_printf("%*z", sizeof(db_expr_t) * 2, addr);
                    205:                break;
                    206:        case 'd':
                    207:                db_printf("%*d", sizeof(db_expr_t) * 2 * 6 / 5, addr);
                    208:                break;
                    209:        case 'u':
                    210:                db_printf("%*u", sizeof(db_expr_t) * 2 * 6 / 5, addr);
                    211:                break;
                    212:        case 'o':
                    213:                db_printf("%*o", sizeof(db_expr_t) * 2 * 4 / 3, addr);
                    214:                break;
                    215:        case 'c':
                    216:                value = addr & 0xFF;
                    217:                if (value >= ' ' && value <= '~')
                    218:                        db_printf("%c", value);
                    219:                else
                    220:                        db_printf("\\%03o", value);
                    221:                break;
                    222:        }
                    223:        db_printf("\n");
                    224: }
                    225:
                    226: void
                    227: db_print_loc_and_inst(db_addr_t loc)
                    228: {
                    229:        db_printsym(loc, DB_STGY_PROC, db_printf);
                    230:        db_printf(":\t");
                    231:        (void) db_disasm(loc, FALSE);
                    232: }
                    233:
                    234: /* local copy is needed here so that we can trace strlcpy() in libkern */
                    235: size_t
                    236: db_strlcpy(char *dst, const char *src, size_t siz)
                    237: {
                    238:        char *d = dst;
                    239:        const char *s = src;
                    240:        size_t n = siz;
                    241:
                    242:        /* Copy as many bytes as will fit */
                    243:        if (n != 0 && --n != 0) {
                    244:                do {
                    245:                        if ((*d++ = *s++) == 0)
                    246:                                break;
                    247:                } while (--n != 0);
                    248:        }
                    249:
                    250:        /* Not enough room in dst, add NUL and traverse rest of src */
                    251:        if (n == 0) {
                    252:                if (siz != 0)
                    253:                        *d = '\0';              /* NUL-terminate dst */
                    254:                while (*s++)
                    255:                        ;
                    256:        }
                    257:
                    258:        return(s - src - 1);    /* count does not include NUL */
                    259: }
                    260:
                    261: /*
                    262:  * Search for a value in memory.
                    263:  * Syntax: search [/bhl] addr value [mask] [,count]
                    264:  */
                    265: /*ARGSUSED*/
                    266: void
                    267: db_search_cmd(db_expr_t daddr, int have_addr, db_expr_t dcount, char *modif)
                    268: {
                    269:        int             t;
                    270:        db_addr_t       addr;
                    271:        int             size;
                    272:        db_expr_t       value;
                    273:        db_expr_t       mask;
                    274:        db_expr_t       count;
                    275:
                    276:        t = db_read_token();
                    277:        if (t == tSLASH) {
                    278:                t = db_read_token();
                    279:                if (t != tIDENT) {
                    280:                        bad_modifier:
                    281:                        db_printf("Bad modifier\n");
                    282:                        db_flush_lex();
                    283:                        return;
                    284:                }
                    285:
                    286:                if (!strcmp(db_tok_string, "b"))
                    287:                        size = 1;
                    288:                else if (!strcmp(db_tok_string, "h"))
                    289:                        size = 2;
                    290:                else if (!strcmp(db_tok_string, "l"))
                    291:                        size = 4;
                    292:                else
                    293:                        goto bad_modifier;
                    294:        } else {
                    295:                db_unread_token(t);
                    296:                size = 4;
                    297:        }
                    298:
                    299:        if (!db_expression(&value)) {
                    300:                db_printf("Address missing\n");
                    301:                db_flush_lex();
                    302:                return;
                    303:        }
                    304:        addr = (db_addr_t) value;
                    305:
                    306:        if (!db_expression(&value)) {
                    307:                db_printf("Value missing\n");
                    308:                db_flush_lex();
                    309:                return;
                    310:        }
                    311:
                    312:        if (!db_expression(&mask))
                    313:                mask = (int) ~0;
                    314:
                    315:        t = db_read_token();
                    316:        if (t == tCOMMA) {
                    317:                if (!db_expression(&count)) {
                    318:                        db_printf("Count missing\n");
                    319:                        db_flush_lex();
                    320:                        return;
                    321:                }
                    322:        } else {
                    323:                db_unread_token(t);
                    324:                count = -1;             /* forever */
                    325:        }
                    326:        db_skip_to_eol();
                    327:
                    328:        db_search(addr, size, value, mask, count);
                    329: }
                    330:
                    331: void
                    332: db_search(db_addr_t addr, int size, db_expr_t value, db_expr_t mask,
                    333:     db_expr_t count)
                    334: {
                    335:        /* Negative counts means forever.  */
                    336:        while (count < 0 || count-- != 0) {
                    337:                db_prev = addr;
                    338:                if ((db_get_value(addr, size, FALSE) & mask) == value)
                    339:                        break;
                    340:                addr += size;
                    341:        }
                    342:        db_next = addr;
                    343: }

CVSweb