stevel@tonic-gate | 7c478bd | 2005-06-14 00:00:00 -0700 | [diff] [blame] | 1 | /* |
| 2 | * CDDL HEADER START |
| 3 | * |
| 4 | * The contents of this file are subject to the terms of the |
af | 8a6a72f | 2006-12-19 01:50:12 -0800 | [diff] [blame] | 5 | * Common Development and Distribution License (the "License"). |
| 6 | * You may not use this file except in compliance with the License. |
stevel@tonic-gate | 7c478bd | 2005-06-14 00:00:00 -0700 | [diff] [blame] | 7 | * |
| 8 | * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE |
| 9 | * or http://www.opensolaris.org/os/licensing. |
| 10 | * See the License for the specific language governing permissions |
| 11 | * and limitations under the License. |
| 12 | * |
| 13 | * When distributing Covered Code, include this CDDL HEADER in each |
| 14 | * file and include the License file at usr/src/OPENSOLARIS.LICENSE. |
| 15 | * If applicable, add the following below this CDDL HEADER, with the |
| 16 | * fields enclosed by brackets "[]" replaced with your own identifying |
| 17 | * information: Portions Copyright [yyyy] [name of copyright owner] |
| 18 | * |
| 19 | * CDDL HEADER END |
| 20 | */ |
| 21 | /* |
af | 8a6a72f | 2006-12-19 01:50:12 -0800 | [diff] [blame] | 22 | * Copyright 2006 Sun Microsystems, Inc. All rights reserved. |
stevel@tonic-gate | 7c478bd | 2005-06-14 00:00:00 -0700 | [diff] [blame] | 23 | * Use is subject to license terms. |
| 24 | */ |
| 25 | |
| 26 | #pragma ident "%Z%%M% %I% %E% SMI" |
| 27 | |
| 28 | /* |
| 29 | * Utility routines to manage debugger frames and commands. A debugger frame |
| 30 | * is used by each invocation of mdb_run() (the main parsing loop) to manage |
| 31 | * its state. Refer to the comments in mdb.c for more information on frames. |
| 32 | * Each frame has a list of commands (that is, a dcmd, argument list, and |
| 33 | * optional address list) that represent a pipeline after it has been parsed. |
| 34 | */ |
| 35 | |
| 36 | #include <mdb/mdb_debug.h> |
| 37 | #include <mdb/mdb_frame.h> |
| 38 | #include <mdb/mdb_modapi.h> |
| 39 | #include <mdb/mdb_err.h> |
| 40 | #include <mdb/mdb_lex.h> |
| 41 | #include <mdb/mdb_io.h> |
| 42 | #include <mdb/mdb.h> |
| 43 | |
| 44 | mdb_cmd_t * |
| 45 | mdb_cmd_create(mdb_idcmd_t *idcp, mdb_argvec_t *argv) |
| 46 | { |
| 47 | mdb_cmd_t *cp = mdb_zalloc(sizeof (mdb_cmd_t), UM_NOSLEEP); |
| 48 | |
| 49 | if (cp == NULL) { |
| 50 | warn("failed to allocate memory for command"); |
| 51 | longjmp(mdb.m_frame->f_pcb, MDB_ERR_NOMEM); |
| 52 | } |
| 53 | |
| 54 | mdb_list_append(&mdb.m_frame->f_cmds, cp); |
| 55 | mdb_argvec_copy(&cp->c_argv, argv); |
| 56 | mdb_argvec_zero(argv); |
| 57 | cp->c_dcmd = idcp; |
| 58 | |
| 59 | return (cp); |
| 60 | } |
| 61 | |
| 62 | void |
| 63 | mdb_cmd_destroy(mdb_cmd_t *cp) |
| 64 | { |
| 65 | mdb_addrvec_destroy(&cp->c_addrv); |
| 66 | mdb_argvec_destroy(&cp->c_argv); |
| 67 | mdb_vcb_purge(cp->c_vcbs); |
| 68 | mdb_free(cp, sizeof (mdb_cmd_t)); |
| 69 | } |
| 70 | |
| 71 | void |
| 72 | mdb_cmd_reset(mdb_cmd_t *cp) |
| 73 | { |
| 74 | mdb_addrvec_destroy(&cp->c_addrv); |
| 75 | mdb_vcb_purge(cp->c_vcbs); |
| 76 | cp->c_vcbs = NULL; |
| 77 | } |
| 78 | |
| 79 | void |
| 80 | mdb_frame_reset(mdb_frame_t *fp) |
| 81 | { |
| 82 | mdb_cmd_t *cp; |
| 83 | |
| 84 | while ((cp = mdb_list_next(&fp->f_cmds)) != NULL) { |
| 85 | mdb_list_delete(&fp->f_cmds, cp); |
| 86 | mdb_cmd_destroy(cp); |
| 87 | } |
| 88 | fp->f_cp = NULL; |
| 89 | fp->f_pcmd = NULL; |
| 90 | |
| 91 | while (mdb_iob_stack_size(&fp->f_ostk) != 0) { |
| 92 | mdb_iob_destroy(mdb.m_out); |
| 93 | mdb.m_out = mdb_iob_stack_pop(&fp->f_ostk); |
| 94 | } |
| 95 | |
| 96 | mdb_wcb_purge(&fp->f_wcbs); |
| 97 | mdb_recycle(&fp->f_mblks); |
| 98 | } |
| 99 | |
| 100 | void |
| 101 | mdb_frame_push(mdb_frame_t *fp) |
| 102 | { |
| 103 | mdb_intr_disable(); |
| 104 | |
| 105 | if (mdb.m_fmark == NULL) |
| 106 | mdb.m_fmark = fp; |
| 107 | |
| 108 | mdb_lex_state_save(mdb.m_frame->f_lstate); |
| 109 | |
| 110 | bzero(fp, sizeof (mdb_frame_t)); |
| 111 | mdb_lex_state_create(fp); |
| 112 | mdb_list_append(&mdb.m_flist, fp); |
| 113 | |
| 114 | fp->f_flags = mdb.m_flags & MDB_FL_VOLATILE; |
| 115 | fp->f_pcmd = mdb.m_frame->f_pcmd; |
| 116 | fp->f_id = mdb.m_fid++; |
| 117 | mdb.m_frame->f_dot = mdb_nv_get_value(mdb.m_dot); |
| 118 | |
| 119 | mdb.m_frame = fp; |
| 120 | mdb.m_depth++; |
| 121 | |
| 122 | mdb_dprintf(MDB_DBG_DSTK, "push frame <%u> mark=%p in=%s out=%s\n", |
| 123 | fp->f_id, (void *)mdb.m_fmark, |
| 124 | mdb_iob_name(mdb.m_in), mdb_iob_name(mdb.m_out)); |
| 125 | |
| 126 | mdb_intr_enable(); |
| 127 | } |
| 128 | |
| 129 | void |
| 130 | mdb_frame_pop(mdb_frame_t *fp, int err) |
| 131 | { |
| 132 | mdb_intr_disable(); |
| 133 | |
| 134 | ASSERT(mdb_iob_stack_size(&fp->f_istk) == 0); |
| 135 | ASSERT(mdb_iob_stack_size(&fp->f_ostk) == 0); |
| 136 | ASSERT(mdb_list_next(&fp->f_cmds) == NULL); |
| 137 | ASSERT(fp->f_mblks == NULL); |
| 138 | ASSERT(fp->f_wcbs == NULL); |
| 139 | |
| 140 | mdb_dprintf(MDB_DBG_DSTK, "pop frame <%u> status=%s\n", |
| 141 | fp->f_id, mdb_err2str(err)); |
| 142 | |
| 143 | if (mdb.m_frame == fp) { |
| 144 | mdb.m_flags &= ~MDB_FL_VOLATILE; |
| 145 | mdb.m_flags |= fp->f_flags; |
| 146 | mdb_frame_switch(mdb_list_prev(fp)); |
| 147 | } |
| 148 | |
| 149 | if (mdb.m_fmark == fp) |
| 150 | mdb.m_fmark = NULL; |
| 151 | |
| 152 | mdb_lex_state_destroy(fp); |
| 153 | |
| 154 | mdb_list_delete(&mdb.m_flist, fp); |
| 155 | ASSERT(mdb.m_depth != 0); |
| 156 | mdb.m_depth--; |
| 157 | |
| 158 | mdb_intr_enable(); |
| 159 | } |
| 160 | |
| 161 | void |
| 162 | mdb_frame_switch(mdb_frame_t *frame) |
| 163 | { |
| 164 | mdb_lex_state_save(mdb.m_frame->f_lstate); |
| 165 | mdb.m_frame->f_dot = mdb_nv_get_value(mdb.m_dot); |
| 166 | mdb.m_frame = frame; |
| 167 | mdb_lex_state_restore(mdb.m_frame->f_lstate); |
| 168 | mdb_dprintf(MDB_DBG_DSTK, "switch to frame <%u>\n", mdb.m_frame->f_id); |
| 169 | |
| 170 | mdb_nv_set_value(mdb.m_dot, frame->f_dot); |
| 171 | } |
af | 8a6a72f | 2006-12-19 01:50:12 -0800 | [diff] [blame] | 172 | |
| 173 | void |
| 174 | mdb_frame_set_pipe(mdb_frame_t *frame) |
| 175 | { |
| 176 | frame->pipe = TRUE; |
| 177 | } |
| 178 | |
| 179 | void |
| 180 | mdb_frame_clear_pipe(mdb_frame_t *frame) |
| 181 | { |
| 182 | frame->pipe = FALSE; |
| 183 | } |
| 184 | |
| 185 | mdb_frame_t * |
| 186 | mdb_frame_pipe(void) |
| 187 | { |
| 188 | mdb_frame_t *frame = mdb_list_prev(mdb.m_frame); |
| 189 | |
| 190 | while (frame && frame->pipe == FALSE) |
| 191 | frame = mdb_list_prev(frame); |
| 192 | |
| 193 | return (frame); |
| 194 | } |