db_examine.c revision 47098
18876Srgrimes/* 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 * 2647098Sbde * $Id: db_examine.c,v 1.24 1998/07/08 10:53:47 bde Exp $ 274Srgrimes */ 28623Srgrimes 294Srgrimes/* 304Srgrimes * Author: David B. Golub, Carnegie Mellon University 314Srgrimes * Date: 7/90 324Srgrimes */ 3347098Sbde 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 4724490Sbdestatic void db_examine __P((db_addr_t, char *, int)); 4824490Sbdestatic void db_search __P((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 834Srgrimes while (--count >= 0) { 844Srgrimes fp = fmt; 854Srgrimes size = 4; 864Srgrimes width = 16; 874Srgrimes while ((c = *fp++) != 0) { 884Srgrimes switch (c) { 894Srgrimes case 'b': 904Srgrimes size = 1; 914Srgrimes width = 4; 924Srgrimes break; 934Srgrimes case 'h': 944Srgrimes size = 2; 954Srgrimes width = 8; 964Srgrimes break; 974Srgrimes case 'l': 984Srgrimes size = 4; 994Srgrimes width = 16; 1004Srgrimes break; 10137390Sdfr case 'g': 10237390Sdfr size = 8; 10337390Sdfr width = 32; 10437390Sdfr break; 1054Srgrimes case 'a': /* address */ 1064Srgrimes /* always forces a new line */ 1074Srgrimes if (db_print_position() != 0) 1084Srgrimes db_printf("\n"); 1094Srgrimes db_prev = addr; 1104Srgrimes db_printsym(addr, DB_STGY_ANY); 1114Srgrimes db_printf(":\t"); 1124Srgrimes break; 1134Srgrimes default: 1144Srgrimes if (db_print_position() == 0) { 1158698Sdg /* Print the address. */ 1168698Sdg db_printsym(addr, DB_STGY_ANY); 1178698Sdg db_printf(":\t"); 1184Srgrimes db_prev = addr; 1194Srgrimes } 1204Srgrimes 1214Srgrimes switch (c) { 1224Srgrimes case 'r': /* signed, current radix */ 1234Srgrimes value = db_get_value(addr, size, TRUE); 1244Srgrimes addr += size; 12537506Sbde db_printf("%+-*r", width, value); 1264Srgrimes break; 1274Srgrimes case 'x': /* unsigned hex */ 1284Srgrimes value = db_get_value(addr, size, FALSE); 1294Srgrimes addr += size; 1304Srgrimes db_printf("%-*x", width, value); 1314Srgrimes break; 1324Srgrimes case 'z': /* signed hex */ 1334Srgrimes value = db_get_value(addr, size, TRUE); 1344Srgrimes addr += size; 13537506Sbde db_printf("%-*z", width, value); 1364Srgrimes break; 1374Srgrimes case 'd': /* signed decimal */ 1384Srgrimes value = db_get_value(addr, size, TRUE); 1394Srgrimes addr += size; 1404Srgrimes db_printf("%-*d", width, value); 1414Srgrimes break; 1424Srgrimes case 'u': /* unsigned decimal */ 1434Srgrimes value = db_get_value(addr, size, FALSE); 1444Srgrimes addr += size; 1454Srgrimes db_printf("%-*u", width, value); 1464Srgrimes break; 1474Srgrimes case 'o': /* unsigned octal */ 1484Srgrimes value = db_get_value(addr, size, FALSE); 1494Srgrimes addr += size; 1504Srgrimes db_printf("%-*o", width, value); 1514Srgrimes break; 1524Srgrimes case 'c': /* character */ 1534Srgrimes value = db_get_value(addr, 1, FALSE); 1544Srgrimes addr += 1; 1554Srgrimes if (value >= ' ' && value <= '~') 1564Srgrimes db_printf("%c", value); 1574Srgrimes else 1584Srgrimes db_printf("\\%03o", value); 1594Srgrimes break; 1604Srgrimes case 's': /* null-terminated string */ 1614Srgrimes for (;;) { 1624Srgrimes value = db_get_value(addr, 1, FALSE); 1634Srgrimes addr += 1; 1644Srgrimes if (value == 0) 1654Srgrimes break; 1664Srgrimes if (value >= ' ' && value <= '~') 1674Srgrimes db_printf("%c", value); 1684Srgrimes else 1694Srgrimes db_printf("\\%03o", value); 1704Srgrimes } 1714Srgrimes break; 1724Srgrimes case 'i': /* instruction */ 1734Srgrimes addr = db_disasm(addr, FALSE); 1744Srgrimes break; 1754Srgrimes case 'I': /* instruction, alternate form */ 1764Srgrimes addr = db_disasm(addr, TRUE); 1774Srgrimes break; 1784Srgrimes default: 1794Srgrimes break; 1804Srgrimes } 1814Srgrimes if (db_print_position() != 0) 1824Srgrimes db_end_line(); 1834Srgrimes break; 1844Srgrimes } 1854Srgrimes } 1864Srgrimes } 1874Srgrimes db_next = addr; 1884Srgrimes} 1894Srgrimes 1904Srgrimes/* 1914Srgrimes * Print value. 1924Srgrimes */ 19312515Sphkstatic char db_print_format = 'x'; 1944Srgrimes 1954Srgrimes/*ARGSUSED*/ 1964Srgrimesvoid 1974Srgrimesdb_print_cmd(addr, have_addr, count, modif) 1984Srgrimes db_expr_t addr; 19912473Sbde boolean_t have_addr; 2004Srgrimes db_expr_t count; 2014Srgrimes char * modif; 2024Srgrimes{ 2034Srgrimes db_expr_t value; 2044Srgrimes 2054Srgrimes if (modif[0] != '\0') 2064Srgrimes db_print_format = modif[0]; 2074Srgrimes 2084Srgrimes switch (db_print_format) { 2094Srgrimes case 'a': 2104Srgrimes db_printsym((db_addr_t)addr, DB_STGY_ANY); 2114Srgrimes break; 2124Srgrimes case 'r': 21337506Sbde db_printf("%+11lr", (long)addr); 2144Srgrimes break; 2154Srgrimes case 'x': 21637495Sbde db_printf("%8lx", (unsigned long)addr); 2174Srgrimes break; 2184Srgrimes case 'z': 21937506Sbde db_printf("%8lz", (long)addr); 2204Srgrimes break; 2214Srgrimes case 'd': 22237495Sbde db_printf("%11ld", (long)addr); 2234Srgrimes break; 2244Srgrimes case 'u': 22537495Sbde db_printf("%11lu", (unsigned long)addr); 2264Srgrimes break; 2274Srgrimes case 'o': 22837495Sbde db_printf("%16lo", (unsigned long)addr); 2294Srgrimes break; 2304Srgrimes case 'c': 2314Srgrimes value = addr & 0xFF; 2324Srgrimes if (value >= ' ' && value <= '~') 2334Srgrimes db_printf("%c", value); 2344Srgrimes else 2354Srgrimes db_printf("\\%03o", value); 2364Srgrimes break; 2374Srgrimes } 2384Srgrimes db_printf("\n"); 2394Srgrimes} 2404Srgrimes 241798Swollmanvoid 2424Srgrimesdb_print_loc_and_inst(loc) 2434Srgrimes db_addr_t loc; 2444Srgrimes{ 2454Srgrimes db_printsym(loc, DB_STGY_PROC); 2464Srgrimes db_printf(":\t"); 2474Srgrimes (void) db_disasm(loc, TRUE); 2484Srgrimes} 2494Srgrimes 2504Srgrimes/* 2514Srgrimes * Search for a value in memory. 2524Srgrimes * Syntax: search [/bhl] addr value [mask] [,count] 2534Srgrimes */ 2544Srgrimesvoid 25512473Sbdedb_search_cmd(dummy1, dummy2, dummy3, dummy4) 25612473Sbde db_expr_t dummy1; 25712473Sbde boolean_t dummy2; 25812473Sbde db_expr_t dummy3; 25912473Sbde char * dummy4; 2604Srgrimes{ 2614Srgrimes int t; 2624Srgrimes db_addr_t addr; 2634Srgrimes int size; 2644Srgrimes db_expr_t value; 2654Srgrimes db_expr_t mask; 26636849Sdfr db_expr_t count; 2674Srgrimes 2684Srgrimes t = db_read_token(); 2694Srgrimes if (t == tSLASH) { 2704Srgrimes t = db_read_token(); 2714Srgrimes if (t != tIDENT) { 2724Srgrimes bad_modifier: 2734Srgrimes db_printf("Bad modifier\n"); 2744Srgrimes db_flush_lex(); 2754Srgrimes return; 2764Srgrimes } 2774Srgrimes 2784Srgrimes if (!strcmp(db_tok_string, "b")) 2794Srgrimes size = 1; 2804Srgrimes else if (!strcmp(db_tok_string, "h")) 2814Srgrimes size = 2; 2824Srgrimes else if (!strcmp(db_tok_string, "l")) 2834Srgrimes size = 4; 2844Srgrimes else 2854Srgrimes goto bad_modifier; 2864Srgrimes } else { 2874Srgrimes db_unread_token(t); 2884Srgrimes size = 4; 2894Srgrimes } 2904Srgrimes 291798Swollman if (!db_expression((db_expr_t *)&addr)) { 2924Srgrimes db_printf("Address missing\n"); 2934Srgrimes db_flush_lex(); 2944Srgrimes return; 2954Srgrimes } 2964Srgrimes 2974Srgrimes if (!db_expression(&value)) { 2984Srgrimes db_printf("Value missing\n"); 2994Srgrimes db_flush_lex(); 3004Srgrimes return; 3014Srgrimes } 3024Srgrimes 3034Srgrimes if (!db_expression(&mask)) 304879Swollman mask = 0xffffffffUL; 3054Srgrimes 3064Srgrimes t = db_read_token(); 3074Srgrimes if (t == tCOMMA) { 3084Srgrimes if (!db_expression(&count)) { 3094Srgrimes db_printf("Count missing\n"); 3104Srgrimes db_flush_lex(); 3114Srgrimes return; 3124Srgrimes } 3134Srgrimes } else { 3144Srgrimes db_unread_token(t); 3154Srgrimes count = -1; /* effectively forever */ 3164Srgrimes } 3174Srgrimes db_skip_to_eol(); 3184Srgrimes 3194Srgrimes db_search(addr, size, value, mask, count); 3204Srgrimes} 3214Srgrimes 322798Swollmanstatic void 3234Srgrimesdb_search(addr, size, value, mask, count) 3244Srgrimes register 3254Srgrimes db_addr_t addr; 3264Srgrimes int size; 3274Srgrimes db_expr_t value; 3284Srgrimes db_expr_t mask; 3294Srgrimes unsigned int count; 3304Srgrimes{ 3314Srgrimes while (count-- != 0) { 3324Srgrimes db_prev = addr; 3334Srgrimes if ((db_get_value(addr, size, FALSE) & mask) == value) 3344Srgrimes break; 3354Srgrimes addr += size; 3364Srgrimes } 3374Srgrimes db_next = addr; 3384Srgrimes} 339