db_examine.c revision 173077
1139747Simp/*- 24Srgrimes * Mach Operating System 34Srgrimes * Copyright (c) 1991,1990 Carnegie Mellon University 44Srgrimes * All Rights Reserved. 58876Srgrimes * 64Srgrimes * Permission to use, copy, modify and distribute this software and its 74Srgrimes * documentation is hereby granted, provided that both the copyright 84Srgrimes * notice and this permission notice appear in all copies of the 94Srgrimes * software, derivative works or modified versions, and any portions 104Srgrimes * thereof, and that both notices appear in supporting documentation. 118876Srgrimes * 128876Srgrimes * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS 134Srgrimes * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR 144Srgrimes * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 158876Srgrimes * 164Srgrimes * Carnegie Mellon requests users of this software to return to 178876Srgrimes * 184Srgrimes * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 194Srgrimes * School of Computer Science 204Srgrimes * Carnegie Mellon University 214Srgrimes * Pittsburgh PA 15213-3890 228876Srgrimes * 234Srgrimes * any improvements or extensions that they make and grant Carnegie the 244Srgrimes * rights to redistribute these changes. 254Srgrimes */ 264Srgrimes/* 274Srgrimes * Author: David B. Golub, Carnegie Mellon University 284Srgrimes * Date: 7/90 294Srgrimes */ 3047098Sbde 31116176Sobrien#include <sys/cdefs.h> 32116176Sobrien__FBSDID("$FreeBSD: head/sys/ddb/db_examine.c 173077 2007-10-27 20:19:11Z jhb $"); 33116176Sobrien 342056Swollman#include <sys/param.h> 3547098Sbde#include <sys/systm.h> 364Srgrimes 372056Swollman#include <ddb/ddb.h> 38798Swollman 392056Swollman#include <ddb/db_lex.h> 402056Swollman#include <ddb/db_output.h> 412056Swollman#include <ddb/db_command.h> 422056Swollman#include <ddb/db_sym.h> 432056Swollman#include <ddb/db_access.h> 444Srgrimes 4512515Sphkstatic char db_examine_format[TOK_STRING_SIZE] = "x"; 464Srgrimes 4792756Salfredstatic void db_examine(db_addr_t, char *, int); 4892756Salfredstatic void db_search(db_addr_t, int, db_expr_t, db_expr_t, u_int); 49798Swollman 504Srgrimes/* 514Srgrimes * Examine (print) data. 524Srgrimes */ 534Srgrimes/*ARGSUSED*/ 544Srgrimesvoid 554Srgrimesdb_examine_cmd(addr, have_addr, count, modif) 564Srgrimes db_expr_t addr; 5712473Sbde boolean_t have_addr; 584Srgrimes db_expr_t count; 594Srgrimes char * modif; 604Srgrimes{ 614Srgrimes if (modif[0] != '\0') 624Srgrimes db_strcpy(db_examine_format, modif); 634Srgrimes 644Srgrimes if (count == -1) 654Srgrimes count = 1; 664Srgrimes 674Srgrimes db_examine((db_addr_t) addr, db_examine_format, count); 684Srgrimes} 694Srgrimes 70798Swollmanstatic void 714Srgrimesdb_examine(addr, fmt, count) 724Srgrimes register 734Srgrimes db_addr_t addr; 744Srgrimes char * fmt; /* format string */ 754Srgrimes int count; /* repeat count */ 764Srgrimes{ 774Srgrimes int c; 784Srgrimes db_expr_t value; 794Srgrimes int size; 804Srgrimes int width; 814Srgrimes char * fp; 824Srgrimes 83173077Sjhb while (--count >= 0 && !db_pager_quit) { 844Srgrimes fp = fmt; 854Srgrimes size = 4; 864Srgrimes while ((c = *fp++) != 0) { 874Srgrimes switch (c) { 884Srgrimes case 'b': 894Srgrimes size = 1; 904Srgrimes break; 914Srgrimes case 'h': 924Srgrimes size = 2; 934Srgrimes break; 944Srgrimes case 'l': 954Srgrimes size = 4; 964Srgrimes break; 9737390Sdfr case 'g': 9837390Sdfr size = 8; 9937390Sdfr break; 1004Srgrimes case 'a': /* address */ 10198815Stmm size = sizeof(void *); 1024Srgrimes /* always forces a new line */ 1034Srgrimes if (db_print_position() != 0) 1044Srgrimes db_printf("\n"); 1054Srgrimes db_prev = addr; 1064Srgrimes db_printsym(addr, DB_STGY_ANY); 1074Srgrimes db_printf(":\t"); 1084Srgrimes break; 1094Srgrimes default: 1104Srgrimes if (db_print_position() == 0) { 1118698Sdg /* Print the address. */ 1128698Sdg db_printsym(addr, DB_STGY_ANY); 1138698Sdg db_printf(":\t"); 1144Srgrimes db_prev = addr; 1154Srgrimes } 1164Srgrimes 11798815Stmm width = size * 4; 1184Srgrimes switch (c) { 1194Srgrimes case 'r': /* signed, current radix */ 1204Srgrimes value = db_get_value(addr, size, TRUE); 1214Srgrimes addr += size; 12248407Speter db_printf("%+-*lr", width, (long)value); 1234Srgrimes break; 1244Srgrimes case 'x': /* unsigned hex */ 1254Srgrimes value = db_get_value(addr, size, FALSE); 1264Srgrimes addr += size; 12748407Speter db_printf("%-*lx", width, (long)value); 1284Srgrimes break; 1294Srgrimes case 'z': /* signed hex */ 1304Srgrimes value = db_get_value(addr, size, TRUE); 1314Srgrimes addr += size; 132105954Smux db_printf("%-*ly", width, (long)value); 1334Srgrimes break; 1344Srgrimes case 'd': /* signed decimal */ 1354Srgrimes value = db_get_value(addr, size, TRUE); 1364Srgrimes addr += size; 13748407Speter db_printf("%-*ld", width, (long)value); 1384Srgrimes break; 1394Srgrimes case 'u': /* unsigned decimal */ 1404Srgrimes value = db_get_value(addr, size, FALSE); 1414Srgrimes addr += size; 14248407Speter db_printf("%-*lu", width, (long)value); 1434Srgrimes break; 1444Srgrimes case 'o': /* unsigned octal */ 1454Srgrimes value = db_get_value(addr, size, FALSE); 1464Srgrimes addr += size; 14748407Speter db_printf("%-*lo", width, (long)value); 1484Srgrimes break; 1494Srgrimes case 'c': /* character */ 1504Srgrimes value = db_get_value(addr, 1, FALSE); 1514Srgrimes addr += 1; 1524Srgrimes if (value >= ' ' && value <= '~') 15348407Speter db_printf("%c", (int)value); 1544Srgrimes else 15548407Speter db_printf("\\%03o", (int)value); 1564Srgrimes break; 1574Srgrimes case 's': /* null-terminated string */ 1584Srgrimes for (;;) { 1594Srgrimes value = db_get_value(addr, 1, FALSE); 1604Srgrimes addr += 1; 1614Srgrimes if (value == 0) 1624Srgrimes break; 1634Srgrimes if (value >= ' ' && value <= '~') 16448407Speter db_printf("%c", (int)value); 1654Srgrimes else 16648407Speter db_printf("\\%03o", (int)value); 1674Srgrimes } 1684Srgrimes break; 1694Srgrimes case 'i': /* instruction */ 1704Srgrimes addr = db_disasm(addr, FALSE); 1714Srgrimes break; 1724Srgrimes case 'I': /* instruction, alternate form */ 1734Srgrimes addr = db_disasm(addr, TRUE); 1744Srgrimes break; 1754Srgrimes default: 1764Srgrimes break; 1774Srgrimes } 1784Srgrimes if (db_print_position() != 0) 179163134Sbde db_end_line(1); 1804Srgrimes break; 1814Srgrimes } 1824Srgrimes } 1834Srgrimes } 1844Srgrimes db_next = addr; 1854Srgrimes} 1864Srgrimes 1874Srgrimes/* 1884Srgrimes * Print value. 1894Srgrimes */ 19012515Sphkstatic char db_print_format = 'x'; 1914Srgrimes 1924Srgrimes/*ARGSUSED*/ 1934Srgrimesvoid 1944Srgrimesdb_print_cmd(addr, have_addr, count, modif) 1954Srgrimes db_expr_t addr; 19612473Sbde boolean_t have_addr; 1974Srgrimes db_expr_t count; 1984Srgrimes char * modif; 1994Srgrimes{ 2004Srgrimes db_expr_t value; 2014Srgrimes 2024Srgrimes if (modif[0] != '\0') 2034Srgrimes db_print_format = modif[0]; 2044Srgrimes 2054Srgrimes switch (db_print_format) { 2064Srgrimes case 'a': 2074Srgrimes db_printsym((db_addr_t)addr, DB_STGY_ANY); 2084Srgrimes break; 2094Srgrimes case 'r': 21037506Sbde db_printf("%+11lr", (long)addr); 2114Srgrimes break; 2124Srgrimes case 'x': 21337495Sbde db_printf("%8lx", (unsigned long)addr); 2144Srgrimes break; 2154Srgrimes case 'z': 216105954Smux db_printf("%8ly", (long)addr); 2174Srgrimes break; 2184Srgrimes case 'd': 21937495Sbde db_printf("%11ld", (long)addr); 2204Srgrimes break; 2214Srgrimes case 'u': 22237495Sbde db_printf("%11lu", (unsigned long)addr); 2234Srgrimes break; 2244Srgrimes case 'o': 22537495Sbde db_printf("%16lo", (unsigned long)addr); 2264Srgrimes break; 2274Srgrimes case 'c': 2284Srgrimes value = addr & 0xFF; 2294Srgrimes if (value >= ' ' && value <= '~') 23048407Speter db_printf("%c", (int)value); 2314Srgrimes else 23248407Speter db_printf("\\%03o", (int)value); 2334Srgrimes break; 2344Srgrimes } 2354Srgrimes db_printf("\n"); 2364Srgrimes} 2374Srgrimes 238798Swollmanvoid 2394Srgrimesdb_print_loc_and_inst(loc) 2404Srgrimes db_addr_t loc; 2414Srgrimes{ 2424Srgrimes db_printsym(loc, DB_STGY_PROC); 2434Srgrimes db_printf(":\t"); 2444Srgrimes (void) db_disasm(loc, TRUE); 2454Srgrimes} 2464Srgrimes 2474Srgrimes/* 2484Srgrimes * Search for a value in memory. 2494Srgrimes * Syntax: search [/bhl] addr value [mask] [,count] 2504Srgrimes */ 2514Srgrimesvoid 25212473Sbdedb_search_cmd(dummy1, dummy2, dummy3, dummy4) 25312473Sbde db_expr_t dummy1; 25412473Sbde boolean_t dummy2; 25512473Sbde db_expr_t dummy3; 25612473Sbde char * dummy4; 2574Srgrimes{ 2584Srgrimes int t; 2594Srgrimes db_addr_t addr; 2604Srgrimes int size; 2614Srgrimes db_expr_t value; 2624Srgrimes db_expr_t mask; 26336849Sdfr db_expr_t count; 2644Srgrimes 2654Srgrimes t = db_read_token(); 2664Srgrimes if (t == tSLASH) { 2674Srgrimes t = db_read_token(); 2684Srgrimes if (t != tIDENT) { 2694Srgrimes bad_modifier: 2704Srgrimes db_printf("Bad modifier\n"); 2714Srgrimes db_flush_lex(); 2724Srgrimes return; 2734Srgrimes } 2744Srgrimes 2754Srgrimes if (!strcmp(db_tok_string, "b")) 2764Srgrimes size = 1; 2774Srgrimes else if (!strcmp(db_tok_string, "h")) 2784Srgrimes size = 2; 2794Srgrimes else if (!strcmp(db_tok_string, "l")) 2804Srgrimes size = 4; 2814Srgrimes else 2824Srgrimes goto bad_modifier; 2834Srgrimes } else { 2844Srgrimes db_unread_token(t); 2854Srgrimes size = 4; 2864Srgrimes } 2874Srgrimes 288798Swollman if (!db_expression((db_expr_t *)&addr)) { 2894Srgrimes db_printf("Address missing\n"); 2904Srgrimes db_flush_lex(); 2914Srgrimes return; 2924Srgrimes } 2934Srgrimes 2944Srgrimes if (!db_expression(&value)) { 2954Srgrimes db_printf("Value missing\n"); 2964Srgrimes db_flush_lex(); 2974Srgrimes return; 2984Srgrimes } 2994Srgrimes 3004Srgrimes if (!db_expression(&mask)) 301879Swollman mask = 0xffffffffUL; 3024Srgrimes 3034Srgrimes t = db_read_token(); 3044Srgrimes if (t == tCOMMA) { 3054Srgrimes if (!db_expression(&count)) { 3064Srgrimes db_printf("Count missing\n"); 3074Srgrimes db_flush_lex(); 3084Srgrimes return; 3094Srgrimes } 3104Srgrimes } else { 3114Srgrimes db_unread_token(t); 3124Srgrimes count = -1; /* effectively forever */ 3134Srgrimes } 3144Srgrimes db_skip_to_eol(); 3154Srgrimes 3164Srgrimes db_search(addr, size, value, mask, count); 3174Srgrimes} 3184Srgrimes 319798Swollmanstatic void 3204Srgrimesdb_search(addr, size, value, mask, count) 3214Srgrimes register 3224Srgrimes db_addr_t addr; 3234Srgrimes int size; 3244Srgrimes db_expr_t value; 3254Srgrimes db_expr_t mask; 3264Srgrimes unsigned int count; 3274Srgrimes{ 3284Srgrimes while (count-- != 0) { 3294Srgrimes db_prev = addr; 3304Srgrimes if ((db_get_value(addr, size, FALSE) & mask) == value) 3314Srgrimes break; 3324Srgrimes addr += size; 3334Srgrimes } 3344Srgrimes db_next = addr; 3354Srgrimes} 336