db_examine.c revision 22975
122514Sdarrenr/* 231183Speter * Mach Operating System 322514Sdarrenr * Copyright (c) 1991,1990 Carnegie Mellon University 431183Speter * All Rights Reserved. 531183Speter * 631183Speter * Permission to use, copy, modify and distribute this software and its 722514Sdarrenr * documentation is hereby granted, provided that both the copyright 831183Speter * notice and this permission notice appear in all copies of the 931183Speter * software, derivative works or modified versions, and any portions 1037074Speter * thereof, and that both notices appear in supporting documentation. 1122514Sdarrenr * 1222514Sdarrenr * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS 1322514Sdarrenr * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR 1422514Sdarrenr * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 1522514Sdarrenr * 1622514Sdarrenr * Carnegie Mellon requests users of this software to return to 1722514Sdarrenr * 1822514Sdarrenr * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 1931183Speter * School of Computer Science 2022514Sdarrenr * Carnegie Mellon University 2122514Sdarrenr * Pittsburgh PA 15213-3890 2222514Sdarrenr * 2322514Sdarrenr * any improvements or extensions that they make and grant Carnegie the 2422514Sdarrenr * rights to redistribute these changes. 2522514Sdarrenr * 2622514Sdarrenr * $Id$ 2722514Sdarrenr */ 2822514Sdarrenr 2931183Speter/* 3031183Speter * Author: David B. Golub, Carnegie Mellon University 3131183Speter * Date: 7/90 3231183Speter */ 3331183Speter#include <sys/param.h> 3431183Speter#include <sys/systm.h> 3526119Sdarrenr 3626119Sdarrenr#include <ddb/ddb.h> 3726119Sdarrenr 3822514Sdarrenr#include <ddb/db_lex.h> 3922514Sdarrenr#include <ddb/db_output.h> 4022514Sdarrenr#include <ddb/db_command.h> 4122514Sdarrenr#include <ddb/db_sym.h> 4222514Sdarrenr#include <ddb/db_access.h> 4322514Sdarrenr 4431183Speterstatic char db_examine_format[TOK_STRING_SIZE] = "x"; 4531183Speter 4631183Speterstatic void db_examine(db_addr_t, char *, int); 4722514Sdarrenrstatic void db_search(db_addr_t, int, db_expr_t, db_expr_t, u_int); 4822514Sdarrenr 4922514Sdarrenr/* 5022514Sdarrenr * Examine (print) data. 5131183Speter */ 5231183Speter/*ARGSUSED*/ 5331183Spetervoid 5431183Speterdb_examine_cmd(addr, have_addr, count, modif) 5531183Speter db_expr_t addr; 5631183Speter boolean_t have_addr; 5731183Speter db_expr_t count; 5831183Speter char * modif; 5931183Speter{ 6022514Sdarrenr if (modif[0] != '\0') 6122514Sdarrenr db_strcpy(db_examine_format, modif); 6222514Sdarrenr 6322514Sdarrenr if (count == -1) 6422514Sdarrenr count = 1; 6522514Sdarrenr 6631183Speter db_examine((db_addr_t) addr, db_examine_format, count); 6731183Speter} 6831183Speter 6931183Speterstatic void 7031183Speterdb_examine(addr, fmt, count) 7131183Speter register 7231183Speter db_addr_t addr; 7331183Speter char * fmt; /* format string */ 7431183Speter int count; /* repeat count */ 7524583Sdarrenr{ 7622514Sdarrenr int c; 7724583Sdarrenr db_expr_t value; 7822514Sdarrenr int size; 7922514Sdarrenr int width; 8022514Sdarrenr char * fp; 8122514Sdarrenr 8222514Sdarrenr while (--count >= 0) { 8322514Sdarrenr fp = fmt; 8422514Sdarrenr size = 4; 8522514Sdarrenr width = 16; 8622514Sdarrenr while ((c = *fp++) != 0) { 8722514Sdarrenr switch (c) { 8822514Sdarrenr case 'b': 8922514Sdarrenr size = 1; 9022514Sdarrenr width = 4; 9131183Speter break; 9222514Sdarrenr case 'h': 9322514Sdarrenr size = 2; 9422514Sdarrenr width = 8; 9522514Sdarrenr break; 9622514Sdarrenr case 'l': 9722514Sdarrenr size = 4; 9822514Sdarrenr width = 16; 9922514Sdarrenr break; 10022514Sdarrenr case 'a': /* address */ 10137074Speter /* always forces a new line */ 10237074Speter if (db_print_position() != 0) 10322514Sdarrenr db_printf("\n"); 10437074Speter db_prev = addr; 10537074Speter db_printsym(addr, DB_STGY_ANY); 10622514Sdarrenr db_printf(":\t"); 10722514Sdarrenr break; 10822514Sdarrenr default: 10922514Sdarrenr if (db_print_position() == 0) { 11022514Sdarrenr /* Print the address. */ 11122514Sdarrenr db_printsym(addr, DB_STGY_ANY); 11222514Sdarrenr db_printf(":\t"); 11322514Sdarrenr db_prev = addr; 11422514Sdarrenr } 11537074Speter 11622514Sdarrenr switch (c) { 11722514Sdarrenr case 'r': /* signed, current radix */ 11822514Sdarrenr value = db_get_value(addr, size, TRUE); 11922514Sdarrenr addr += size; 12022514Sdarrenr db_printf("%+-*n", width, value); 12122514Sdarrenr break; 12222514Sdarrenr case 'x': /* unsigned hex */ 12322514Sdarrenr value = db_get_value(addr, size, FALSE); 12422514Sdarrenr addr += size; 12522514Sdarrenr db_printf("%-*x", width, value); 12622514Sdarrenr break; 12722514Sdarrenr case 'z': /* signed hex */ 12822514Sdarrenr value = db_get_value(addr, size, TRUE); 12922514Sdarrenr addr += size; 13022514Sdarrenr db_printf("%+-*x", width, value); 13137074Speter break; 13222514Sdarrenr case 'd': /* signed decimal */ 13322514Sdarrenr value = db_get_value(addr, size, TRUE); 13422514Sdarrenr addr += size; 13522514Sdarrenr db_printf("%-*d", width, value); 13622514Sdarrenr break; 13722514Sdarrenr case 'u': /* unsigned decimal */ 13822514Sdarrenr value = db_get_value(addr, size, FALSE); 13922514Sdarrenr addr += size; 14022514Sdarrenr db_printf("%-*u", width, value); 14122514Sdarrenr break; 14222514Sdarrenr case 'o': /* unsigned octal */ 14322514Sdarrenr value = db_get_value(addr, size, FALSE); 14422514Sdarrenr addr += size; 14522514Sdarrenr db_printf("%-*o", width, value); 14622514Sdarrenr break; 14722514Sdarrenr case 'c': /* character */ 14822514Sdarrenr value = db_get_value(addr, 1, FALSE); 14922514Sdarrenr addr += 1; 15022514Sdarrenr if (value >= ' ' && value <= '~') 15122514Sdarrenr db_printf("%c", value); 15222514Sdarrenr else 15322514Sdarrenr db_printf("\\%03o", value); 15422514Sdarrenr break; 15522514Sdarrenr case 's': /* null-terminated string */ 15622514Sdarrenr for (;;) { 15722514Sdarrenr value = db_get_value(addr, 1, FALSE); 15822514Sdarrenr addr += 1; 15922514Sdarrenr if (value == 0) 16022514Sdarrenr break; 16122514Sdarrenr if (value >= ' ' && value <= '~') 16222514Sdarrenr db_printf("%c", value); 16322514Sdarrenr else 16422514Sdarrenr db_printf("\\%03o", value); 16522514Sdarrenr } 16622514Sdarrenr break; 16722514Sdarrenr case 'i': /* instruction */ 16822514Sdarrenr addr = db_disasm(addr, FALSE); 16922514Sdarrenr break; 17022514Sdarrenr case 'I': /* instruction, alternate form */ 17122514Sdarrenr addr = db_disasm(addr, TRUE); 17222514Sdarrenr break; 17322514Sdarrenr default: 17422514Sdarrenr break; 17522514Sdarrenr } 17622514Sdarrenr if (db_print_position() != 0) 17722514Sdarrenr db_end_line(); 17822514Sdarrenr break; 17922514Sdarrenr } 18022514Sdarrenr } 18122514Sdarrenr } 18237074Speter db_next = addr; 18322514Sdarrenr} 18422514Sdarrenr 18524583Sdarrenr/* 18624583Sdarrenr * Print value. 18722514Sdarrenr */ 18822514Sdarrenrstatic char db_print_format = 'x'; 18922514Sdarrenr 19022514Sdarrenr/*ARGSUSED*/ 19122514Sdarrenrvoid 19222514Sdarrenrdb_print_cmd(addr, have_addr, count, modif) 19322514Sdarrenr db_expr_t addr; 19422514Sdarrenr boolean_t have_addr; 19537074Speter db_expr_t count; 19622514Sdarrenr char * modif; 19724583Sdarrenr{ 19824583Sdarrenr db_expr_t value; 19922514Sdarrenr 20022514Sdarrenr if (modif[0] != '\0') 20122514Sdarrenr db_print_format = modif[0]; 20222514Sdarrenr 20322514Sdarrenr switch (db_print_format) { 20422514Sdarrenr case 'a': 20522514Sdarrenr db_printsym((db_addr_t)addr, DB_STGY_ANY); 20622514Sdarrenr break; 20722514Sdarrenr case 'r': 20822514Sdarrenr db_printf("%+11n", addr); 20922514Sdarrenr break; 21022514Sdarrenr case 'x': 21122514Sdarrenr db_printf("%8x", addr); 21222514Sdarrenr break; 21322514Sdarrenr case 'z': 21437074Speter db_printf("%+8x", addr); 21522514Sdarrenr break; 21624583Sdarrenr case 'd': 21724583Sdarrenr db_printf("%11d", addr); 21822514Sdarrenr break; 21922514Sdarrenr case 'u': 22022514Sdarrenr db_printf("%11u", addr); 22122514Sdarrenr break; 22222514Sdarrenr case 'o': 22337074Speter db_printf("%16o", addr); 22422514Sdarrenr break; 22522514Sdarrenr case 'c': 22622514Sdarrenr value = addr & 0xFF; 22722514Sdarrenr if (value >= ' ' && value <= '~') 22824583Sdarrenr db_printf("%c", value); 22924583Sdarrenr else 23022514Sdarrenr db_printf("\\%03o", value); 23122514Sdarrenr break; 23222514Sdarrenr } 23322514Sdarrenr db_printf("\n"); 23422514Sdarrenr} 23522514Sdarrenr 23622514Sdarrenrvoid 23722514Sdarrenrdb_print_loc_and_inst(loc) 23822514Sdarrenr db_addr_t loc; 23922514Sdarrenr{ 24022514Sdarrenr db_printsym(loc, DB_STGY_PROC); 24122514Sdarrenr db_printf(":\t"); 24222514Sdarrenr (void) db_disasm(loc, TRUE); 24322514Sdarrenr} 24422514Sdarrenr 24522514Sdarrenr/* 24622514Sdarrenr * Search for a value in memory. 24722514Sdarrenr * Syntax: search [/bhl] addr value [mask] [,count] 24822514Sdarrenr */ 24922514Sdarrenrvoid 25022514Sdarrenrdb_search_cmd(dummy1, dummy2, dummy3, dummy4) 25122514Sdarrenr db_expr_t dummy1; 25222514Sdarrenr boolean_t dummy2; 25322514Sdarrenr db_expr_t dummy3; 25422514Sdarrenr char * dummy4; 25522514Sdarrenr{ 25622514Sdarrenr int t; 25722514Sdarrenr db_addr_t addr; 25822514Sdarrenr int size; 25922514Sdarrenr db_expr_t value; 26022514Sdarrenr db_expr_t mask; 26122514Sdarrenr unsigned int count; 26222514Sdarrenr 26322514Sdarrenr t = db_read_token(); 26422514Sdarrenr if (t == tSLASH) { 26522514Sdarrenr t = db_read_token(); 26622514Sdarrenr if (t != tIDENT) { 26722514Sdarrenr bad_modifier: 26822514Sdarrenr db_printf("Bad modifier\n"); 26922514Sdarrenr db_flush_lex(); 27022514Sdarrenr return; 27122514Sdarrenr } 27222514Sdarrenr 27322514Sdarrenr if (!strcmp(db_tok_string, "b")) 27422514Sdarrenr size = 1; 27522514Sdarrenr else if (!strcmp(db_tok_string, "h")) 27622514Sdarrenr size = 2; 27722514Sdarrenr else if (!strcmp(db_tok_string, "l")) 27822514Sdarrenr size = 4; 27922514Sdarrenr else 28022514Sdarrenr goto bad_modifier; 28122514Sdarrenr } else { 28222514Sdarrenr db_unread_token(t); 28322514Sdarrenr size = 4; 28422514Sdarrenr } 28522514Sdarrenr 28637074Speter if (!db_expression((db_expr_t *)&addr)) { 28722514Sdarrenr db_printf("Address missing\n"); 28822514Sdarrenr db_flush_lex(); 28922514Sdarrenr return; 29022514Sdarrenr } 29122514Sdarrenr 29222514Sdarrenr if (!db_expression(&value)) { 29322514Sdarrenr db_printf("Value missing\n"); 29422514Sdarrenr db_flush_lex(); 29522514Sdarrenr return; 29622514Sdarrenr } 29737074Speter 29822514Sdarrenr if (!db_expression(&mask)) 29922514Sdarrenr mask = 0xffffffffUL; 30022514Sdarrenr 30122514Sdarrenr t = db_read_token(); 30222514Sdarrenr if (t == tCOMMA) { 30322514Sdarrenr if (!db_expression(&count)) { 30437074Speter db_printf("Count missing\n"); 30522514Sdarrenr db_flush_lex(); 30622514Sdarrenr return; 30722514Sdarrenr } 30822514Sdarrenr } else { 30922514Sdarrenr db_unread_token(t); 31022514Sdarrenr count = -1; /* effectively forever */ 31122514Sdarrenr } 31222514Sdarrenr db_skip_to_eol(); 31322514Sdarrenr 31422514Sdarrenr db_search(addr, size, value, mask, count); 31522514Sdarrenr} 31622514Sdarrenr 31737074Speterstatic void 31822514Sdarrenrdb_search(addr, size, value, mask, count) 31922514Sdarrenr register 32022514Sdarrenr db_addr_t addr; 32122514Sdarrenr int size; 32222514Sdarrenr db_expr_t value; 32322514Sdarrenr db_expr_t mask; 32422514Sdarrenr unsigned int count; 32522514Sdarrenr{ 32622514Sdarrenr while (count-- != 0) { 32722514Sdarrenr db_prev = addr; 32822514Sdarrenr if ((db_get_value(addr, size, FALSE) & mask) == value) 32922514Sdarrenr break; 33022514Sdarrenr addr += size; 33137074Speter } 33222514Sdarrenr db_next = addr; 33322514Sdarrenr} 33422514Sdarrenr