LCOV - code coverage report
Current view: top level - ddb - db_examine.c (source / functions) Hit Total Coverage
Test: 6.4 Lines: 0 173 0.0 %
Date: 2018-10-19 03:25:38 Functions: 0 7 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*      $OpenBSD: db_examine.c,v 1.23 2016/10/18 19:46:00 naddy 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/systm.h>
      35             : 
      36             : #include <machine/db_machdep.h>           /* type definitions */
      37             : 
      38             : #include <ddb/db_lex.h>
      39             : #include <ddb/db_output.h>
      40             : #include <ddb/db_command.h>
      41             : #include <ddb/db_sym.h>
      42             : #include <ddb/db_access.h>
      43             : #include <ddb/db_extern.h>
      44             : #include <ddb/db_interface.h>
      45             : 
      46             : char    db_examine_format[TOK_STRING_SIZE] = "x";
      47             : 
      48             : void db_examine(db_addr_t, char *, int);
      49             : void db_search(db_addr_t, int, db_expr_t, db_expr_t, db_expr_t);
      50             : 
      51             : /*
      52             :  * Examine (print) data.  Syntax is:
      53             :  *              x/[bhlq][cdiorsuxz]*
      54             :  * For example, the command:
      55             :  *      x/bxxxx
      56             :  * should print:
      57             :  *      address:  01  23  45  67
      58             :  */
      59             : /*ARGSUSED*/
      60             : void
      61           0 : db_examine_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
      62             : {
      63           0 :         if (modif[0] != '\0')
      64           0 :                 db_strlcpy(db_examine_format, modif, sizeof(db_examine_format));
      65             : 
      66           0 :         if (count == -1)
      67           0 :                 count = 1;
      68             : 
      69           0 :         db_examine((db_addr_t)addr, db_examine_format, count);
      70           0 : }
      71             : 
      72             : void
      73           0 : db_examine(db_addr_t addr, char *fmt, int count)
      74             : {
      75             :         int             i, c;
      76             :         db_expr_t       value;
      77             :         int             size;
      78             :         int             width;
      79             :         int             bytes;
      80             :         char *          fp;
      81             :         db_addr_t       incr;
      82             :         int             dis;
      83           0 :         char            tmpfmt[28];
      84             : 
      85           0 :         while (--count >= 0) {
      86             :                 fp = fmt;
      87             : 
      88             :                 /* defaults */
      89             :                 size = 4;
      90             :                 width = 12;
      91             :                 incr = 0;
      92             :                 dis = 0;
      93             : 
      94           0 :                 while ((c = *fp++) != 0) {
      95           0 :                         if (db_print_position() == 0) {
      96             :                                 /* Always print the address. */
      97           0 :                                 db_printsym(addr, DB_STGY_ANY, db_printf);
      98           0 :                                 db_printf(":\t");
      99           0 :                                 db_prev = addr;
     100           0 :                         }
     101           0 :                         incr = size;
     102           0 :                         switch (c) {
     103             :                         case 'b':       /* byte */
     104             :                                 size = 1;
     105             :                                 width = 4;
     106           0 :                                 break;
     107             :                         case 'h':       /* half-word */
     108             :                                 size = 2;
     109             :                                 width = 8;
     110           0 :                                 break;
     111             :                         case 'l':       /* long-word */
     112             :                                 size = 4;
     113             :                                 width = 12;
     114           0 :                                 break;
     115             : #ifdef __LP64__
     116             :                         case 'q':       /* quad-word */
     117             :                                 size = 8;
     118             :                                 width = 20;
     119           0 :                                 break;
     120             : #endif
     121             :                         case 'a':       /* address */
     122           0 :                                 db_printf("= 0x%lx\n", (long)addr);
     123             :                                 incr = 0;
     124           0 :                                 break;
     125             :                         case 'r':       /* signed, current radix */
     126           0 :                                 value = db_get_value(addr, size, TRUE);
     127           0 :                                 db_format(tmpfmt, sizeof tmpfmt,
     128             :                                     (long)value, DB_FORMAT_R, 0, width);
     129           0 :                                 db_printf("%-*s", width, tmpfmt);
     130           0 :                                 break;
     131             :                         case 'x':       /* unsigned hex */
     132           0 :                                 value = db_get_value(addr, size, FALSE);
     133           0 :                                 db_printf("%-*lx", width, (long)value);
     134           0 :                                 break;
     135             :                         case 'm':       /* hex dump */
     136             :                                 /*
     137             :                                  * Print off in chunks of size. Try to print 16
     138             :                                  * bytes at a time into 4 columns. This
     139             :                                  * loops modify's count extra times in order
     140             :                                  * to get the nicely formatted lines.
     141             :                                  */
     142             :                                 incr = 0;
     143             :                                 bytes = 0;
     144           0 :                                 do {
     145           0 :                                         for (i = 0; i < size; i++) {
     146             :                                                 value =
     147           0 :                                                     db_get_value(addr+bytes, 1,
     148             :                                                         FALSE);
     149           0 :                                                 db_printf("%02lx",
     150             :                                                     (long)value);
     151           0 :                                                 bytes++;
     152           0 :                                                 if (!(bytes % 4))
     153           0 :                                                         db_printf(" ");
     154             :                                         }
     155           0 :                                 } while ((bytes != 16) && count--);
     156             :                                 /* True up the columns before continuing */
     157           0 :                                 db_printf("%-*s",
     158           0 :                                     (16-bytes)*2 + (4 - bytes/4) + 1, " ");
     159             :                                 /* Print chars, use . for non-printables */
     160           0 :                                 while (bytes--) {
     161           0 :                                         value = db_get_value(addr + incr, 1,
     162             :                                             FALSE);
     163           0 :                                         incr++;
     164           0 :                                         if (value >= ' ' && value <= '~')
     165           0 :                                                 db_printf("%c", (int)value);
     166             :                                         else
     167           0 :                                                 db_printf(".");
     168             :                                 }
     169           0 :                                 db_printf("\n");
     170           0 :                                 break;
     171             :                         case 'z':       /* signed hex */
     172           0 :                                 value = db_get_value(addr, size, TRUE);
     173           0 :                                 db_format(tmpfmt, sizeof tmpfmt,
     174             :                                     (long)value, DB_FORMAT_Z, 0, width);
     175           0 :                                 db_printf("%-*s", width, tmpfmt);
     176           0 :                                 break;
     177             :                         case 'd':       /* signed decimal */
     178           0 :                                 value = db_get_value(addr, size, TRUE);
     179           0 :                                 db_printf("%-*ld", width, (long)value);
     180           0 :                                 break;
     181             :                         case 'u':       /* unsigned decimal */
     182           0 :                                 value = db_get_value(addr, size, FALSE);
     183           0 :                                 db_printf("%-*lu", width, (long)value);
     184           0 :                                 break;
     185             :                         case 'o':       /* unsigned octal */
     186           0 :                                 value = db_get_value(addr, size, FALSE);
     187           0 :                                 db_printf("%-*lo", width, value);
     188           0 :                                 break;
     189             :                         case 'c':       /* character */
     190           0 :                                 value = db_get_value(addr, 1, FALSE);
     191             :                                 incr = 1;
     192           0 :                                 if (value >= ' ' && value <= '~')
     193           0 :                                         db_printf("%c", (int)value);
     194             :                                 else
     195           0 :                                         db_printf("\\%03o", (int)value);
     196             :                                 break;
     197             :                         case 's':       /* null-terminated string */
     198             :                                 incr = 0;
     199           0 :                                 for (;;) {
     200           0 :                                         value = db_get_value(addr + incr, 1,
     201             :                                             FALSE);
     202           0 :                                         incr++;
     203           0 :                                         if (value == 0)
     204             :                                                 break;
     205           0 :                                         if (value >= ' ' && value <= '~')
     206           0 :                                                 db_printf("%c", (int)value);
     207             :                                         else
     208           0 :                                                 db_printf("\\%03o", (int)value);
     209             :                                 }
     210             :                                 break;
     211             :                         case 'i':       /* instruction */
     212             :                         case 'I':       /* instruction, alternate form */
     213             :                                 dis = c;
     214           0 :                                 break;
     215             :                         default:
     216             :                                 incr = 0;
     217           0 :                                 break;
     218             :                         }
     219             :                 }
     220             :                 /* if we had a disassembly modifier, do it last */
     221           0 :                 switch (dis) {
     222             :                 case 'i':       /* instruction */
     223           0 :                         addr = db_disasm(addr, FALSE);
     224           0 :                         break;
     225             :                 case 'I':       /* instruction, alternate form */
     226           0 :                         addr = db_disasm(addr, TRUE);
     227           0 :                         break;
     228             :                 default:
     229           0 :                         addr += incr;
     230           0 :                         break;
     231             :                 }
     232           0 :                 if (db_print_position() != 0)
     233           0 :                         db_printf("\n");
     234             :         }
     235           0 :         db_next = addr;
     236           0 : }
     237             : 
     238             : /*
     239             :  * Print value.
     240             :  */
     241             : char    db_print_format = 'x';
     242             : 
     243             : /*ARGSUSED*/
     244             : void
     245           0 : db_print_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
     246             : {
     247             :         db_expr_t       value;
     248           0 :         char            tmpfmt[28];
     249             : 
     250           0 :         if (modif[0] != '\0')
     251           0 :                 db_print_format = modif[0];
     252             : 
     253           0 :         switch (db_print_format) {
     254             :         case 'a':
     255           0 :                 db_printsym((db_addr_t)addr, DB_STGY_ANY, db_printf);
     256           0 :                 break;
     257             :         case 'r':
     258           0 :                 db_printf("%s", db_format(tmpfmt, sizeof tmpfmt, addr,
     259             :                     DB_FORMAT_R, 0, sizeof(db_expr_t) * 2 * 6 / 5));
     260           0 :                 break;
     261             :         case 'x':
     262           0 :                 db_printf("%*lx", (uint)sizeof(db_expr_t) * 2, addr);
     263           0 :                 break;
     264             :         case 'z':
     265           0 :                 db_printf("%s", db_format(tmpfmt, sizeof tmpfmt, addr,
     266             :                     DB_FORMAT_Z, 0, sizeof(db_expr_t) * 2));
     267           0 :                 break;
     268             :         case 'd':
     269           0 :                 db_printf("%*ld", (uint)sizeof(db_expr_t) * 2 * 6 / 5, addr);
     270           0 :                 break;
     271             :         case 'u':
     272           0 :                 db_printf("%*lu", (uint)sizeof(db_expr_t) * 2 * 6 / 5, addr);
     273           0 :                 break;
     274             :         case 'o':
     275           0 :                 db_printf("%*lo", (uint)sizeof(db_expr_t) * 2 * 4 / 3, addr);
     276           0 :                 break;
     277             :         case 'c':
     278           0 :                 value = addr & 0xFF;
     279           0 :                 if (value >= ' ' && value <= '~')
     280           0 :                         db_printf("%c", (int)value);
     281             :                 else
     282           0 :                         db_printf("\\%03o", (int)value);
     283             :                 break;
     284             :         }
     285           0 :         db_printf("\n");
     286           0 : }
     287             : 
     288             : void
     289           0 : db_print_loc_and_inst(db_addr_t loc)
     290             : {
     291           0 :         db_printsym(loc, DB_STGY_PROC, db_printf);
     292           0 :         db_printf(":\t");
     293           0 :         (void) db_disasm(loc, FALSE);
     294           0 : }
     295             : 
     296             : /* local copy is needed here so that we can trace strlcpy() in libkern */
     297             : size_t
     298           0 : db_strlcpy(char *dst, const char *src, size_t siz)
     299             : {
     300             :         char *d = dst;
     301             :         const char *s = src;
     302             :         size_t n = siz;
     303             : 
     304             :         /* Copy as many bytes as will fit */
     305           0 :         if (n != 0 && --n != 0) {
     306           0 :                 do {
     307           0 :                         if ((*d++ = *s++) == 0)
     308             :                                 break;
     309           0 :                 } while (--n != 0);
     310             :         }
     311             : 
     312             :         /* Not enough room in dst, add NUL and traverse rest of src */
     313           0 :         if (n == 0) {
     314           0 :                 if (siz != 0)
     315           0 :                         *d = '\0';              /* NUL-terminate dst */
     316           0 :                 while (*s++)
     317           0 :                         continue;
     318             :         }
     319             : 
     320           0 :         return(s - src - 1);    /* count does not include NUL */
     321             : }
     322             : 
     323             : /*
     324             :  * Search for a value in memory.
     325             :  * Syntax: search [/bhl] addr value [mask] [,count]
     326             :  */
     327             : /*ARGSUSED*/
     328             : void
     329           0 : db_search_cmd(db_expr_t daddr, int have_addr, db_expr_t dcount, char *modif)
     330             : {
     331             :         int             t;
     332             :         db_addr_t       addr;
     333             :         int             size;
     334           0 :         db_expr_t       value;
     335           0 :         db_expr_t       mask;
     336           0 :         db_expr_t       count;
     337             : 
     338           0 :         t = db_read_token();
     339           0 :         if (t == tSLASH) {
     340           0 :                 t = db_read_token();
     341           0 :                 if (t != tIDENT) {
     342             :                         bad_modifier:
     343           0 :                         db_printf("Bad modifier\n");
     344           0 :                         db_flush_lex();
     345           0 :                         return;
     346             :                 }
     347             : 
     348           0 :                 if (!strcmp(db_tok_string, "b"))
     349           0 :                         size = 1;
     350           0 :                 else if (!strcmp(db_tok_string, "h"))
     351           0 :                         size = 2;
     352           0 :                 else if (!strcmp(db_tok_string, "l"))
     353             :                         size = 4;
     354             :                 else
     355             :                         goto bad_modifier;
     356             :         } else {
     357           0 :                 db_unread_token(t);
     358             :                 size = 4;
     359             :         }
     360             : 
     361           0 :         if (!db_expression(&value)) {
     362           0 :                 db_printf("Address missing\n");
     363           0 :                 db_flush_lex();
     364           0 :                 return;
     365             :         }
     366           0 :         addr = (db_addr_t) value;
     367             : 
     368           0 :         if (!db_expression(&value)) {
     369           0 :                 db_printf("Value missing\n");
     370           0 :                 db_flush_lex();
     371           0 :                 return;
     372             :         }
     373             : 
     374           0 :         if (!db_expression(&mask))
     375           0 :                 mask = (int) ~0;
     376             : 
     377           0 :         t = db_read_token();
     378           0 :         if (t == tCOMMA) {
     379           0 :                 if (!db_expression(&count)) {
     380           0 :                         db_printf("Count missing\n");
     381           0 :                         db_flush_lex();
     382           0 :                         return;
     383             :                 }
     384             :         } else {
     385           0 :                 db_unread_token(t);
     386           0 :                 count = -1;             /* forever */
     387             :         }
     388           0 :         db_skip_to_eol();
     389             : 
     390           0 :         db_search(addr, size, value, mask, count);
     391           0 : }
     392             : 
     393             : void
     394           0 : db_search(db_addr_t addr, int size, db_expr_t value, db_expr_t mask,
     395             :     db_expr_t count)
     396             : {
     397             :         /* Negative counts means forever.  */
     398           0 :         while (count < 0 || count-- != 0) {
     399           0 :                 db_prev = addr;
     400           0 :                 if ((db_get_value(addr, size, FALSE) & mask) == value)
     401             :                         break;
     402           0 :                 addr += size;
     403             :         }
     404           0 :         db_next = addr;
     405           0 : }

Generated by: LCOV version 1.13