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.32 2007/02/22 06:41:00 thorpej 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.32 2007/02/22 06:41:00 thorpej 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, bool have_addr, db_expr_t count,
   65     const char *modif)
   66 {
   67         if (modif[0] != '\0')
   68                 strlcpy(db_examine_format, modif, sizeof(db_examine_format));
   69 
   70         if (count == -1)
   71                 count = 1;
   72 
   73         db_examine((db_addr_t) addr, db_examine_format, count);
   74 }
   75 
   76 static void
   77 db_examine(db_addr_t addr, char *fmt, int count)
   78 {
   79         int             i, c;
   80         db_expr_t       value;
   81         int             size;
   82         int             width;
   83         int             bytes;
   84         char *          fp;
   85         char            tbuf[24];
   86 
   87         while (--count >= 0) {
   88                 fp = fmt;
   89                 size = 4;
   90                 width = 12;
   91                 while ((c = *fp++) != 0) {
   92                         if (db_print_position() == 0) {
   93                                 /* Always print the address. */
   94                                 db_printsym(addr, DB_STGY_ANY, db_printf);
   95                                 db_printf(":\t");
   96                                 db_prev = addr;
   97                         }
   98                         switch (c) {
   99                         case 'b':       /* byte */
  100                                 size = 1;
  101                                 width = 4;
  102                                 break;
  103                         case 'h':       /* half-word */
  104                                 size = 2;
  105                                 width = 8;
  106                                 break;
  107                         case 'l':       /* long-word */
  108                                 size = 4;
  109                                 width = 12;
  110                                 break;
  111                         case 'L':       /* implementation maximum */
  112                                 size = sizeof value;
  113                                 width = 12 * (sizeof value / 4);
  114                                 break;
  115                         case 'a':       /* address */
  116                                 db_printf("= 0x%lx\n", (long)addr);
  117                                 break;
  118                         case 'r':       /* signed, current radix */
  119                                 value = db_get_value(addr, size, true);
  120                                 addr += size;
  121                                 db_format_radix(tbuf, 24, value, false);
  122                                 db_printf("%-*s", width, tbuf);
  123                                 break;
  124                         case 'x':       /* unsigned hex */
  125                                 value = db_get_value(addr, size, false);
  126                                 addr += size;
  127                                 db_printf(DB_EXPR_T_IS_QUAD ? "%-*qx" : "%-*lx",
  128                                     width, value);
  129                                 break;
  130                         case 'm':       /* hex dump */
  131                                 /*
  132                                  * Print off in chunks of size. Try to print 16
  133                                  * bytes at a time into 4 columns. This
  134                                  * loops modify's count extra times in order
  135                                  * to get the nicely formatted lines.
  136                                  */
  137 
  138                                 bytes = 0;
  139                                 do {
  140                                         for (i = 0; i < size; i++) {
  141                                                 value =
  142                                                     db_get_value(addr+bytes, 1,
  143                                                         false);
  144                                                 db_printf(
  145                                                     DB_EXPR_T_IS_QUAD ? "%02qx":
  146                                                     "%02lx", value);
  147                                                 bytes++;
  148                                                 if (!(bytes % 4))
  149                                                         db_printf(" ");
  150                                         }
  151                                 } while ((bytes != 16) && count--);
  152                                 /* True up the columns before continuing */
  153                                 for (i = 4; i >= (bytes / 4); i--)
  154                                         db_printf ("\t");
  155                                 /* Print chars,  use . for non-printable's. */
  156                                 while (bytes--) {
  157                                         value = db_get_value(addr, 1, false);
  158                                         addr += 1;
  159                                         if (value >= ' ' && value <= '~')
  160                                                 db_printf("%c", (char)value);
  161                                         else
  162                                                 db_printf(".");
  163                                 }
  164                                 db_printf("\n");
  165                                 break;
  166                         case 'z':       /* signed hex */
  167                                 value = db_get_value(addr, size, true);
  168                                 addr += size;
  169                                 db_format_hex(tbuf, 24, value, false);
  170                                 db_printf("%-*s", width, tbuf);
  171                                 break;
  172                         case 'd':       /* signed decimal */
  173                                 value = db_get_value(addr, size, true);
  174                                 addr += size;
  175                                 db_printf(DB_EXPR_T_IS_QUAD ? "%-*qd" : "%-*ld",
  176                                     width, value);
  177                                 break;
  178                         case 'u':       /* unsigned decimal */
  179                                 value = db_get_value(addr, size, false);
  180                                 addr += size;
  181                                 db_printf(DB_EXPR_T_IS_QUAD ? "%-*qu" : "%-*lu",
  182                                     width, value);
  183                                 break;
  184                         case 'o':       /* unsigned octal */
  185                                 value = db_get_value(addr, size, false);
  186                                 addr += size;
  187                                 db_printf(DB_EXPR_T_IS_QUAD ? "%-*qo" : "%-*lo",
  188                                     width, value);
  189                                 break;
  190                         case 'c':       /* character */
  191                                 value = db_get_value(addr, 1, false);
  192                                 addr += 1;
  193                                 if (value >= ' ' && value <= '~')
  194                                         db_printf("%c", (char)value);
  195                                 else
  196                                         db_printf("\\%03o", (int)value);
  197                                 break;
  198                         case 's':       /* null-terminated string */
  199                                 for (;;) {
  200                                         value = db_get_value(addr, 1, false);
  201                                         addr += 1;
  202                                         if (value == 0)
  203                                                 break;
  204                                         if (value >= ' ' && value <= '~')
  205                                                 db_printf("%c", (char)value);
  206                                         else
  207                                                 db_printf("\\%03o", (int)value);
  208                                 }
  209                                 break;
  210                         case 'i':       /* instruction */
  211                                 addr = db_disasm(addr, false);
  212                                 break;
  213                         case 'I':       /* instruction, alternate form */
  214                                 addr = db_disasm(addr, true);
  215                                 break;
  216                         default:
  217                                 break;
  218                         }
  219                         if (db_print_position() != 0)
  220                                 db_end_line();
  221                 }
  222         }
  223         db_next = addr;
  224 }
  225 
  226 /*
  227  * Print value.
  228  */
  229 static char     db_print_format = 'x';
  230 
  231 /*ARGSUSED*/
  232 void
  233 db_print_cmd(db_expr_t addr, bool have_addr, db_expr_t count,
  234     const char *modif)
  235 {
  236         db_expr_t       value;
  237 
  238         if (modif[0] != '\0')
  239                 db_print_format = modif[0];
  240 
  241         switch (db_print_format) {
  242         case 'a':
  243                 db_printsym((db_addr_t)addr, DB_STGY_ANY, db_printf);
  244                 break;
  245         case 'r':
  246                 {
  247                         char tbuf[24];
  248 
  249                         db_format_radix(tbuf, 24, addr, false);
  250                         db_printf("%11s", tbuf);
  251                         break;
  252                 }
  253         case 'x':
  254                 db_printf(DB_EXPR_T_IS_QUAD ? "%16qx" : "%8lx", addr);
  255                 break;
  256         case 'z':
  257                 {
  258                         char tbuf[24];
  259 
  260                         db_format_hex(tbuf, 24, addr, false);
  261                         db_printf("%8s", tbuf);
  262                         break;
  263                 }
  264         case 'd':
  265                 db_printf(DB_EXPR_T_IS_QUAD ? "%11qd" : "%11ld", addr);
  266                 break;
  267         case 'u':
  268                 db_printf(DB_EXPR_T_IS_QUAD ? "%11qu" : "%11lu", addr);
  269                 break;
  270         case 'o':
  271                 db_printf(DB_EXPR_T_IS_QUAD ? "%15qo" : "%16lo", addr);
  272                 break;
  273         case 'c':
  274                 value = addr & 0xFF;
  275                 if (value >= ' ' && value <= '~')
  276                         db_printf("%c", (char)value);
  277                 else
  278                         db_printf("\\%03o", (int)value);
  279                 break;
  280         }
  281         db_printf("\n");
  282 }
  283 
  284 void
  285 db_print_loc_and_inst(db_addr_t loc)
  286 {
  287 
  288         db_printsym(loc, DB_STGY_PROC, db_printf);
  289         db_printf(":\t");
  290         (void) db_disasm(loc, false);
  291 }
  292 
  293 /*
  294  * Search for a value in memory.
  295  * Syntax: search [/bhl] addr value [mask] [,count]
  296  */
  297 /*ARGSUSED*/
  298 void
  299 db_search_cmd(db_expr_t daddr, bool have_addr,
  300     db_expr_t dcount, const char *modif)
  301 {
  302         int             t;
  303         db_addr_t       addr;
  304         int             size;
  305         db_expr_t       value;
  306         db_expr_t       mask;
  307         db_expr_t       count;
  308 
  309         t = db_read_token();
  310         if (t == tSLASH) {
  311                 t = db_read_token();
  312                 if (t != tIDENT) {
  313                         bad_modifier:
  314                         db_printf("Bad modifier\n");
  315                         db_flush_lex();
  316                         return;
  317                 }
  318 
  319                 if (!strcmp(db_tok_string, "b"))
  320                         size = 1;
  321                 else if (!strcmp(db_tok_string, "h"))
  322                         size = 2;
  323                 else if (!strcmp(db_tok_string, "l"))
  324                         size = 4;
  325                 else
  326                         goto bad_modifier;
  327         } else {
  328                 db_unread_token(t);
  329                 size = 4;
  330         }
  331 
  332         if (!db_expression(&value)) {
  333                 db_printf("Address missing\n");
  334                 db_flush_lex();
  335                 return;
  336         }
  337         addr = (db_addr_t) value;
  338 
  339         if (!db_expression(&value)) {
  340                 db_printf("Value missing\n");
  341                 db_flush_lex();
  342                 return;
  343         }
  344 
  345         if (!db_expression(&mask))
  346                 mask = (int) ~0;
  347 
  348         t = db_read_token();
  349         if (t == tCOMMA) {
  350                 if (!db_expression(&count)) {
  351                         db_printf("Count missing\n");
  352                         db_flush_lex();
  353                         return;
  354                 }
  355         } else {
  356                 db_unread_token(t);
  357                 count = -1;             /* effectively forever */
  358         }
  359         db_skip_to_eol();
  360 
  361         db_search(addr, size, value, mask, count);
  362 }
  363 
  364 static void
  365 db_search(db_addr_t addr, int size, db_expr_t value, db_expr_t mask,
  366     unsigned int count)
  367 {
  368         while (count-- != 0) {
  369                 db_prev = addr;
  370                 if ((db_get_value(addr, size, false) & mask) == value)
  371                         break;
  372                 addr += size;
  373         }
  374         db_next = addr;
  375 }

Cache object: a8b35456c2757bbe214b7bdbb9c50b25


[ 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.