The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/ddb/db_examine.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: 106b94a067b2a44908c947de8d6085bf


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.