Annotation of XNU/osfmk/ddb/db_command.c, revision 1.1.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:  * Mach Operating System
                     27:  * Copyright (c) 1991 Carnegie Mellon University
                     28:  * All Rights Reserved.
                     29:  * 
                     30:  * Permission to use, copy, modify and distribute this software and its
                     31:  * documentation is hereby granted, provided that both the copyright
                     32:  * notice and this permission notice appear in all copies of the
                     33:  * software, derivative works or modified versions, and any portions
                     34:  * thereof, and that both notices appear in supporting documentation.
                     35:  * 
                     36:  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
                     37:  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
                     38:  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
                     39:  * 
                     40:  * Carnegie Mellon requests users of this software to return to
                     41:  * 
                     42:  *  Software Distribution Coordinator  or  [email protected]
                     43:  *  School of Computer Science
                     44:  *  Carnegie Mellon University
                     45:  *  Pittsburgh PA 15213-3890
                     46:  * 
                     47:  * any improvements or extensions that they make and grant Carnegie Mellon
                     48:  * the rights to redistribute these changes.
                     49:  */
                     50: /*
                     51:  */
                     52: /*
                     53:  *     Author: David B. Golub, Carnegie Mellon University
                     54:  *     Date:   7/90
                     55:  */
                     56: 
                     57: /*
                     58:  * Command dispatcher.
                     59:  */
                     60: #include <cpus.h>
                     61: #include <dipc.h>
                     62: #include <dipc_timer.h>
                     63: #include <xkmachkernel.h>
                     64: #include <norma_vm.h>
                     65: #ifdef AT386
                     66: #include <norma_scsi.h>
                     67: #endif /* AT386 */
                     68: 
                     69: #include <mach/boolean.h>
                     70: #include <string.h>
                     71: #include <machine/db_machdep.h>
                     72: 
                     73: #if defined(__alpha)
                     74: #  include <kdebug.h>
                     75: #  if KDEBUG
                     76: #    include <machine/kdebug.h>
                     77: #  endif
                     78: #endif /* defined(__alpha) */
                     79: 
                     80: #include <ddb/db_lex.h>
                     81: #include <ddb/db_output.h>
                     82: #include <ddb/db_break.h>
                     83: #include <ddb/db_command.h>
                     84: #include <ddb/db_cond.h>
                     85: #include <ddb/db_examine.h>
                     86: #include <ddb/db_expr.h>
                     87: #include <ppc/db_low_trace.h>
                     88: #include <ddb/db_macro.h>
                     89: #include <ddb/db_print.h>
                     90: #include <ddb/db_run.h>
                     91: #include <ddb/db_task_thread.h>
                     92: #include <ddb/db_variables.h>
                     93: #include <ddb/db_watch.h>
                     94: #include <ddb/db_write_cmd.h>
                     95: #include <ddb/tr.h>
                     96: 
                     97: #include <machine/setjmp.h>
                     98: #include <kern/thread.h>
                     99: 
                    100: #include <kern/misc_protos.h>
                    101: #include <vm/vm_print.h>
                    102: #include <ipc/ipc_print.h>
                    103: #include <kern/kern_print.h>
                    104: #include <machine/db_machdep.h>                /* For db_stack_trace_cmd(). */
                    105: #include <kern/zalloc.h>       /* For db_show_one_zone, db_show_all_zones. */
                    106: #include <kern/lock.h>                 /* For db_show_all_slocks(). */
                    107: 
                    108: #if    DIPC_TIMER
                    109: #include <dipc/dipc_timer.h>
                    110: #endif /* DIPC_TIMER */
                    111: 
                    112: #if    NORMA_VM
                    113: #include <xmm/xmm_obj.h>
                    114: #endif /* NORMA_VM */
                    115: 
                    116: /*
                    117:  * Exported global variables
                    118:  */
                    119: boolean_t      db_cmd_loop_done;
                    120: jmp_buf_t      *db_recover = 0;
                    121: db_addr_t      db_dot;
                    122: db_addr_t      db_last_addr;
                    123: db_addr_t      db_prev;
                    124: db_addr_t      db_next;
                    125: 
                    126: /*
                    127:  * if 'ed' style: 'dot' is set at start of last item printed,
                    128:  * and '+' points to next line.
                    129:  * Otherwise: 'dot' points to next item, '..' points to last.
                    130:  */
                    131: boolean_t      db_ed_style = TRUE;
                    132: 
                    133: /*
                    134:  * Results of command search.
                    135:  */
                    136: #define        CMD_UNIQUE      0
                    137: #define        CMD_FOUND       1
                    138: #define        CMD_NONE        2
                    139: #define        CMD_AMBIGUOUS   3
                    140: #define        CMD_HELP        4
                    141: 
                    142: /* Prototypes for functions local to this file.  XXX -- should be static!
                    143:  */
                    144: 
                    145: void db_command(
                    146:        struct db_command       **last_cmdp,    /* IN_OUT */
                    147:        db_expr_t               *last_countp,   /* IN_OUT */
                    148:        char                    *last_modifp,   /* IN_OUT */
                    149:        struct db_command       *cmd_table);
                    150: 
                    151: void db_help_cmd(void);
                    152: 
                    153: void db_output_prompt(void);
                    154: 
                    155: void db_fncall(void);
                    156: 
                    157: void db_cmd_list(struct db_command *table);
                    158: 
                    159: int db_cmd_search(
                    160:        char *                  name,
                    161:        struct db_command *     table,
                    162:        struct db_command **    cmdp);  /* out */
                    163: 
                    164: void db_command_list(
                    165:        struct db_command       **last_cmdp,    /* IN_OUT */
                    166:        db_expr_t               *last_countp,   /* IN_OUT */
                    167:        char                    *last_modifp,   /* IN_OUT */
                    168:        struct db_command       *cmd_table);
                    169: 
                    170: 
                    171: 
                    172: /*
                    173:  * Search for command prefix.
                    174:  */
                    175: int
                    176: db_cmd_search(
                    177:        char *                  name,
                    178:        struct db_command *     table,
                    179:        struct db_command **    cmdp)   /* out */
                    180: {
                    181:        struct db_command       *cmd;
                    182:        int             result = CMD_NONE;
                    183: 
                    184:        for (cmd = table; cmd->name != 0; cmd++) {
                    185:            register char *lp;
                    186:            register char *rp;
                    187:            register int  c;
                    188: 
                    189:            lp = name;
                    190:            rp = cmd->name;
                    191:            while ((c = *lp) == *rp) {
                    192:                if (c == 0) {
                    193:                    /* complete match */
                    194:                    *cmdp = cmd;
                    195:                    return (CMD_UNIQUE);
                    196:                }
                    197:                lp++;
                    198:                rp++;
                    199:            }
                    200:            if (c == 0) {
                    201:                /* end of name, not end of command -
                    202:                   partial match */
                    203:                if (result == CMD_FOUND) {
                    204:                    result = CMD_AMBIGUOUS;
                    205:                    /* but keep looking for a full match -
                    206:                       this lets us match single letters */
                    207:                }
                    208:                else {
                    209:                    *cmdp = cmd;
                    210:                    result = CMD_FOUND;
                    211:                }
                    212:            }
                    213:        }
                    214:        if (result == CMD_NONE) {
                    215:            /* check for 'help' */
                    216:            if (!strncmp(name, "help", strlen(name)))
                    217:                result = CMD_HELP;
                    218:        }
                    219:        return (result);
                    220: }
                    221: 
                    222: void
                    223: db_cmd_list(struct db_command *table)
                    224: {
                    225:        register struct db_command *new;
                    226:        register struct db_command *old;
                    227:        register struct db_command *cur;
                    228:        unsigned int l;
                    229:        unsigned int len;
                    230: 
                    231:        len = 1;
                    232:        for (cur = table; cur->name != 0; cur++)
                    233:            if ((l = strlen(cur->name)) >= len)
                    234:                len = l + 1;
                    235: 
                    236:        old = (struct db_command *)0;
                    237:        for (;;) {
                    238:            new = (struct db_command *)0;
                    239:            for (cur = table; cur->name != 0; cur++)
                    240:                if ((new == (struct db_command *)0 ||
                    241:                     strcmp(cur->name, new->name) < 0) &&
                    242:                    (old == (struct db_command *)0 ||
                    243:                     strcmp(cur->name, old->name) > 0))
                    244:                    new = cur;
                    245:            if (new == (struct db_command *)0)
                    246:                    return;
                    247:            db_reserve_output_position(len);
                    248:            db_printf("%-*s", len, new->name);
                    249:            old = new;
                    250:        }
                    251: }
                    252: 
                    253: void
                    254: db_command(
                    255:        struct db_command       **last_cmdp,    /* IN_OUT */
                    256:        db_expr_t               *last_countp,   /* IN_OUT */
                    257:        char                    *last_modifp,   /* IN_OUT */
                    258:        struct db_command       *cmd_table)
                    259: {
                    260:        struct db_command       *cmd;
                    261:        int             t;
                    262:        char            modif[TOK_STRING_SIZE];
                    263:        char            *modifp = &modif[0];
                    264:        db_expr_t       addr, count;
                    265:        boolean_t       have_addr;
                    266:        int             result;
                    267: 
                    268:        t = db_read_token();
                    269:        if (t == tEOL || t == tSEMI_COLON) {
                    270:            /* empty line repeats last command, at 'next' */
                    271:            cmd = *last_cmdp;
                    272:            count = *last_countp;
                    273:            modifp = last_modifp;
                    274:            addr = (db_expr_t)db_next;
                    275:            have_addr = FALSE;
                    276:            if (t == tSEMI_COLON)
                    277:                db_unread_token(t);
                    278:        }
                    279:        else if (t == tEXCL) {
                    280:            db_fncall();
                    281:            return;
                    282:        }
                    283:        else if (t != tIDENT) {
                    284:            db_printf("?\n");
                    285:            db_flush_lex();
                    286:            return;
                    287:        }
                    288:        else {
                    289:            /*
                    290:             * Search for command
                    291:             */
                    292:            while (cmd_table) {
                    293:                result = db_cmd_search(db_tok_string,
                    294:                                       cmd_table,
                    295:                                       &cmd);
                    296:                switch (result) {
                    297:                    case CMD_NONE:
                    298:                        if (db_exec_macro(db_tok_string) == 0)
                    299:                            return;
                    300:                        db_printf("No such command \"%s\"\n", db_tok_string);
                    301:                        db_flush_lex();
                    302:                        return;
                    303:                    case CMD_AMBIGUOUS:
                    304:                        db_printf("Ambiguous\n");
                    305:                        db_flush_lex();
                    306:                        return;
                    307:                    case CMD_HELP:
                    308:                        db_cmd_list(cmd_table);
                    309:                        db_flush_lex();
                    310:                        return;
                    311:                    default:
                    312:                        break;
                    313:                }
                    314:                if ((cmd_table = cmd->more) != 0) {
                    315:                    t = db_read_token();
                    316:                    if (t != tIDENT) {
                    317:                        db_cmd_list(cmd_table);
                    318:                        db_flush_lex();
                    319:                        return;
                    320:                    }
                    321:                }
                    322:            }
                    323: 
                    324:            if ((cmd->flag & CS_OWN) == 0) {
                    325:                /*
                    326:                 * Standard syntax:
                    327:                 * command [/modifier] [addr] [,count]
                    328:                 */
                    329:                t = db_read_token();
                    330:                if (t == tSLASH) {
                    331:                    t = db_read_token();
                    332:                    if (t != tIDENT) {
                    333:                        db_printf("Bad modifier \"/%s\"\n", db_tok_string);
                    334:                        db_flush_lex();
                    335:                        return;
                    336:                    }
                    337:                    strcpy(modif, db_tok_string);
                    338:                }
                    339:                else {
                    340:                    db_unread_token(t);
                    341:                    modif[0] = '\0';
                    342:                }
                    343: 
                    344:                if (db_expression(&addr)) {
                    345:                    db_dot = (db_addr_t) addr;
                    346:                    db_last_addr = db_dot;
                    347:                    have_addr = TRUE;
                    348:                }
                    349:                else {
                    350:                    addr = (db_expr_t) db_dot;
                    351:                    have_addr = FALSE;
                    352:                }
                    353:                t = db_read_token();
                    354:                if (t == tCOMMA) {
                    355:                    if (!db_expression(&count)) {
                    356:                        db_printf("Count missing after ','\n");
                    357:                        db_flush_lex();
                    358:                        return;
                    359:                    }
                    360:                }
                    361:                else {
                    362:                    db_unread_token(t);
                    363:                    count = -1;
                    364:                }
                    365:            }
                    366:        }
                    367:        if (cmd != 0) {
                    368:            /*
                    369:             * Execute the command.
                    370:             */
                    371:            (*cmd->fcn)(addr, have_addr, count, modifp);
                    372: 
                    373:            if (cmd->flag & CS_SET_DOT) {
                    374:                /*
                    375:                 * If command changes dot, set dot to
                    376:                 * previous address displayed (if 'ed' style).
                    377:                 */
                    378:                if (db_ed_style) {
                    379:                    db_dot = db_prev;
                    380:                }
                    381:                else {
                    382:                    db_dot = db_next;
                    383:                }
                    384:            }
                    385:            else {
                    386:                /*
                    387:                 * If command does not change dot,
                    388:                 * set 'next' location to be the same.
                    389:                 */
                    390:                db_next = db_dot;
                    391:            }
                    392:        }
                    393:        *last_cmdp = cmd;
                    394:        *last_countp = count;
                    395:        strcpy(last_modifp, modifp);
                    396: }
                    397: 
                    398: void
                    399: db_command_list(
                    400:        struct db_command       **last_cmdp,    /* IN_OUT */
                    401:        db_expr_t               *last_countp,   /* IN_OUT */
                    402:        char                    *last_modifp,   /* IN_OUT */
                    403:        struct db_command       *cmd_table)
                    404: {
                    405:        do {
                    406:            db_command(last_cmdp, last_countp, last_modifp, cmd_table);
                    407:            db_skip_to_eol();
                    408:        } while (db_read_token() == tSEMI_COLON && db_cmd_loop_done == 0);
                    409: }
                    410: 
                    411: 
                    412: extern void    db_system_stats(void);
                    413: 
                    414: #if     XKMACHKERNEL
                    415: extern void     db_show_net_memory(void);
                    416: 
                    417: struct db_command db_show_net_cmds[] = {
                    418:         { "memory",     (db_func)db_show_net_memory,            0,      0 },
                    419: };
                    420: #endif /* XKMACHKERNEL */
                    421: 
                    422: #if    DIPC
                    423: extern void    db_dipc_stats(void), db_dipc_memory(void),
                    424:                db_dipc_port_deads(void), db_dipc_port_table(void),
                    425:                db_dipc_msg_progress(void), db_dipc_special_ports(void),
                    426:                db_dipc_port_table_proxies(void),
                    427:                db_dipc_port_table_principals(void), db_dipc_port_get(void);
                    428: 
                    429: extern void    db_show_kkt_handle(void), db_show_kkt_request(void),
                    430:                db_show_kkt_channel(void), db_show_kkt(void),
                    431:                db_show_kkt_node_map(void);
                    432: #if    PARAGON860
                    433: extern void    db_show_kkt_transmit(void), db_show_kkt_transport(void);
                    434: #endif /* PARAGON860 */
                    435: #if    NORMA_SCSI
                    436: extern void    db_show_kkt_node(void), db_show_kkt_msg(void),
                    437:                db_show_kkt_event(void);
                    438: #endif /* NORMA_SCSI */
                    439: 
                    440: struct db_command db_dipc_port_cmds[] = {
                    441:        { "dead",       (db_func)db_dipc_port_deads,            0,      0 },
                    442:        { "principals", (db_func)db_dipc_port_table_principals, 0,      0 },
                    443:        { "proxies",    (db_func)db_dipc_port_table_proxies,    0,      0 },
                    444:        { "special",    (db_func)db_dipc_special_ports,         0,      0 },
                    445:        { "table",      (db_func)db_dipc_port_table,            0,      0 },
                    446:        { "uid",        (db_func)db_dipc_port_get,              0,      0 },
                    447:        { (char *)0 }
                    448: };
                    449: 
                    450: struct db_command db_dipc_cmds[] = {
                    451:        { "port",       0,                                      0,      db_dipc_port_cmds },
                    452:        { "memory",     (db_func)db_dipc_memory,                0,      0 },
                    453:        { "message_progress",(db_func)db_dipc_msg_progress,     0,      0 },
                    454:        { "mp",         (db_func)db_dipc_msg_progress,          0,      0 },
                    455:        { "stats",      (db_func)db_dipc_stats,                 0,      0 },
                    456:        { (char *)0 }
                    457: };
                    458: 
                    459: struct db_command db_show_kkt_cmds[] = {
                    460:        { "handle",     (db_func)db_show_kkt_handle,            0,      0 },
                    461:        { "request",    (db_func)db_show_kkt_request,           0,      0 },
                    462:        { "channel",    (db_func)db_show_kkt_channel,           0,      0 },
                    463:        { "stats",      (db_func)db_show_kkt,                   0,      0 },
                    464:        { "map",        (db_func)db_show_kkt_node_map,          0,      0 },
                    465: #if    PARAGON860
                    466:        { "transmit",   (db_func)db_show_kkt_transmit,          0,      0 },
                    467:        { "transport",  (db_func)db_show_kkt_transport,         0,      0 },
                    468: #endif /* PARAGON860 */
                    469: #if    NORMA_SCSI
                    470:        { "node",       (db_func)db_show_kkt_node,              0,      0 },
                    471:        { "msg",        (db_func)db_show_kkt_msg,               0,      0 },
                    472:        { "event",      (db_func)db_show_kkt_event,             0,      0 },
                    473: #endif /* NORMA_SCSI */
                    474:        { (char *)0 }
                    475: };
                    476: #endif /*DIPC*/
                    477: 
                    478: struct db_command db_show_all_cmds[] = {
                    479: #if    USLOCK_DEBUG
                    480:        { "slocks",     (db_func) db_show_all_slocks,           0,      0 },
                    481: #endif /* USLOCK_DEBUG */
                    482: #if    DIPC_TIMER
                    483:        { "timers",     (db_func)db_timer_print,                0,      0 },
                    484: #endif /* DIPC_TIMER */
                    485:        { "acts",       db_show_all_acts,                       0,      0 },
                    486:        { "spaces",     db_show_all_spaces,                     0,      0 },
                    487:        { "tasks",      db_show_all_acts,                       0,      0 },
                    488:        /* temporary alias for sanity preservation */
                    489:        { "threads",    db_show_all_acts,                       0,      0 },
                    490:        { "zones",      db_show_all_zones,                      0,      0 },
                    491:        { "vmtask",     db_show_all_task_vm,                    0,      0 },
                    492:        { (char *)0 }
                    493: };
                    494: 
                    495: /* XXX */
                    496: 
                    497: extern void            db_show_thread_log(void);
                    498: extern void            db_show_one_lock(lock_t*);
                    499: extern void            db_show_etap_log(db_expr_t, int, db_expr_t, char *);
                    500: 
                    501: struct db_command db_show_cmds[] = {
                    502:        { "all",        0,                              0,      db_show_all_cmds },
                    503: #if    DIPC
                    504:        { "dipc",       0,                              0,      db_dipc_cmds },
                    505:        { "kkt",        0,                              0,      db_show_kkt_cmds },
                    506: #endif /* DIPC */
                    507: #if    XKMACHKERNEL
                    508:        { "net",        0,                              0,      db_show_net_cmds },
                    509: #endif /* XKMACHKERNEL */
                    510:        { "registers",  db_show_regs,                   0,      0 },
                    511:        { "variables",  (db_func) db_show_variable,     CS_OWN, 0 },
                    512:        { "breaks",     (db_func) db_listbreak_cmd,     0,      0 },
                    513:        { "watches",    (db_func) db_listwatch_cmd,     0,      0 },
                    514:        { "task",       db_show_one_task,               0,      0 },
                    515:        { "act",        db_show_one_act,                0,      0 },
                    516:        { "shuttle",    db_show_shuttle,                0,      0 },
                    517: #if 0
                    518:        { "thread",     db_show_one_thread,             0,      0 },
                    519: #endif
                    520:        { "vmtask",     db_show_one_task_vm,            0,      0 },
                    521:        { "macro",      (db_func) db_show_macro,        CS_OWN, 0 },
                    522:        { "runq",       (db_func) db_show_runq,         0,      0 },
                    523:        { "map",        (db_func) vm_map_print,         0,      0 },
                    524:        { "object",     (db_func) vm_object_print,      0,      0 },
                    525:        { "page",       (db_func) vm_page_print,        0,      0 },
                    526:        { "copy",       (db_func) vm_map_copy_print,    0,      0 },
                    527:        { "port",       (db_func) ipc_port_print,       0,      0 },
                    528:        { "pset",       (db_func) ipc_pset_print,       0,      0 },
                    529:        { "kmsg",       (db_func) ipc_kmsg_print,       0,      0 },
                    530:        { "msg",        (db_func) ipc_msg_print,        0,      0 },
                    531:        { "ipc_port",   db_show_port_id,                0,      0 },
                    532:        { "lock",       (db_func)db_show_one_lock,      0,      0 },
                    533: #if    NORMA_VM
                    534:        { "xmm_obj",    (db_func) xmm_obj_print,        0,      0 },
                    535:        { "xmm_reply",  (db_func) xmm_reply_print,      0,      0 },
                    536: #endif /* NORMA_VM */
                    537: #if    TRACE_BUFFER
                    538:        { "tr",         db_show_tr,                     0,      0 },
                    539: #endif /* TRACE_BUFFER */
                    540:        { "space",      db_show_one_space,              0,      0 },
                    541:        { "system",     (db_func) db_system_stats,      0,      0 },
                    542: #if    DIPC_TIMER
                    543:        { "timer",      (db_func)db_show_one_timer,     0,      0 },
                    544: #endif /* DIPC_TIMER */
                    545:        { "zone",       db_show_one_zone,               0,      0 },
                    546:        { "simple_lock", db_show_one_simple_lock,       0,      0 },
                    547: #if !NORMA_IPC
                    548:        { "mutex",      db_show_one_mutex,              0,      0 },
                    549: #endif /* !NORMA_IPC */
                    550:        { "thread_log", (db_func)db_show_thread_log,    0,      0 },
                    551:        { "subsystem",  db_show_subsystem,              0,      0 },
                    552:        { "shuttle",    db_show_shuttle,                0,      0 },
                    553:        { "etap_log",   db_show_etap_log,               0,      0 },
                    554:        { (char *)0, }
                    555: };
                    556: 
                    557: #if    NCPUS > 1
                    558: #define        db_switch_cpu kdb_on
                    559: extern void    db_switch_cpu(int);
                    560: #endif /* NCPUS > 1 */
                    561: 
                    562: struct db_command db_command_table[] = {
                    563: #if DB_MACHINE_COMMANDS
                    564: 
                    565: /* this must be the first entry, if it exists */
                    566:        { "machine",    0,                              0,                      0 },
                    567: #endif
                    568:        { "print",      (db_func) db_print_cmd,         CS_OWN,                 0 },
                    569:        { "examine",    db_examine_cmd,                 CS_MORE|CS_SET_DOT,     0 },
                    570:        { "x",          db_examine_cmd,                 CS_MORE|CS_SET_DOT,     0 },
                    571:        { "xf",         db_examine_forward,             CS_SET_DOT,             0 },
                    572:        { "xb",         db_examine_backward,            CS_SET_DOT,             0 },
                    573:        { "search",     (db_func) db_search_cmd,        CS_OWN|CS_SET_DOT,      0 },
                    574:        { "set",        (db_func) db_set_cmd,           CS_OWN,                 0 },
                    575:        { "write",      db_write_cmd,                   CS_MORE|CS_SET_DOT,     0 },
                    576:        { "w",          db_write_cmd,                   CS_MORE|CS_SET_DOT,     0 },
                    577:        { "delete",     (db_func) db_delete_cmd,        CS_OWN,                 0 },
                    578:        { "d",          (db_func) db_delete_cmd,        CS_OWN,                 0 },
                    579:        { "break",      db_breakpoint_cmd,              CS_MORE,                0 },
                    580:        { "dwatch",     db_deletewatch_cmd,             CS_MORE,                0 },
                    581:        { "watch",      db_watchpoint_cmd,              CS_MORE,                0 },
                    582:        { "step",       db_single_step_cmd,             0,                      0 },
                    583:        { "s",          db_single_step_cmd,             0,                      0 },
                    584:        { "continue",   db_continue_cmd,                0,                      0 },
                    585:        { "c",          db_continue_cmd,                0,                      0 },
                    586:        { "gdb",        db_continue_gdb,                0,                      0 },
                    587:        { "until",      db_trace_until_call_cmd,        0,                      0 },
                    588: 
                    589:        /* As per request of DNoveck, CR1550, leave this disabled       */
                    590: #if 0  /* until CR1440 is fixed, to avoid toe-stubbing                 */
                    591:        { "next",       db_trace_until_matching_cmd,    0,                      0 },
                    592: #endif
                    593:        { "match",      db_trace_until_matching_cmd,    0       ,               0 },
                    594:        { "trace",      db_stack_trace_cmd,             0,                      0 },
                    595:        { "cond",       (db_func) db_cond_cmd,          CS_OWN,                 0 },
                    596:        { "call",       (db_func) db_fncall,            CS_OWN,                 0 },
                    597:        { "macro",      (db_func) db_def_macro_cmd,     CS_OWN,                 0 },
                    598:        { "dmacro",     (db_func) db_del_macro_cmd,     CS_OWN,                 0 },
                    599:        { "show",       0,                              0,                      db_show_cmds },
                    600: #if    NCPUS > 1
                    601:        { "cpu",        (db_func) db_switch_cpu,        0,                      0 },
                    602: #endif /* NCPUS > 1 */
                    603:        { "reboot",     (db_func) db_reboot,            0,                      0 },
                    604: #if defined(__ppc__)
                    605:        { "lt",         db_low_trace,                   CS_MORE|CS_SET_DOT,     0 },
                    606:        { "dl",         db_display_long,                CS_MORE|CS_SET_DOT,     0 },
                    607:        { "dr",         db_display_real,                CS_MORE|CS_SET_DOT,     0 },
                    608:        { "dv",         db_display_virtual,             CS_MORE|CS_SET_DOT,     0 },
                    609:        { "dm",         db_display_mappings,    CS_MORE|CS_SET_DOT,     0 },
                    610:        { "dp",         db_display_phys,                CS_MORE|CS_SET_DOT,     0 },
                    611:        { "ds",         db_display_save,                CS_MORE|CS_SET_DOT,     0 },
                    612:        { "dx",         db_display_xregs,               CS_MORE|CS_SET_DOT,     0 },
                    613: #endif
                    614:        { (char *)0, }
                    615: };
                    616: 
                    617: /* this function should be called to install the machine dependent
                    618:    commands. It should be called before the debugger is enabled  */
                    619: void db_machine_commands_install(struct db_command *ptr)
                    620: {
                    621:   db_command_table[0].more = ptr;
                    622:   return;
                    623: }
                    624: 
                    625: 
                    626: struct db_command      *db_last_command = 0;
                    627: db_expr_t              db_last_count = 0;
                    628: char                   db_last_modifier[TOK_STRING_SIZE] = { '\0' };
                    629: 
                    630: void
                    631: db_help_cmd(void)
                    632: {
                    633:        struct db_command *cmd = db_command_table;
                    634: 
                    635:        while (cmd->name != 0) {
                    636:            db_printf("%-12s", cmd->name);
                    637:            db_end_line();
                    638:            cmd++;
                    639:        }
                    640: }
                    641: 
                    642: int    (*ddb_display)(void);
                    643: 
                    644: void
                    645: db_command_loop(void)
                    646: {
                    647:        jmp_buf_t db_jmpbuf;
                    648:        jmp_buf_t *prev = db_recover;
                    649:        extern int db_output_line;
                    650:        extern int db_macro_level;
                    651:        extern int db_indent;
                    652: 
                    653:        /*
                    654:         * Initialize 'prev' and 'next' to dot.
                    655:         */
                    656:        db_prev = db_dot;
                    657:        db_next = db_dot;
                    658: 
                    659:        if (ddb_display)
                    660:                (*ddb_display)();
                    661: 
                    662:        db_cmd_loop_done = 0;
                    663:        while (!db_cmd_loop_done) {
                    664:            (void) _setjmp(db_recover = &db_jmpbuf);
                    665:            db_macro_level = 0;
                    666:            if (db_print_position() != 0)
                    667:                db_printf("\n");
                    668:            db_output_line = 0;
                    669:            db_indent = 0;
                    670:            db_reset_more();
                    671:            db_output_prompt();
                    672: 
                    673:            (void) db_read_line("!!");
                    674:            db_command_list(&db_last_command, &db_last_count,
                    675:                            db_last_modifier, db_command_table);
                    676:        }
                    677: 
                    678:        db_recover = prev;
                    679: }
                    680: 
                    681: boolean_t
                    682: db_exec_cmd_nest(
                    683:        char    *cmd,
                    684:        int     size)
                    685: {
                    686:        struct db_lex_context lex_context;
                    687: 
                    688:        db_cmd_loop_done = 0;
                    689:        if (cmd) {
                    690:            db_save_lex_context(&lex_context);
                    691:            db_switch_input(cmd, size);
                    692:        }
                    693:        db_command_list(&db_last_command, &db_last_count,
                    694:                        db_last_modifier, db_command_table);
                    695:        if (cmd)
                    696:            db_restore_lex_context(&lex_context);
                    697:        return(db_cmd_loop_done == 0);
                    698: }
                    699: 
                    700: void
                    701: db_error(char *s)
                    702: {
                    703:        extern int db_macro_level;
                    704: 
                    705: #if defined(__alpha)
                    706: #  if KDEBUG
                    707:        extern boolean_t kdebug_mode;
                    708:        if (kdebug_mode) {
                    709:                if (s) kprintf(DBG_DEBUG, s);
                    710:                return;
                    711:        }
                    712: #  endif /* KDEBUG */
                    713: #endif /* defined(__alpha) */
                    714: 
                    715:        db_macro_level = 0;
                    716:        if (db_recover) {
                    717:            if (s > (char *)1)
                    718:                db_printf(s);
                    719:            db_flush_lex();
                    720:            _longjmp(db_recover, (s == (char *)1) ? 2 : 1);
                    721:        }
                    722:        else
                    723:        {
                    724:            if (s > (char *)1)
                    725:                db_printf(s);
                    726:            panic("db_error");
                    727:        }
                    728: }
                    729: 
                    730: 
                    731: /*
                    732:  * Call random function:
                    733:  * !expr(arg,arg,arg)
                    734:  */
                    735: void
                    736: db_fncall(void)
                    737: {
                    738:        db_expr_t       fn_addr;
                    739: #define        MAXARGS         11
                    740:        db_expr_t       args[MAXARGS];
                    741:        int             nargs = 0;
                    742:        db_expr_t       retval;
                    743:        db_expr_t       (*func)(db_expr_t, ...);
                    744:        int             t;
                    745: 
                    746:        if (!db_expression(&fn_addr)) {
                    747:            db_printf("Bad function \"%s\"\n", db_tok_string);
                    748:            db_flush_lex();
                    749:            return;
                    750:        }
                    751:        func = (db_expr_t (*) (db_expr_t, ...)) fn_addr;
                    752: 
                    753:        t = db_read_token();
                    754:        if (t == tLPAREN) {
                    755:            if (db_expression(&args[0])) {
                    756:                nargs++;
                    757:                while ((t = db_read_token()) == tCOMMA) {
                    758:                    if (nargs == MAXARGS) {
                    759:                        db_printf("Too many arguments\n");
                    760:                        db_flush_lex();
                    761:                        return;
                    762:                    }
                    763:                    if (!db_expression(&args[nargs])) {
                    764:                        db_printf("Argument missing\n");
                    765:                        db_flush_lex();
                    766:                        return;
                    767:                    }
                    768:                    nargs++;
                    769:                }
                    770:                db_unread_token(t);
                    771:            }
                    772:            if (db_read_token() != tRPAREN) {
                    773:                db_printf("?\n");
                    774:                db_flush_lex();
                    775:                return;
                    776:            }
                    777:        }
                    778:        while (nargs < MAXARGS) {
                    779:            args[nargs++] = 0;
                    780:        }
                    781: 
                    782:        retval = (*func)(args[0], args[1], args[2], args[3], args[4],
                    783:                         args[5], args[6], args[7], args[8], args[9] );
                    784:        db_printf(" %#n\n", retval);
                    785: }
                    786: 
                    787: boolean_t
                    788: db_option(
                    789:        char    *modif,
                    790:        int     option)
                    791: {
                    792:        register char *p;
                    793: 
                    794:        for (p = modif; *p; p++)
                    795:            if (*p == option)
                    796:                return(TRUE);
                    797:        return(FALSE);
                    798: }

unix.superglobalmegacorp.com

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