|
|
1.1 ! root 1: /* ! 2: * Mach Operating System ! 3: * Copyright (c) 1991,1990 Carnegie Mellon University ! 4: * All Rights Reserved. ! 5: * ! 6: * Permission to use, copy, modify and distribute this software and its ! 7: * documentation is hereby granted, provided that both the copyright ! 8: * notice and this permission notice appear in all copies of the ! 9: * software, derivative works or modified versions, and any portions ! 10: * thereof, and that both notices appear in supporting documentation. ! 11: * ! 12: * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS ! 13: * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR ! 14: * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. ! 15: * ! 16: * Carnegie Mellon requests users of this software to return to ! 17: * ! 18: * Software Distribution Coordinator or [email protected] ! 19: * School of Computer Science ! 20: * Carnegie Mellon University ! 21: * Pittsburgh PA 15213-3890 ! 22: * ! 23: * any improvements or extensions that they make and grant Carnegie the ! 24: * rights to redistribute these changes. ! 25: */ ! 26: /* ! 27: * HISTORY ! 28: * $Log: db_examine.c,v $ ! 29: * Revision 1.1 1992/03/25 21:45:07 pace ! 30: * Initial revision ! 31: * ! 32: * Revision 2.4 91/02/05 17:06:20 mrt ! 33: * Changed to new Mach copyright ! 34: * [91/01/31 16:17:37 mrt] ! 35: * ! 36: * Revision 2.3 90/11/07 16:49:23 rpd ! 37: * Added db_search_cmd, db_search. ! 38: * [90/11/06 rpd] ! 39: * ! 40: * Revision 2.2 90/08/27 21:50:38 dbg ! 41: * Add 'r', 'z' to print and examine formats. ! 42: * Change calling sequence of db_disasm. ! 43: * db_examine sets db_prev and db_next instead of explicitly ! 44: * advancing dot. ! 45: * [90/08/20 dbg] ! 46: * Reflected changes in db_printsym()'s calling seq. ! 47: * [90/08/20 af] ! 48: * Reduce lint. ! 49: * [90/08/07 dbg] ! 50: * Created. ! 51: * [90/07/25 dbg] ! 52: * ! 53: */ ! 54: /* ! 55: * Author: David B. Golub, Carnegie Mellon University ! 56: * Date: 7/90 ! 57: */ ! 58: #include "param.h" ! 59: #include "proc.h" ! 60: #include <machine/db_machdep.h> /* type definitions */ ! 61: ! 62: #include <ddb/db_lex.h> ! 63: #include <ddb/db_output.h> ! 64: #include <ddb/db_command.h> ! 65: #include <ddb/db_sym.h> ! 66: ! 67: char db_examine_format[TOK_STRING_SIZE] = "x"; ! 68: ! 69: extern db_addr_t db_disasm(/* db_addr_t, boolean_t */); ! 70: /* instruction disassembler */ ! 71: ! 72: /* ! 73: * Examine (print) data. ! 74: */ ! 75: /*ARGSUSED*/ ! 76: void ! 77: db_examine_cmd(addr, have_addr, count, modif) ! 78: db_expr_t addr; ! 79: int have_addr; ! 80: db_expr_t count; ! 81: char * modif; ! 82: { ! 83: if (modif[0] != '\0') ! 84: db_strcpy(db_examine_format, modif); ! 85: ! 86: if (count == -1) ! 87: count = 1; ! 88: ! 89: db_examine((db_addr_t) addr, db_examine_format, count); ! 90: } ! 91: ! 92: db_examine(addr, fmt, count) ! 93: register ! 94: db_addr_t addr; ! 95: char * fmt; /* format string */ ! 96: int count; /* repeat count */ ! 97: { ! 98: int c; ! 99: db_expr_t value; ! 100: int size; ! 101: int width; ! 102: char * fp; ! 103: ! 104: while (--count >= 0) { ! 105: fp = fmt; ! 106: size = 4; ! 107: width = 16; ! 108: while ((c = *fp++) != 0) { ! 109: switch (c) { ! 110: case 'b': ! 111: size = 1; ! 112: width = 4; ! 113: break; ! 114: case 'h': ! 115: size = 2; ! 116: width = 8; ! 117: break; ! 118: case 'l': ! 119: size = 4; ! 120: width = 16; ! 121: break; ! 122: case 'a': /* address */ ! 123: /* always forces a new line */ ! 124: if (db_print_position() != 0) ! 125: db_printf("\n"); ! 126: db_prev = addr; ! 127: db_printsym(addr, DB_STGY_ANY); ! 128: db_printf(":\t"); ! 129: break; ! 130: default: ! 131: if (db_print_position() == 0) { ! 132: /* If we hit a new symbol, print it */ ! 133: char * name; ! 134: db_expr_t off; ! 135: ! 136: db_find_sym_and_offset(addr, &name, &off); ! 137: if (off == 0) ! 138: db_printf("%s:\t", name); ! 139: else ! 140: db_printf("\t\t"); ! 141: ! 142: db_prev = addr; ! 143: } ! 144: ! 145: switch (c) { ! 146: case 'r': /* signed, current radix */ ! 147: value = db_get_value(addr, size, TRUE); ! 148: addr += size; ! 149: db_printf("%-*r", width, value); ! 150: break; ! 151: case 'x': /* unsigned hex */ ! 152: value = db_get_value(addr, size, FALSE); ! 153: addr += size; ! 154: db_printf("%-*x", width, value); ! 155: break; ! 156: case 'z': /* signed hex */ ! 157: value = db_get_value(addr, size, TRUE); ! 158: addr += size; ! 159: db_printf("%-*z", width, value); ! 160: break; ! 161: case 'd': /* signed decimal */ ! 162: value = db_get_value(addr, size, TRUE); ! 163: addr += size; ! 164: db_printf("%-*d", width, value); ! 165: break; ! 166: case 'u': /* unsigned decimal */ ! 167: value = db_get_value(addr, size, FALSE); ! 168: addr += size; ! 169: db_printf("%-*u", width, value); ! 170: break; ! 171: case 'o': /* unsigned octal */ ! 172: value = db_get_value(addr, size, FALSE); ! 173: addr += size; ! 174: db_printf("%-*o", width, value); ! 175: break; ! 176: case 'c': /* character */ ! 177: value = db_get_value(addr, 1, FALSE); ! 178: addr += 1; ! 179: if (value >= ' ' && value <= '~') ! 180: db_printf("%c", value); ! 181: else ! 182: db_printf("\\%03o", value); ! 183: break; ! 184: case 's': /* null-terminated string */ ! 185: for (;;) { ! 186: value = db_get_value(addr, 1, FALSE); ! 187: addr += 1; ! 188: if (value == 0) ! 189: break; ! 190: if (value >= ' ' && value <= '~') ! 191: db_printf("%c", value); ! 192: else ! 193: db_printf("\\%03o", value); ! 194: } ! 195: break; ! 196: case 'i': /* instruction */ ! 197: addr = db_disasm(addr, FALSE); ! 198: break; ! 199: case 'I': /* instruction, alternate form */ ! 200: addr = db_disasm(addr, TRUE); ! 201: break; ! 202: default: ! 203: break; ! 204: } ! 205: if (db_print_position() != 0) ! 206: db_end_line(); ! 207: break; ! 208: } ! 209: } ! 210: } ! 211: db_next = addr; ! 212: } ! 213: ! 214: /* ! 215: * Print value. ! 216: */ ! 217: char db_print_format = 'x'; ! 218: ! 219: /*ARGSUSED*/ ! 220: void ! 221: db_print_cmd(addr, have_addr, count, modif) ! 222: db_expr_t addr; ! 223: int have_addr; ! 224: db_expr_t count; ! 225: char * modif; ! 226: { ! 227: db_expr_t value; ! 228: ! 229: if (modif[0] != '\0') ! 230: db_print_format = modif[0]; ! 231: ! 232: switch (db_print_format) { ! 233: case 'a': ! 234: db_printsym((db_addr_t)addr, DB_STGY_ANY); ! 235: break; ! 236: case 'r': ! 237: db_printf("%11r", addr); ! 238: break; ! 239: case 'x': ! 240: db_printf("%8x", addr); ! 241: break; ! 242: case 'z': ! 243: db_printf("%8z", addr); ! 244: break; ! 245: case 'd': ! 246: db_printf("%11d", addr); ! 247: break; ! 248: case 'u': ! 249: db_printf("%11u", addr); ! 250: break; ! 251: case 'o': ! 252: db_printf("%16o", addr); ! 253: break; ! 254: case 'c': ! 255: value = addr & 0xFF; ! 256: if (value >= ' ' && value <= '~') ! 257: db_printf("%c", value); ! 258: else ! 259: db_printf("\\%03o", value); ! 260: break; ! 261: } ! 262: db_printf("\n"); ! 263: } ! 264: ! 265: db_print_loc_and_inst(loc) ! 266: db_addr_t loc; ! 267: { ! 268: db_printsym(loc, DB_STGY_PROC); ! 269: db_printf(":\t"); ! 270: (void) db_disasm(loc, TRUE); ! 271: } ! 272: ! 273: db_strcpy(dst, src) ! 274: register char *dst; ! 275: register char *src; ! 276: { ! 277: while (*dst++ = *src++) ! 278: ; ! 279: } ! 280: ! 281: /* ! 282: * Search for a value in memory. ! 283: * Syntax: search [/bhl] addr value [mask] [,count] ! 284: */ ! 285: void ! 286: db_search_cmd() ! 287: { ! 288: int t; ! 289: db_addr_t addr; ! 290: int size; ! 291: db_expr_t value; ! 292: db_expr_t mask; ! 293: unsigned int count; ! 294: ! 295: t = db_read_token(); ! 296: if (t == tSLASH) { ! 297: t = db_read_token(); ! 298: if (t != tIDENT) { ! 299: bad_modifier: ! 300: db_printf("Bad modifier\n"); ! 301: db_flush_lex(); ! 302: return; ! 303: } ! 304: ! 305: if (!strcmp(db_tok_string, "b")) ! 306: size = 1; ! 307: else if (!strcmp(db_tok_string, "h")) ! 308: size = 2; ! 309: else if (!strcmp(db_tok_string, "l")) ! 310: size = 4; ! 311: else ! 312: goto bad_modifier; ! 313: } else { ! 314: db_unread_token(t); ! 315: size = 4; ! 316: } ! 317: ! 318: if (!db_expression(&addr)) { ! 319: db_printf("Address missing\n"); ! 320: db_flush_lex(); ! 321: return; ! 322: } ! 323: ! 324: if (!db_expression(&value)) { ! 325: db_printf("Value missing\n"); ! 326: db_flush_lex(); ! 327: return; ! 328: } ! 329: ! 330: if (!db_expression(&mask)) ! 331: mask = 0xffffffff; ! 332: ! 333: t = db_read_token(); ! 334: if (t == tCOMMA) { ! 335: if (!db_expression(&count)) { ! 336: db_printf("Count missing\n"); ! 337: db_flush_lex(); ! 338: return; ! 339: } ! 340: } else { ! 341: db_unread_token(t); ! 342: count = -1; /* effectively forever */ ! 343: } ! 344: db_skip_to_eol(); ! 345: ! 346: db_search(addr, size, value, mask, count); ! 347: } ! 348: ! 349: db_search(addr, size, value, mask, count) ! 350: register ! 351: db_addr_t addr; ! 352: int size; ! 353: db_expr_t value; ! 354: db_expr_t mask; ! 355: unsigned int count; ! 356: { ! 357: while (count-- != 0) { ! 358: db_prev = addr; ! 359: if ((db_get_value(addr, size, FALSE) & mask) == value) ! 360: break; ! 361: addr += size; ! 362: } ! 363: db_next = addr; ! 364: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.