blob: 8bd899dd5b81d7621e6804afbf338203a4a595ed [file] [log] [blame]
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -07001/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
af8a6a72f2006-12-19 01:50:12 -08005 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -07007 *
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/*
af8a6a72f2006-12-19 01:50:12 -080022 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -070023 * 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
44mdb_cmd_t *
45mdb_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
62void
63mdb_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
71void
72mdb_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
79void
80mdb_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
100void
101mdb_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
129void
130mdb_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
161void
162mdb_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}
af8a6a72f2006-12-19 01:50:12 -0800172
173void
174mdb_frame_set_pipe(mdb_frame_t *frame)
175{
176 frame->pipe = TRUE;
177}
178
179void
180mdb_frame_clear_pipe(mdb_frame_t *frame)
181{
182 frame->pipe = FALSE;
183}
184
185mdb_frame_t *
186mdb_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}