|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. ! 3: * ! 4: * @APPLE_LICENSE_HEADER_START@ ! 5: * ! 6: * The contents of this file constitute Original Code as defined in and ! 7: * are subject to the Apple Public Source License Version 1.1 (the ! 8: * "License"). You may not use this file except in compliance with the ! 9: * License. Please obtain a copy of the License at ! 10: * http://www.apple.com/publicsource and read it before using this file. ! 11: * ! 12: * This Original Code and all software distributed under the License are ! 13: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER ! 14: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, ! 15: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, ! 16: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the ! 17: * License for the specific language governing rights and limitations ! 18: * under the License. ! 19: * ! 20: * @APPLE_LICENSE_HEADER_END@ ! 21: */ ! 22: /* ! 23: * @OSF_COPYRIGHT@ ! 24: */ ! 25: /* ! 26: * HISTORY ! 27: * ! 28: * Revision 1.1.1.1 1998/09/22 21:05:47 wsanchez ! 29: * Import of Mac OS X kernel (~semeria) ! 30: * ! 31: * Revision 1.2 1998/04/24 19:34:23 semeria ! 32: * KDP and KDB support ! 33: * ! 34: * Revision 1.1.1.1 1998/03/07 02:26:09 wsanchez ! 35: * Import of OSF Mach kernel (~mburg) ! 36: * ! 37: * Revision 1.2.42.2 1997/09/12 17:15:15 stephen ! 38: * make x/x do zero fill right justified hex display ! 39: * [1997/09/12 16:31:04 stephen] ! 40: * ! 41: * Revision 1.2.42.1 1997/03/27 18:46:31 barbou ! 42: * Add 'p' option to the "examine" command - values in ! 43: * memory treated as addresses and rendered as sym+offset ! 44: * [1995/12/29 21:32:33 mod] ! 45: * ri-osc CR1560: make search command output address of any matching ! 46: * data it finds (so user knows it did something). ! 47: * [1995/09/20 15:24:55 bolinger] ! 48: * [97/02/25 barbou] ! 49: * ! 50: * Revision 1.2.25.5 1996/01/09 19:15:38 devrcs ! 51: * Add db_print_loc() & db_print_inst() functions. ! 52: * Make 'l' display 32 bits and new 'q' to display 64 bits. ! 53: * Allow 'u' to display unsigned decimal values (same as 'U'). ! 54: * Changed declarations of 'register foo' to 'register int foo'. ! 55: * [1995/12/01 21:42:03 jfraser] ! 56: * ! 57: * Merged '64-bit safe' changes from DEC alpha port. ! 58: * [1995/11/21 18:02:58 jfraser] ! 59: * ! 60: * Revision 1.2.25.4 1995/06/13 18:21:27 sjs ! 61: * Merge with flipc_shared. ! 62: * [95/05/22 sjs] ! 63: * ! 64: * Revision 1.2.30.1 1995/04/03 17:35:17 randys ! 65: * Minor change; allow a repeat count to work properly when multiple ! 66: * modifier flags are given to the ddb 'x' command. This allows, ! 67: * for instance, examination of multiple words in activations other ! 68: * than the current one. ! 69: * [95/04/03 randys] ! 70: * ! 71: * Revision 1.2.25.3 1995/01/06 19:10:09 devrcs ! 72: * mk6 CR668 - 1.3b26 merge ! 73: * * Revision 1.2.6.7 1994/05/06 18:39:09 tmt ! 74: * Merged osc1.3dec/shared with osc1.3b19 ! 75: * Merge Alpha changes into osc1.312b source code. ! 76: * 64bit cleanup. ! 77: * * End1.3merge ! 78: * [1994/11/04 08:49:22 dwm] ! 79: * ! 80: * Revision 1.2.25.2 1994/09/23 01:18:44 ezf ! 81: * change marker to not FREE ! 82: * [1994/09/22 21:09:44 ezf] ! 83: * ! 84: * Revision 1.2.25.1 1994/06/11 21:11:43 bolinger ! 85: * Merge up to NMK17.2. ! 86: * [1994/06/11 20:01:31 bolinger] ! 87: * ! 88: * Revision 1.2.23.1 1994/02/08 10:57:47 bernadat ! 89: * Fixed output of an examine command to have a power of 2 ! 90: * number of fields. ! 91: * [93/09/29 paire] ! 92: * ! 93: * Added dump of hexadecimal address in each line of examine command. ! 94: * Fixed beginning of line to be always located at position 0. ! 95: * [93/08/11 paire] ! 96: * [94/02/07 bernadat] ! 97: * ! 98: * Revision 1.2.21.4 1994/03/17 22:35:27 dwm ! 99: * The infamous name change: thread_activation + thread_shuttle = thread. ! 100: * [1994/03/17 21:25:43 dwm] ! 101: * ! 102: * Revision 1.2.21.3 1994/01/12 17:50:40 dwm ! 103: * Coloc: initial restructuring to follow Utah model. ! 104: * [1994/01/12 17:13:08 dwm] ! 105: * ! 106: * Revision 1.2.21.2 1993/10/12 16:38:58 dwm ! 107: * Print '\n' in x/s statements. [rwd] ! 108: * [1993/10/12 16:14:41 dwm] ! 109: * ! 110: * Revision 1.2.6.5 1993/08/11 20:37:37 elliston ! 111: * Add ANSI Prototypes. CR #9523. ! 112: * [1993/08/11 03:33:05 elliston] ! 113: * ! 114: * Revision 1.2.6.4 1993/08/09 19:34:42 dswartz ! 115: * Add ANSI prototypes - CR#9523 ! 116: * [1993/08/06 15:47:32 dswartz] ! 117: * ! 118: * Revision 1.2.6.3 1993/07/27 18:27:07 elliston ! 119: * Add ANSI prototypes. CR #9523. ! 120: * [1993/07/27 18:11:21 elliston] ! 121: * ! 122: * Revision 1.2.6.2 1993/06/09 02:20:00 gm ! 123: * Added to OSF/1 R1.3 from NMK15.0. ! 124: * [1993/06/02 20:56:10 jeffc] ! 125: * ! 126: * Revision 1.2 1993/04/19 16:01:58 devrcs ! 127: * Changes from mk78: ! 128: * Added void type to functions that needed it. ! 129: * Added init to 'size' in db_search_cmd(). Removed unused variables. ! 130: * Other cleanup to quiet gcc warnings. ! 131: * [92/05/16 jfriedl] ! 132: * x/u now examines current user space. x/t still examines user ! 133: * space of the the specified thread. x/tu is redundant. ! 134: * To examine an value as unsigned decimal, use x/U. ! 135: * [92/04/18 danner] ! 136: * [93/02/02 bruel] ! 137: * ! 138: * Remember count argument when repeating commands instead of the ! 139: * default command, also apply all the formats to current address ! 140: * instead of incrementing addresses when switching to next format. ! 141: * [[email protected]] ! 142: * ! 143: * Support 'A' format for print 'p' command [[email protected]] ! 144: * [92/12/03 bernadat] ! 145: * ! 146: * Revision 1.1 1992/09/30 02:01:01 robert ! 147: * Initial revision ! 148: * ! 149: * $EndLog$ ! 150: */ ! 151: /* CMU_HIST */ ! 152: /* ! 153: * Revision 2.7 91/10/09 15:59:28 af ! 154: * Revision 2.6.1.1 91/10/05 13:05:49 jeffreyh ! 155: * Supported non current task space data examination and search. ! 156: * Added 'm' format and db_xcdump to print with hex and characters. ! 157: * Added db_examine_{forward, backward}. ! 158: * Changed db_print_cmd to support variable number of parameters ! 159: * including string constant. ! 160: * Included "db_access.h". ! 161: * [91/08/29 tak] ! 162: * ! 163: * Revision 2.6.1.1 91/10/05 13:05:49 jeffreyh ! 164: * Supported non current task space data examination and search. ! 165: * Added 'm' format and db_xcdump to print with hex and characters. ! 166: * Added db_examine_{forward, backward}. ! 167: * Changed db_print_cmd to support variable number of parameters ! 168: * including string constant. ! 169: * Included "db_access.h". ! 170: * [91/08/29 tak] ! 171: * ! 172: * Revision 2.6 91/08/28 11:11:01 jsb ! 173: * Added 'A' flag to examine: just like 'a' (address), but prints addr ! 174: * as a procedure type, thus printing file/line info if available. ! 175: * Useful when called as 'x/Ai'. ! 176: * [91/08/13 18:14:55 jsb] ! 177: * ! 178: * Revision 2.5 91/05/14 15:33:31 mrt ! 179: * Correcting copyright ! 180: * ! 181: * Revision 2.4 91/02/05 17:06:20 mrt ! 182: * Changed to new Mach copyright ! 183: * [91/01/31 16:17:37 mrt] ! 184: * ! 185: * Revision 2.3 90/11/07 16:49:23 rpd ! 186: * Added db_search_cmd, db_search. ! 187: * [90/11/06 rpd] ! 188: * ! 189: * Revision 2.2 90/08/27 21:50:38 dbg ! 190: * Add 'r', 'z' to print and examine formats. ! 191: * Change calling sequence of db_disasm. ! 192: * db_examine sets db_prev and db_next instead of explicitly ! 193: * advancing dot. ! 194: * [90/08/20 dbg] ! 195: * Reflected changes in db_printsym()'s calling seq. ! 196: * [90/08/20 af] ! 197: * Reduce lint. ! 198: * [90/08/07 dbg] ! 199: * Created. ! 200: * [90/07/25 dbg] ! 201: * ! 202: */ ! 203: /* CMU_ENDHIST */ ! 204: /* ! 205: * Mach Operating System ! 206: * Copyright (c) 1991,1990 Carnegie Mellon University ! 207: * All Rights Reserved. ! 208: * ! 209: * Permission to use, copy, modify and distribute this software and its ! 210: * documentation is hereby granted, provided that both the copyright ! 211: * notice and this permission notice appear in all copies of the ! 212: * software, derivative works or modified versions, and any portions ! 213: * thereof, and that both notices appear in supporting documentation. ! 214: * ! 215: * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" ! 216: * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR ! 217: * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. ! 218: * ! 219: * Carnegie Mellon requests users of this software to return to ! 220: * ! 221: * Software Distribution Coordinator or [email protected] ! 222: * School of Computer Science ! 223: * Carnegie Mellon University ! 224: * Pittsburgh PA 15213-3890 ! 225: * ! 226: * any improvements or extensions that they make and grant Carnegie Mellon ! 227: * the rights to redistribute these changes. ! 228: */ ! 229: /* ! 230: */ ! 231: /* ! 232: * Author: David B. Golub, Carnegie Mellon University ! 233: * Date: 7/90 ! 234: */ ! 235: #include <string.h> /* For strcpy() */ ! 236: #include <mach/boolean.h> ! 237: #include <machine/db_machdep.h> ! 238: ! 239: #include <ddb/db_access.h> ! 240: #include <ddb/db_lex.h> ! 241: #include <ddb/db_output.h> ! 242: #include <ddb/db_command.h> ! 243: #include <ddb/db_sym.h> ! 244: #include <ddb/db_task_thread.h> ! 245: #include <ddb/db_command.h> /* For db_option() */ ! 246: #include <ddb/db_examine.h> ! 247: #include <ddb/db_expr.h> ! 248: #include <kern/thread.h> ! 249: #include <kern/task.h> ! 250: #include <mach/vm_param.h> ! 251: ! 252: #define db_act_to_task(thr_act) ((thr_act)? thr_act->task: TASK_NULL) ! 253: ! 254: char db_examine_format[TOK_STRING_SIZE] = "x"; ! 255: int db_examine_count = 1; ! 256: db_addr_t db_examine_prev_addr = 0; ! 257: thread_act_t db_examine_act = THR_ACT_NULL; ! 258: ! 259: extern int db_max_width; ! 260: ! 261: ! 262: /* Prototypes for functions local to this file. XXX -- should be static! ! 263: */ ! 264: int db_xcdump( ! 265: db_addr_t addr, ! 266: int size, ! 267: int count, ! 268: task_t task); ! 269: ! 270: int db_examine_width( ! 271: int size, ! 272: int *items, ! 273: int *remainder); ! 274: ! 275: /* ! 276: * Examine (print) data. ! 277: */ ! 278: void ! 279: db_examine_cmd( ! 280: db_expr_t addr, ! 281: int have_addr, ! 282: db_expr_t count, ! 283: char * modif) ! 284: { ! 285: thread_act_t thr_act; ! 286: extern char db_last_modifier[]; ! 287: ! 288: if (modif[0] != '\0') ! 289: strcpy(db_examine_format, modif); ! 290: ! 291: if (count == -1) ! 292: count = 1; ! 293: db_examine_count = count; ! 294: if (db_option(modif, 't')) { ! 295: if (modif == db_last_modifier) ! 296: thr_act = db_examine_act; ! 297: else if (!db_get_next_act(&thr_act, 0)) ! 298: return; ! 299: } else ! 300: if (db_option(modif,'u')) ! 301: thr_act = current_act(); ! 302: else ! 303: thr_act = THR_ACT_NULL; ! 304: ! 305: db_examine_act = thr_act; ! 306: db_examine((db_addr_t) addr, db_examine_format, count, ! 307: db_act_to_task(thr_act)); ! 308: } ! 309: ! 310: void ! 311: db_examine_forward( ! 312: db_expr_t addr, ! 313: int have_addr, ! 314: db_expr_t count, ! 315: char * modif) ! 316: { ! 317: db_examine(db_next, db_examine_format, db_examine_count, ! 318: db_act_to_task(db_examine_act)); ! 319: } ! 320: ! 321: void ! 322: db_examine_backward( ! 323: db_expr_t addr, ! 324: int have_addr, ! 325: db_expr_t count, ! 326: char * modif) ! 327: { ! 328: db_examine(db_examine_prev_addr - (db_next - db_examine_prev_addr), ! 329: db_examine_format, db_examine_count, ! 330: db_act_to_task(db_examine_act)); ! 331: } ! 332: ! 333: int ! 334: db_examine_width( ! 335: int size, ! 336: int *items, ! 337: int *remainder) ! 338: { ! 339: int sz; ! 340: int entry; ! 341: int width; ! 342: ! 343: width = size * 2 + 1; ! 344: sz = (db_max_width - (sizeof (void *) * 2 + 4)) / width; ! 345: for (entry = 1; (entry << 1) < sz; entry <<= 1) ! 346: continue; ! 347: ! 348: sz = sizeof (void *) * 2 + 4 + entry * width; ! 349: while (sz + entry < db_max_width) { ! 350: width++; ! 351: sz += entry; ! 352: } ! 353: *remainder = (db_max_width - sz + 1) / 2; ! 354: *items = entry; ! 355: return width; ! 356: } ! 357: ! 358: void ! 359: db_examine( ! 360: db_addr_t addr, ! 361: char * fmt, /* format string */ ! 362: int count, /* repeat count */ ! 363: task_t task) ! 364: { ! 365: int c; ! 366: db_expr_t value; ! 367: int size; ! 368: int width; ! 369: int leader; ! 370: int items; ! 371: int nitems; ! 372: char * fp; ! 373: db_addr_t next_addr; ! 374: int sz; ! 375: ! 376: db_examine_prev_addr = addr; ! 377: while (--count >= 0) { ! 378: fp = fmt; ! 379: size = sizeof(int); ! 380: width = db_examine_width(size, &items, &leader); ! 381: while ((c = *fp++) != 0) { ! 382: switch (c) { ! 383: case 'b': ! 384: size = sizeof(char); ! 385: width = db_examine_width(size, &items, &leader); ! 386: break; ! 387: case 'h': ! 388: size = sizeof(short); ! 389: width = db_examine_width(size, &items, &leader); ! 390: break; ! 391: case 'l': ! 392: size = sizeof(int); ! 393: width = db_examine_width(size, &items, &leader); ! 394: break; ! 395: case 'q': ! 396: size = sizeof(long); ! 397: width = db_examine_width(size, &items, &leader); ! 398: break; ! 399: case 'a': /* address */ ! 400: case 'A': /* function address */ ! 401: /* always forces a new line */ ! 402: if (db_print_position() != 0) ! 403: db_printf("\n"); ! 404: db_prev = addr; ! 405: next_addr = addr + 4; ! 406: db_task_printsym(addr, ! 407: (c == 'a')?DB_STGY_ANY:DB_STGY_PROC, ! 408: task); ! 409: db_printf(":\t"); ! 410: break; ! 411: case 'm': ! 412: db_next = db_xcdump(addr, size, count+1, task); ! 413: return; ! 414: case 't': ! 415: case 'u': ! 416: break; ! 417: default: ! 418: restart: ! 419: /* Reset next_addr in case we are printing in ! 420: multiple formats. */ ! 421: next_addr = addr; ! 422: if (db_print_position() == 0) { ! 423: /* If we hit a new symbol, print it */ ! 424: char * name; ! 425: db_addr_t off; ! 426: ! 427: db_find_task_sym_and_offset(addr,&name,&off,task); ! 428: if (off == 0) ! 429: db_printf("\r%s:\n", name); ! 430: db_printf("%#n: ", addr); ! 431: for (sz = 0; sz < leader; sz++) ! 432: db_putchar(' '); ! 433: db_prev = addr; ! 434: nitems = items; ! 435: } ! 436: ! 437: switch (c) { ! 438: case 'p': /* Addrs rendered symbolically. */ ! 439: if( size == sizeof(void *) ) { ! 440: char *symName; ! 441: db_addr_t offset; ! 442: ! 443: items = 1; ! 444: value = db_get_task_value( next_addr, ! 445: sizeof(db_expr_t), FALSE, task ); ! 446: db_find_task_sym_and_offset( value, ! 447: &symName, &offset, task); ! 448: db_printf("\n\t*%8x(%8X) = %s", ! 449: next_addr, value, symName ); ! 450: if( offset ) { ! 451: db_printf("+%X", offset ); ! 452: } ! 453: next_addr += size; ! 454: } ! 455: break; ! 456: case 'r': /* signed, current radix */ ! 457: for (sz = size, next_addr = addr; ! 458: sz >= sizeof (db_expr_t); ! 459: sz -= sizeof (db_expr_t)) { ! 460: if (nitems-- == 0) { ! 461: db_putchar('\n'); ! 462: goto restart; ! 463: } ! 464: value = db_get_task_value(next_addr, ! 465: sizeof (db_expr_t), ! 466: TRUE,task); ! 467: db_printf("%-*r", width, value); ! 468: next_addr += sizeof (db_expr_t); ! 469: } ! 470: if (sz > 0) { ! 471: if (nitems-- == 0) { ! 472: db_putchar('\n'); ! 473: goto restart; ! 474: } ! 475: value = db_get_task_value(next_addr, sz, ! 476: TRUE, task); ! 477: db_printf("%-*R", width, value); ! 478: next_addr += sz; ! 479: } ! 480: break; ! 481: #ifdef APPLE ! 482: case 'X': /* unsigned hex */ ! 483: #endif ! 484: case 'x': /* unsigned hex */ ! 485: for (sz = size, next_addr = addr; ! 486: sz >= sizeof (db_expr_t); ! 487: sz -= sizeof (db_expr_t)) { ! 488: if (nitems-- == 0) { ! 489: db_putchar('\n'); ! 490: goto restart; ! 491: } ! 492: value = db_get_task_value(next_addr, ! 493: sizeof (db_expr_t), ! 494: FALSE,task); ! 495: #ifdef APPLE ! 496: if ( c == 'X') ! 497: db_printf("%0*X ", 2*size, value); ! 498: else ! 499: db_printf("%-*x", width, value); ! 500: #else ! 501: db_printf("%-*x", width, value); ! 502: #endif ! 503: next_addr += sizeof (db_expr_t); ! 504: } ! 505: if (sz > 0) { ! 506: if (nitems-- == 0) { ! 507: db_putchar('\n'); ! 508: goto restart; ! 509: } ! 510: value = db_get_task_value(next_addr, sz, ! 511: FALSE, task); ! 512: #ifdef APPLE ! 513: if ( c == 'X') ! 514: db_printf("%0*X ", 2*size, value); ! 515: else ! 516: db_printf("%-*X", width, value); ! 517: #else ! 518: db_printf("%-*X", width, value); ! 519: #endif ! 520: next_addr += sz; ! 521: } ! 522: break; ! 523: case 'z': /* signed hex */ ! 524: for (sz = size, next_addr = addr; ! 525: sz >= sizeof (db_expr_t); ! 526: sz -= sizeof (db_expr_t)) { ! 527: if (nitems-- == 0) { ! 528: db_putchar('\n'); ! 529: goto restart; ! 530: } ! 531: value = db_get_task_value(next_addr, ! 532: sizeof (db_expr_t), ! 533: TRUE, task); ! 534: db_printf("%-*z", width, value); ! 535: next_addr += sizeof (db_expr_t); ! 536: } ! 537: if (sz > 0) { ! 538: if (nitems-- == 0) { ! 539: db_putchar('\n'); ! 540: goto restart; ! 541: } ! 542: value = db_get_task_value(next_addr,sz, ! 543: TRUE,task); ! 544: db_printf("%-*Z", width, value); ! 545: next_addr += sz; ! 546: } ! 547: break; ! 548: case 'd': /* signed decimal */ ! 549: for (sz = size, next_addr = addr; ! 550: sz >= sizeof (db_expr_t); ! 551: sz -= sizeof (db_expr_t)) { ! 552: if (nitems-- == 0) { ! 553: db_putchar('\n'); ! 554: goto restart; ! 555: } ! 556: value = db_get_task_value(next_addr, ! 557: sizeof (db_expr_t), ! 558: TRUE,task); ! 559: db_printf("%-*d", width, value); ! 560: next_addr += sizeof (db_expr_t); ! 561: } ! 562: if (sz > 0) { ! 563: if (nitems-- == 0) { ! 564: db_putchar('\n'); ! 565: goto restart; ! 566: } ! 567: value = db_get_task_value(next_addr, sz, ! 568: TRUE, task); ! 569: db_printf("%-*D", width, value); ! 570: next_addr += sz; ! 571: } ! 572: break; ! 573: case 'U': /* unsigned decimal */ ! 574: case 'u': ! 575: for (sz = size, next_addr = addr; ! 576: sz >= sizeof (db_expr_t); ! 577: sz -= sizeof (db_expr_t)) { ! 578: if (nitems-- == 0) { ! 579: db_putchar('\n'); ! 580: goto restart; ! 581: } ! 582: value = db_get_task_value(next_addr, ! 583: sizeof (db_expr_t), ! 584: FALSE,task); ! 585: db_printf("%-*u", width, value); ! 586: next_addr += sizeof (db_expr_t); ! 587: } ! 588: if (sz > 0) { ! 589: if (nitems-- == 0) { ! 590: db_putchar('\n'); ! 591: goto restart; ! 592: } ! 593: value = db_get_task_value(next_addr, sz, ! 594: FALSE, task); ! 595: db_printf("%-*U", width, value); ! 596: next_addr += sz; ! 597: } ! 598: break; ! 599: case 'o': /* unsigned octal */ ! 600: for (sz = size, next_addr = addr; ! 601: sz >= sizeof (db_expr_t); ! 602: sz -= sizeof (db_expr_t)) { ! 603: if (nitems-- == 0) { ! 604: db_putchar('\n'); ! 605: goto restart; ! 606: } ! 607: value = db_get_task_value(next_addr, ! 608: sizeof (db_expr_t), ! 609: FALSE,task); ! 610: db_printf("%-*o", width, value); ! 611: next_addr += sizeof (db_expr_t); ! 612: } ! 613: if (sz > 0) { ! 614: if (nitems-- == 0) { ! 615: db_putchar('\n'); ! 616: goto restart; ! 617: } ! 618: value = db_get_task_value(next_addr, sz, ! 619: FALSE, task); ! 620: db_printf("%-*o", width, value); ! 621: next_addr += sz; ! 622: } ! 623: break; ! 624: case 'c': /* character */ ! 625: for (sz = 0, next_addr = addr; ! 626: sz < size; ! 627: sz++, next_addr++) { ! 628: value = db_get_task_value(next_addr,1, ! 629: FALSE,task); ! 630: if ((value >= ' ' && value <= '~') || ! 631: value == '\n' || ! 632: value == '\t') ! 633: db_printf("%c", value); ! 634: else ! 635: db_printf("\\%03o", value); ! 636: } ! 637: break; ! 638: case 's': /* null-terminated string */ ! 639: size = 0; ! 640: for (;;) { ! 641: value = db_get_task_value(next_addr,1, ! 642: FALSE,task); ! 643: next_addr += 1; ! 644: size++; ! 645: if (value == 0) ! 646: break; ! 647: if (value >= ' ' && value <= '~') ! 648: db_printf("%c", value); ! 649: else ! 650: db_printf("\\%03o", value); ! 651: } ! 652: break; ! 653: case 'i': /* instruction */ ! 654: next_addr = db_disasm(addr, FALSE, task); ! 655: size = next_addr - addr; ! 656: break; ! 657: case 'I': /* instruction, alternate form */ ! 658: next_addr = db_disasm(addr, TRUE, task); ! 659: size = next_addr - addr; ! 660: break; ! 661: default: ! 662: break; ! 663: } ! 664: if (db_print_position() != 0) ! 665: db_end_line(); ! 666: break; ! 667: } ! 668: } ! 669: addr = next_addr; ! 670: } ! 671: db_next = addr; ! 672: } ! 673: ! 674: /* ! 675: * Print value. ! 676: */ ! 677: char db_print_format = 'x'; ! 678: ! 679: void ! 680: db_print_cmd(void) ! 681: { ! 682: db_expr_t value; ! 683: int t; ! 684: task_t task = TASK_NULL; ! 685: ! 686: if ((t = db_read_token()) == tSLASH) { ! 687: if (db_read_token() != tIDENT) { ! 688: db_printf("Bad modifier \"/%s\"\n", db_tok_string); ! 689: db_error(0); ! 690: /* NOTREACHED */ ! 691: } ! 692: if (db_tok_string[0]) ! 693: db_print_format = db_tok_string[0]; ! 694: if (db_option(db_tok_string, 't')) { ! 695: if (db_default_act) ! 696: task = db_default_act->task; ! 697: if (db_print_format == 't') ! 698: db_print_format = db_tok_string[1]; ! 699: } ! 700: } else ! 701: db_unread_token(t); ! 702: ! 703: for ( ; ; ) { ! 704: t = db_read_token(); ! 705: if (t == tSTRING) { ! 706: db_printf("%s", db_tok_string); ! 707: continue; ! 708: } ! 709: db_unread_token(t); ! 710: if (!db_expression(&value)) ! 711: break; ! 712: switch (db_print_format) { ! 713: case 'a': ! 714: case 'A': ! 715: db_task_printsym((db_addr_t)value, ! 716: (db_print_format == 'a') ? DB_STGY_ANY: ! 717: DB_STGY_PROC, ! 718: task); ! 719: break; ! 720: case 'r': ! 721: db_printf("%11r", value); ! 722: break; ! 723: case 'x': ! 724: db_printf("%08x", value); ! 725: break; ! 726: case 'z': ! 727: db_printf("%8z", value); ! 728: break; ! 729: case 'd': ! 730: db_printf("%11d", value); ! 731: break; ! 732: case 'u': ! 733: db_printf("%11u", value); ! 734: break; ! 735: case 'o': ! 736: db_printf("%16o", value); ! 737: break; ! 738: case 'c': ! 739: value = value & 0xFF; ! 740: if (value >= ' ' && value <= '~') ! 741: db_printf("%c", value); ! 742: else ! 743: db_printf("\\%03o", value); ! 744: break; ! 745: default: ! 746: db_printf("Unknown format %c\n", db_print_format); ! 747: db_print_format = 'x'; ! 748: db_error(0); ! 749: } ! 750: } ! 751: } ! 752: ! 753: void ! 754: db_print_loc( ! 755: db_addr_t loc, ! 756: task_t task) ! 757: { ! 758: db_task_printsym(loc, DB_STGY_PROC, task); ! 759: } ! 760: ! 761: void ! 762: db_print_inst( ! 763: db_addr_t loc, ! 764: task_t task) ! 765: { ! 766: (void) db_disasm(loc, TRUE, task); ! 767: } ! 768: ! 769: void ! 770: db_print_loc_and_inst( ! 771: db_addr_t loc, ! 772: task_t task) ! 773: { ! 774: db_task_printsym(loc, DB_STGY_PROC, task); ! 775: db_printf(":\t"); ! 776: (void) db_disasm(loc, TRUE, task); ! 777: } ! 778: ! 779: /* ! 780: * Search for a value in memory. ! 781: * Syntax: search [/bhl] addr value [mask] [,count] [thread] ! 782: */ ! 783: void ! 784: db_search_cmd(void) ! 785: { ! 786: int t; ! 787: db_addr_t addr; ! 788: int size = 0; ! 789: db_expr_t value; ! 790: db_expr_t mask; ! 791: db_addr_t count; ! 792: thread_act_t thr_act; ! 793: boolean_t thread_flag = FALSE; ! 794: register char *p; ! 795: ! 796: t = db_read_token(); ! 797: if (t == tSLASH) { ! 798: t = db_read_token(); ! 799: if (t != tIDENT) { ! 800: bad_modifier: ! 801: db_printf("Bad modifier \"/%s\"\n", db_tok_string); ! 802: db_flush_lex(); ! 803: return; ! 804: } ! 805: ! 806: for (p = db_tok_string; *p; p++) { ! 807: switch(*p) { ! 808: case 'b': ! 809: size = sizeof(char); ! 810: break; ! 811: case 'h': ! 812: size = sizeof(short); ! 813: break; ! 814: case 'l': ! 815: size = sizeof(long); ! 816: break; ! 817: case 't': ! 818: thread_flag = TRUE; ! 819: break; ! 820: default: ! 821: goto bad_modifier; ! 822: } ! 823: } ! 824: } else { ! 825: db_unread_token(t); ! 826: size = sizeof(int); ! 827: } ! 828: ! 829: if (!db_expression((db_expr_t *) &addr)) { ! 830: db_printf("Address missing\n"); ! 831: db_flush_lex(); ! 832: return; ! 833: } ! 834: ! 835: if (!db_expression(&value)) { ! 836: db_printf("Value missing\n"); ! 837: db_flush_lex(); ! 838: return; ! 839: } ! 840: ! 841: if (!db_expression(&mask)) ! 842: mask = ~0; ! 843: ! 844: t = db_read_token(); ! 845: if (t == tCOMMA) { ! 846: if (!db_expression((db_expr_t *) &count)) { ! 847: db_printf("Count missing\n"); ! 848: db_flush_lex(); ! 849: return; ! 850: } ! 851: } else { ! 852: db_unread_token(t); ! 853: count = -1; /* effectively forever */ ! 854: } ! 855: if (thread_flag) { ! 856: if (!db_get_next_act(&thr_act, 0)) ! 857: return; ! 858: } else ! 859: thr_act = THR_ACT_NULL; ! 860: ! 861: db_search(addr, size, value, mask, count, db_act_to_task(thr_act)); ! 862: } ! 863: ! 864: void ! 865: db_search( ! 866: db_addr_t addr, ! 867: int size, ! 868: db_expr_t value, ! 869: db_expr_t mask, ! 870: unsigned int count, ! 871: task_t task) ! 872: { ! 873: while (count-- != 0) { ! 874: db_prev = addr; ! 875: if ((db_get_task_value(addr,size,FALSE,task) & mask) == value) ! 876: break; ! 877: addr += size; ! 878: } ! 879: db_printf("0x%x: ", addr); ! 880: db_next = addr; ! 881: } ! 882: ! 883: #define DB_XCDUMP_NC 16 ! 884: ! 885: int ! 886: db_xcdump( ! 887: db_addr_t addr, ! 888: int size, ! 889: int count, ! 890: task_t task) ! 891: { ! 892: register int i, n; ! 893: db_expr_t value; ! 894: int bcount; ! 895: db_addr_t off; ! 896: char *name; ! 897: char data[DB_XCDUMP_NC]; ! 898: ! 899: db_find_task_sym_and_offset(addr, &name, &off, task); ! 900: for (n = count*size; n > 0; n -= bcount) { ! 901: db_prev = addr; ! 902: if (off == 0) { ! 903: db_printf("%s:\n", name); ! 904: off = -1; ! 905: } ! 906: db_printf("%0*X:%s", 2*sizeof(db_addr_t), addr, ! 907: (size != 1) ? " " : "" ); ! 908: bcount = ((n > DB_XCDUMP_NC)? DB_XCDUMP_NC: n); ! 909: if (trunc_page(addr) != trunc_page(addr+bcount-1)) { ! 910: db_addr_t next_page_addr = trunc_page(addr+bcount-1); ! 911: if (!DB_CHECK_ACCESS(next_page_addr, sizeof(int), task)) ! 912: bcount = next_page_addr - addr; ! 913: } ! 914: db_read_bytes((vm_offset_t)addr, bcount, data, task); ! 915: for (i = 0; i < bcount && off != 0; i += size) { ! 916: if (i % 4 == 0) ! 917: db_printf(" "); ! 918: value = db_get_task_value(addr, size, FALSE, task); ! 919: db_printf("%0*x ", size*2, value); ! 920: addr += size; ! 921: db_find_task_sym_and_offset(addr, &name, &off, task); ! 922: } ! 923: db_printf("%*s", ! 924: ((DB_XCDUMP_NC-i)/size)*(size*2+1)+(DB_XCDUMP_NC-i)/4, ! 925: ""); ! 926: bcount = i; ! 927: db_printf("%s*", (size != 1)? " ": ""); ! 928: for (i = 0; i < bcount; i++) { ! 929: value = data[i]; ! 930: db_printf("%c", (value >= ' ' && value <= '~')? value: '.'); ! 931: } ! 932: db_printf("*\n"); ! 933: } ! 934: return(addr); ! 935: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.