Annotation of XNU/osfmk/ddb/db_examine.c, revision 1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.