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