15b81b6b3SRodney W. Grimes /* 25b81b6b3SRodney W. Grimes * Mach Operating System 35b81b6b3SRodney W. Grimes * Copyright (c) 1991,1990 Carnegie Mellon University 45b81b6b3SRodney W. Grimes * All Rights Reserved. 55b81b6b3SRodney W. Grimes * 65b81b6b3SRodney W. Grimes * Permission to use, copy, modify and distribute this software and its 75b81b6b3SRodney W. Grimes * documentation is hereby granted, provided that both the copyright 85b81b6b3SRodney W. Grimes * notice and this permission notice appear in all copies of the 95b81b6b3SRodney W. Grimes * software, derivative works or modified versions, and any portions 105b81b6b3SRodney W. Grimes * thereof, and that both notices appear in supporting documentation. 115b81b6b3SRodney W. Grimes * 125b81b6b3SRodney W. Grimes * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS 135b81b6b3SRodney W. Grimes * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR 145b81b6b3SRodney W. Grimes * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 155b81b6b3SRodney W. Grimes * 165b81b6b3SRodney W. Grimes * Carnegie Mellon requests users of this software to return to 175b81b6b3SRodney W. Grimes * 185b81b6b3SRodney W. Grimes * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 195b81b6b3SRodney W. Grimes * School of Computer Science 205b81b6b3SRodney W. Grimes * Carnegie Mellon University 215b81b6b3SRodney W. Grimes * Pittsburgh PA 15213-3890 225b81b6b3SRodney W. Grimes * 235b81b6b3SRodney W. Grimes * any improvements or extensions that they make and grant Carnegie the 245b81b6b3SRodney W. Grimes * rights to redistribute these changes. 250edf66ecSRodney W. Grimes * 26f540b106SGarrett Wollman * $Id: db_examine.c,v 1.4 1993/12/19 00:49:43 wollman Exp $ 275b81b6b3SRodney W. Grimes */ 280edf66ecSRodney W. Grimes 295b81b6b3SRodney W. Grimes /* 305b81b6b3SRodney W. Grimes * Author: David B. Golub, Carnegie Mellon University 315b81b6b3SRodney W. Grimes * Date: 7/90 325b81b6b3SRodney W. Grimes */ 33f540b106SGarrett Wollman #include <sys/param.h> 34f540b106SGarrett Wollman #include <sys/systm.h> 35f540b106SGarrett Wollman #include <sys/proc.h> 36381fe1aaSGarrett Wollman 37f540b106SGarrett Wollman #include <ddb/ddb.h> 385b81b6b3SRodney W. Grimes 39f540b106SGarrett Wollman #include <ddb/db_lex.h> 40f540b106SGarrett Wollman #include <ddb/db_output.h> 41f540b106SGarrett Wollman #include <ddb/db_command.h> 42f540b106SGarrett Wollman #include <ddb/db_sym.h> 43f540b106SGarrett Wollman #include <ddb/db_access.h> 445b81b6b3SRodney W. Grimes 455b81b6b3SRodney W. Grimes char db_examine_format[TOK_STRING_SIZE] = "x"; 465b81b6b3SRodney W. Grimes 475b81b6b3SRodney W. Grimes extern db_addr_t db_disasm(/* db_addr_t, boolean_t */); 485b81b6b3SRodney W. Grimes /* instruction disassembler */ 495b81b6b3SRodney W. Grimes 50381fe1aaSGarrett Wollman static void db_examine(db_addr_t, char *, int); 51381fe1aaSGarrett Wollman static void db_search(db_addr_t, int, db_expr_t, db_expr_t, u_int); 52381fe1aaSGarrett Wollman 535b81b6b3SRodney W. Grimes /* 545b81b6b3SRodney W. Grimes * Examine (print) data. 555b81b6b3SRodney W. Grimes */ 565b81b6b3SRodney W. Grimes /*ARGSUSED*/ 575b81b6b3SRodney W. Grimes void 585b81b6b3SRodney W. Grimes db_examine_cmd(addr, have_addr, count, modif) 595b81b6b3SRodney W. Grimes db_expr_t addr; 605b81b6b3SRodney W. Grimes int have_addr; 615b81b6b3SRodney W. Grimes db_expr_t count; 625b81b6b3SRodney W. Grimes char * modif; 635b81b6b3SRodney W. Grimes { 645b81b6b3SRodney W. Grimes if (modif[0] != '\0') 655b81b6b3SRodney W. Grimes db_strcpy(db_examine_format, modif); 665b81b6b3SRodney W. Grimes 675b81b6b3SRodney W. Grimes if (count == -1) 685b81b6b3SRodney W. Grimes count = 1; 695b81b6b3SRodney W. Grimes 705b81b6b3SRodney W. Grimes db_examine((db_addr_t) addr, db_examine_format, count); 715b81b6b3SRodney W. Grimes } 725b81b6b3SRodney W. Grimes 73381fe1aaSGarrett Wollman static void 745b81b6b3SRodney W. Grimes db_examine(addr, fmt, count) 755b81b6b3SRodney W. Grimes register 765b81b6b3SRodney W. Grimes db_addr_t addr; 775b81b6b3SRodney W. Grimes char * fmt; /* format string */ 785b81b6b3SRodney W. Grimes int count; /* repeat count */ 795b81b6b3SRodney W. Grimes { 805b81b6b3SRodney W. Grimes int c; 815b81b6b3SRodney W. Grimes db_expr_t value; 825b81b6b3SRodney W. Grimes int size; 835b81b6b3SRodney W. Grimes int width; 845b81b6b3SRodney W. Grimes char * fp; 855b81b6b3SRodney W. Grimes 865b81b6b3SRodney W. Grimes while (--count >= 0) { 875b81b6b3SRodney W. Grimes fp = fmt; 885b81b6b3SRodney W. Grimes size = 4; 895b81b6b3SRodney W. Grimes width = 16; 905b81b6b3SRodney W. Grimes while ((c = *fp++) != 0) { 915b81b6b3SRodney W. Grimes switch (c) { 925b81b6b3SRodney W. Grimes case 'b': 935b81b6b3SRodney W. Grimes size = 1; 945b81b6b3SRodney W. Grimes width = 4; 955b81b6b3SRodney W. Grimes break; 965b81b6b3SRodney W. Grimes case 'h': 975b81b6b3SRodney W. Grimes size = 2; 985b81b6b3SRodney W. Grimes width = 8; 995b81b6b3SRodney W. Grimes break; 1005b81b6b3SRodney W. Grimes case 'l': 1015b81b6b3SRodney W. Grimes size = 4; 1025b81b6b3SRodney W. Grimes width = 16; 1035b81b6b3SRodney W. Grimes break; 1045b81b6b3SRodney W. Grimes case 'a': /* address */ 1055b81b6b3SRodney W. Grimes /* always forces a new line */ 1065b81b6b3SRodney W. Grimes if (db_print_position() != 0) 1075b81b6b3SRodney W. Grimes db_printf("\n"); 1085b81b6b3SRodney W. Grimes db_prev = addr; 1095b81b6b3SRodney W. Grimes db_printsym(addr, DB_STGY_ANY); 1105b81b6b3SRodney W. Grimes db_printf(":\t"); 1115b81b6b3SRodney W. Grimes break; 1125b81b6b3SRodney W. Grimes default: 1135b81b6b3SRodney W. Grimes if (db_print_position() == 0) { 1145b81b6b3SRodney W. Grimes /* If we hit a new symbol, print it */ 1155b81b6b3SRodney W. Grimes char * name; 1165b81b6b3SRodney W. Grimes db_expr_t off; 1175b81b6b3SRodney W. Grimes 1185b81b6b3SRodney W. Grimes db_find_sym_and_offset(addr, &name, &off); 1195b81b6b3SRodney W. Grimes if (off == 0) 1205b81b6b3SRodney W. Grimes db_printf("%s:\t", name); 1215b81b6b3SRodney W. Grimes else 1225b81b6b3SRodney W. Grimes db_printf("\t\t"); 1235b81b6b3SRodney W. Grimes 1245b81b6b3SRodney W. Grimes db_prev = addr; 1255b81b6b3SRodney W. Grimes } 1265b81b6b3SRodney W. Grimes 1275b81b6b3SRodney W. Grimes switch (c) { 1285b81b6b3SRodney W. Grimes case 'r': /* signed, current radix */ 1295b81b6b3SRodney W. Grimes value = db_get_value(addr, size, TRUE); 1305b81b6b3SRodney W. Grimes addr += size; 1315b81b6b3SRodney W. Grimes db_printf("%-*r", width, value); 1325b81b6b3SRodney W. Grimes break; 1335b81b6b3SRodney W. Grimes case 'x': /* unsigned hex */ 1345b81b6b3SRodney W. Grimes value = db_get_value(addr, size, FALSE); 1355b81b6b3SRodney W. Grimes addr += size; 1365b81b6b3SRodney W. Grimes db_printf("%-*x", width, value); 1375b81b6b3SRodney W. Grimes break; 1385b81b6b3SRodney W. Grimes case 'z': /* signed hex */ 1395b81b6b3SRodney W. Grimes value = db_get_value(addr, size, TRUE); 1405b81b6b3SRodney W. Grimes addr += size; 1415b81b6b3SRodney W. Grimes db_printf("%-*z", width, value); 1425b81b6b3SRodney W. Grimes break; 1435b81b6b3SRodney W. Grimes case 'd': /* signed decimal */ 1445b81b6b3SRodney W. Grimes value = db_get_value(addr, size, TRUE); 1455b81b6b3SRodney W. Grimes addr += size; 1465b81b6b3SRodney W. Grimes db_printf("%-*d", width, value); 1475b81b6b3SRodney W. Grimes break; 1485b81b6b3SRodney W. Grimes case 'u': /* unsigned decimal */ 1495b81b6b3SRodney W. Grimes value = db_get_value(addr, size, FALSE); 1505b81b6b3SRodney W. Grimes addr += size; 1515b81b6b3SRodney W. Grimes db_printf("%-*u", width, value); 1525b81b6b3SRodney W. Grimes break; 1535b81b6b3SRodney W. Grimes case 'o': /* unsigned octal */ 1545b81b6b3SRodney W. Grimes value = db_get_value(addr, size, FALSE); 1555b81b6b3SRodney W. Grimes addr += size; 1565b81b6b3SRodney W. Grimes db_printf("%-*o", width, value); 1575b81b6b3SRodney W. Grimes break; 1585b81b6b3SRodney W. Grimes case 'c': /* character */ 1595b81b6b3SRodney W. Grimes value = db_get_value(addr, 1, FALSE); 1605b81b6b3SRodney W. Grimes addr += 1; 1615b81b6b3SRodney W. Grimes if (value >= ' ' && value <= '~') 1625b81b6b3SRodney W. Grimes db_printf("%c", value); 1635b81b6b3SRodney W. Grimes else 1645b81b6b3SRodney W. Grimes db_printf("\\%03o", value); 1655b81b6b3SRodney W. Grimes break; 1665b81b6b3SRodney W. Grimes case 's': /* null-terminated string */ 1675b81b6b3SRodney W. Grimes for (;;) { 1685b81b6b3SRodney W. Grimes value = db_get_value(addr, 1, FALSE); 1695b81b6b3SRodney W. Grimes addr += 1; 1705b81b6b3SRodney W. Grimes if (value == 0) 1715b81b6b3SRodney W. Grimes break; 1725b81b6b3SRodney W. Grimes if (value >= ' ' && value <= '~') 1735b81b6b3SRodney W. Grimes db_printf("%c", value); 1745b81b6b3SRodney W. Grimes else 1755b81b6b3SRodney W. Grimes db_printf("\\%03o", value); 1765b81b6b3SRodney W. Grimes } 1775b81b6b3SRodney W. Grimes break; 1785b81b6b3SRodney W. Grimes case 'i': /* instruction */ 1795b81b6b3SRodney W. Grimes addr = db_disasm(addr, FALSE); 1805b81b6b3SRodney W. Grimes break; 1815b81b6b3SRodney W. Grimes case 'I': /* instruction, alternate form */ 1825b81b6b3SRodney W. Grimes addr = db_disasm(addr, TRUE); 1835b81b6b3SRodney W. Grimes break; 1845b81b6b3SRodney W. Grimes default: 1855b81b6b3SRodney W. Grimes break; 1865b81b6b3SRodney W. Grimes } 1875b81b6b3SRodney W. Grimes if (db_print_position() != 0) 1885b81b6b3SRodney W. Grimes db_end_line(); 1895b81b6b3SRodney W. Grimes break; 1905b81b6b3SRodney W. Grimes } 1915b81b6b3SRodney W. Grimes } 1925b81b6b3SRodney W. Grimes } 1935b81b6b3SRodney W. Grimes db_next = addr; 1945b81b6b3SRodney W. Grimes } 1955b81b6b3SRodney W. Grimes 1965b81b6b3SRodney W. Grimes /* 1975b81b6b3SRodney W. Grimes * Print value. 1985b81b6b3SRodney W. Grimes */ 1995b81b6b3SRodney W. Grimes char db_print_format = 'x'; 2005b81b6b3SRodney W. Grimes 2015b81b6b3SRodney W. Grimes /*ARGSUSED*/ 2025b81b6b3SRodney W. Grimes void 2035b81b6b3SRodney W. Grimes db_print_cmd(addr, have_addr, count, modif) 2045b81b6b3SRodney W. Grimes db_expr_t addr; 2055b81b6b3SRodney W. Grimes int have_addr; 2065b81b6b3SRodney W. Grimes db_expr_t count; 2075b81b6b3SRodney W. Grimes char * modif; 2085b81b6b3SRodney W. Grimes { 2095b81b6b3SRodney W. Grimes db_expr_t value; 2105b81b6b3SRodney W. Grimes 2115b81b6b3SRodney W. Grimes if (modif[0] != '\0') 2125b81b6b3SRodney W. Grimes db_print_format = modif[0]; 2135b81b6b3SRodney W. Grimes 2145b81b6b3SRodney W. Grimes switch (db_print_format) { 2155b81b6b3SRodney W. Grimes case 'a': 2165b81b6b3SRodney W. Grimes db_printsym((db_addr_t)addr, DB_STGY_ANY); 2175b81b6b3SRodney W. Grimes break; 2185b81b6b3SRodney W. Grimes case 'r': 2195b81b6b3SRodney W. Grimes db_printf("%11r", addr); 2205b81b6b3SRodney W. Grimes break; 2215b81b6b3SRodney W. Grimes case 'x': 2225b81b6b3SRodney W. Grimes db_printf("%8x", addr); 2235b81b6b3SRodney W. Grimes break; 2245b81b6b3SRodney W. Grimes case 'z': 2255b81b6b3SRodney W. Grimes db_printf("%8z", addr); 2265b81b6b3SRodney W. Grimes break; 2275b81b6b3SRodney W. Grimes case 'd': 2285b81b6b3SRodney W. Grimes db_printf("%11d", addr); 2295b81b6b3SRodney W. Grimes break; 2305b81b6b3SRodney W. Grimes case 'u': 2315b81b6b3SRodney W. Grimes db_printf("%11u", addr); 2325b81b6b3SRodney W. Grimes break; 2335b81b6b3SRodney W. Grimes case 'o': 2345b81b6b3SRodney W. Grimes db_printf("%16o", addr); 2355b81b6b3SRodney W. Grimes break; 2365b81b6b3SRodney W. Grimes case 'c': 2375b81b6b3SRodney W. Grimes value = addr & 0xFF; 2385b81b6b3SRodney W. Grimes if (value >= ' ' && value <= '~') 2395b81b6b3SRodney W. Grimes db_printf("%c", value); 2405b81b6b3SRodney W. Grimes else 2415b81b6b3SRodney W. Grimes db_printf("\\%03o", value); 2425b81b6b3SRodney W. Grimes break; 2435b81b6b3SRodney W. Grimes } 2445b81b6b3SRodney W. Grimes db_printf("\n"); 2455b81b6b3SRodney W. Grimes } 2465b81b6b3SRodney W. Grimes 247381fe1aaSGarrett Wollman void 2485b81b6b3SRodney W. Grimes db_print_loc_and_inst(loc) 2495b81b6b3SRodney W. Grimes db_addr_t loc; 2505b81b6b3SRodney W. Grimes { 2515b81b6b3SRodney W. Grimes db_printsym(loc, DB_STGY_PROC); 2525b81b6b3SRodney W. Grimes db_printf(":\t"); 2535b81b6b3SRodney W. Grimes (void) db_disasm(loc, TRUE); 2545b81b6b3SRodney W. Grimes } 2555b81b6b3SRodney W. Grimes 2565b81b6b3SRodney W. Grimes /* 2575b81b6b3SRodney W. Grimes * Search for a value in memory. 2585b81b6b3SRodney W. Grimes * Syntax: search [/bhl] addr value [mask] [,count] 2595b81b6b3SRodney W. Grimes */ 2605b81b6b3SRodney W. Grimes void 261381fe1aaSGarrett Wollman db_search_cmd(db_expr_t dummy1, int dummy2, db_expr_t dummy3, char *dummy4) 2625b81b6b3SRodney W. Grimes { 2635b81b6b3SRodney W. Grimes int t; 2645b81b6b3SRodney W. Grimes db_addr_t addr; 2655b81b6b3SRodney W. Grimes int size; 2665b81b6b3SRodney W. Grimes db_expr_t value; 2675b81b6b3SRodney W. Grimes db_expr_t mask; 2685b81b6b3SRodney W. Grimes unsigned int count; 2695b81b6b3SRodney W. Grimes 2705b81b6b3SRodney W. Grimes t = db_read_token(); 2715b81b6b3SRodney W. Grimes if (t == tSLASH) { 2725b81b6b3SRodney W. Grimes t = db_read_token(); 2735b81b6b3SRodney W. Grimes if (t != tIDENT) { 2745b81b6b3SRodney W. Grimes bad_modifier: 2755b81b6b3SRodney W. Grimes db_printf("Bad modifier\n"); 2765b81b6b3SRodney W. Grimes db_flush_lex(); 2775b81b6b3SRodney W. Grimes return; 2785b81b6b3SRodney W. Grimes } 2795b81b6b3SRodney W. Grimes 2805b81b6b3SRodney W. Grimes if (!strcmp(db_tok_string, "b")) 2815b81b6b3SRodney W. Grimes size = 1; 2825b81b6b3SRodney W. Grimes else if (!strcmp(db_tok_string, "h")) 2835b81b6b3SRodney W. Grimes size = 2; 2845b81b6b3SRodney W. Grimes else if (!strcmp(db_tok_string, "l")) 2855b81b6b3SRodney W. Grimes size = 4; 2865b81b6b3SRodney W. Grimes else 2875b81b6b3SRodney W. Grimes goto bad_modifier; 2885b81b6b3SRodney W. Grimes } else { 2895b81b6b3SRodney W. Grimes db_unread_token(t); 2905b81b6b3SRodney W. Grimes size = 4; 2915b81b6b3SRodney W. Grimes } 2925b81b6b3SRodney W. Grimes 293381fe1aaSGarrett Wollman if (!db_expression((db_expr_t *)&addr)) { 2945b81b6b3SRodney W. Grimes db_printf("Address missing\n"); 2955b81b6b3SRodney W. Grimes db_flush_lex(); 2965b81b6b3SRodney W. Grimes return; 2975b81b6b3SRodney W. Grimes } 2985b81b6b3SRodney W. Grimes 2995b81b6b3SRodney W. Grimes if (!db_expression(&value)) { 3005b81b6b3SRodney W. Grimes db_printf("Value missing\n"); 3015b81b6b3SRodney W. Grimes db_flush_lex(); 3025b81b6b3SRodney W. Grimes return; 3035b81b6b3SRodney W. Grimes } 3045b81b6b3SRodney W. Grimes 3055b81b6b3SRodney W. Grimes if (!db_expression(&mask)) 306aaf08d94SGarrett Wollman mask = 0xffffffffUL; 3075b81b6b3SRodney W. Grimes 3085b81b6b3SRodney W. Grimes t = db_read_token(); 3095b81b6b3SRodney W. Grimes if (t == tCOMMA) { 3105b81b6b3SRodney W. Grimes if (!db_expression(&count)) { 3115b81b6b3SRodney W. Grimes db_printf("Count missing\n"); 3125b81b6b3SRodney W. Grimes db_flush_lex(); 3135b81b6b3SRodney W. Grimes return; 3145b81b6b3SRodney W. Grimes } 3155b81b6b3SRodney W. Grimes } else { 3165b81b6b3SRodney W. Grimes db_unread_token(t); 3175b81b6b3SRodney W. Grimes count = -1; /* effectively forever */ 3185b81b6b3SRodney W. Grimes } 3195b81b6b3SRodney W. Grimes db_skip_to_eol(); 3205b81b6b3SRodney W. Grimes 3215b81b6b3SRodney W. Grimes db_search(addr, size, value, mask, count); 3225b81b6b3SRodney W. Grimes } 3235b81b6b3SRodney W. Grimes 324381fe1aaSGarrett Wollman static void 3255b81b6b3SRodney W. Grimes db_search(addr, size, value, mask, count) 3265b81b6b3SRodney W. Grimes register 3275b81b6b3SRodney W. Grimes db_addr_t addr; 3285b81b6b3SRodney W. Grimes int size; 3295b81b6b3SRodney W. Grimes db_expr_t value; 3305b81b6b3SRodney W. Grimes db_expr_t mask; 3315b81b6b3SRodney W. Grimes unsigned int count; 3325b81b6b3SRodney W. Grimes { 3335b81b6b3SRodney W. Grimes while (count-- != 0) { 3345b81b6b3SRodney W. Grimes db_prev = addr; 3355b81b6b3SRodney W. Grimes if ((db_get_value(addr, size, FALSE) & mask) == value) 3365b81b6b3SRodney W. Grimes break; 3375b81b6b3SRodney W. Grimes addr += size; 3385b81b6b3SRodney W. Grimes } 3395b81b6b3SRodney W. Grimes db_next = addr; 3405b81b6b3SRodney W. Grimes } 341