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$"); 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; 169176914Srwatson case 'S': /* symbol */ 170176914Srwatson value = db_get_value(addr, sizeof(void *), 171176914Srwatson FALSE); 172176914Srwatson addr += sizeof(void *); 173176914Srwatson db_printsym(value, DB_STGY_ANY); 174176914Srwatson break; 1754Srgrimes case 'i': /* instruction */ 1764Srgrimes addr = db_disasm(addr, FALSE); 1774Srgrimes break; 1784Srgrimes case 'I': /* instruction, alternate form */ 1794Srgrimes addr = db_disasm(addr, TRUE); 1804Srgrimes break; 1814Srgrimes default: 1824Srgrimes break; 1834Srgrimes } 1844Srgrimes if (db_print_position() != 0) 185163134Sbde db_end_line(1); 1864Srgrimes break; 1874Srgrimes } 1884Srgrimes } 1894Srgrimes } 1904Srgrimes db_next = addr; 1914Srgrimes} 1924Srgrimes 1934Srgrimes/* 1944Srgrimes * Print value. 1954Srgrimes */ 19612515Sphkstatic char db_print_format = 'x'; 1974Srgrimes 1984Srgrimes/*ARGSUSED*/ 1994Srgrimesvoid 2004Srgrimesdb_print_cmd(addr, have_addr, count, modif) 2014Srgrimes db_expr_t addr; 20212473Sbde boolean_t have_addr; 2034Srgrimes db_expr_t count; 2044Srgrimes char * modif; 2054Srgrimes{ 2064Srgrimes db_expr_t value; 2074Srgrimes 2084Srgrimes if (modif[0] != '\0') 2094Srgrimes db_print_format = modif[0]; 2104Srgrimes 2114Srgrimes switch (db_print_format) { 2124Srgrimes case 'a': 2134Srgrimes db_printsym((db_addr_t)addr, DB_STGY_ANY); 2144Srgrimes break; 2154Srgrimes case 'r': 21637506Sbde db_printf("%+11lr", (long)addr); 2174Srgrimes break; 2184Srgrimes case 'x': 21937495Sbde db_printf("%8lx", (unsigned long)addr); 2204Srgrimes break; 2214Srgrimes case 'z': 222105954Smux db_printf("%8ly", (long)addr); 2234Srgrimes break; 2244Srgrimes case 'd': 22537495Sbde db_printf("%11ld", (long)addr); 2264Srgrimes break; 2274Srgrimes case 'u': 22837495Sbde db_printf("%11lu", (unsigned long)addr); 2294Srgrimes break; 2304Srgrimes case 'o': 23137495Sbde db_printf("%16lo", (unsigned long)addr); 2324Srgrimes break; 2334Srgrimes case 'c': 2344Srgrimes value = addr & 0xFF; 2354Srgrimes if (value >= ' ' && value <= '~') 23648407Speter db_printf("%c", (int)value); 2374Srgrimes else 23848407Speter db_printf("\\%03o", (int)value); 2394Srgrimes break; 2404Srgrimes } 2414Srgrimes db_printf("\n"); 2424Srgrimes} 2434Srgrimes 244798Swollmanvoid 2454Srgrimesdb_print_loc_and_inst(loc) 2464Srgrimes db_addr_t loc; 2474Srgrimes{ 2484Srgrimes db_printsym(loc, DB_STGY_PROC); 2494Srgrimes db_printf(":\t"); 2504Srgrimes (void) db_disasm(loc, TRUE); 2514Srgrimes} 2524Srgrimes 2534Srgrimes/* 2544Srgrimes * Search for a value in memory. 2554Srgrimes * Syntax: search [/bhl] addr value [mask] [,count] 2564Srgrimes */ 2574Srgrimesvoid 25812473Sbdedb_search_cmd(dummy1, dummy2, dummy3, dummy4) 25912473Sbde db_expr_t dummy1; 26012473Sbde boolean_t dummy2; 26112473Sbde db_expr_t dummy3; 26212473Sbde char * dummy4; 2634Srgrimes{ 2644Srgrimes int t; 2654Srgrimes db_addr_t addr; 2664Srgrimes int size; 2674Srgrimes db_expr_t value; 2684Srgrimes db_expr_t mask; 26936849Sdfr db_expr_t count; 2704Srgrimes 2714Srgrimes t = db_read_token(); 2724Srgrimes if (t == tSLASH) { 2734Srgrimes t = db_read_token(); 2744Srgrimes if (t != tIDENT) { 2754Srgrimes bad_modifier: 2764Srgrimes db_printf("Bad modifier\n"); 2774Srgrimes db_flush_lex(); 2784Srgrimes return; 2794Srgrimes } 2804Srgrimes 2814Srgrimes if (!strcmp(db_tok_string, "b")) 2824Srgrimes size = 1; 2834Srgrimes else if (!strcmp(db_tok_string, "h")) 2844Srgrimes size = 2; 2854Srgrimes else if (!strcmp(db_tok_string, "l")) 2864Srgrimes size = 4; 2874Srgrimes else 2884Srgrimes goto bad_modifier; 2894Srgrimes } else { 2904Srgrimes db_unread_token(t); 2914Srgrimes size = 4; 2924Srgrimes } 2934Srgrimes 294798Swollman if (!db_expression((db_expr_t *)&addr)) { 2954Srgrimes db_printf("Address missing\n"); 2964Srgrimes db_flush_lex(); 2974Srgrimes return; 2984Srgrimes } 2994Srgrimes 3004Srgrimes if (!db_expression(&value)) { 3014Srgrimes db_printf("Value missing\n"); 3024Srgrimes db_flush_lex(); 3034Srgrimes return; 3044Srgrimes } 3054Srgrimes 3064Srgrimes if (!db_expression(&mask)) 307879Swollman mask = 0xffffffffUL; 3084Srgrimes 3094Srgrimes t = db_read_token(); 3104Srgrimes if (t == tCOMMA) { 3114Srgrimes if (!db_expression(&count)) { 3124Srgrimes db_printf("Count missing\n"); 3134Srgrimes db_flush_lex(); 3144Srgrimes return; 3154Srgrimes } 3164Srgrimes } else { 3174Srgrimes db_unread_token(t); 3184Srgrimes count = -1; /* effectively forever */ 3194Srgrimes } 3204Srgrimes db_skip_to_eol(); 3214Srgrimes 3224Srgrimes db_search(addr, size, value, mask, count); 3234Srgrimes} 3244Srgrimes 325798Swollmanstatic void 3264Srgrimesdb_search(addr, size, value, mask, count) 3274Srgrimes register 3284Srgrimes db_addr_t addr; 3294Srgrimes int size; 3304Srgrimes db_expr_t value; 3314Srgrimes db_expr_t mask; 3324Srgrimes unsigned int count; 3334Srgrimes{ 3344Srgrimes while (count-- != 0) { 3354Srgrimes db_prev = addr; 3364Srgrimes if ((db_get_value(addr, size, FALSE) & mask) == value) 3374Srgrimes break; 3384Srgrimes addr += size; 3394Srgrimes } 3404Srgrimes db_next = addr; 3414Srgrimes} 342