/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* * Utility routines to manage debugger frames and commands. A debugger frame * is used by each invocation of mdb_run() (the main parsing loop) to manage * its state. Refer to the comments in mdb.c for more information on frames. * Each frame has a list of commands (that is, a dcmd, argument list, and * optional address list) that represent a pipeline after it has been parsed. */ #include #include #include #include #include #include #include mdb_cmd_t * mdb_cmd_create(mdb_idcmd_t *idcp, mdb_argvec_t *argv) { mdb_cmd_t *cp = mdb_zalloc(sizeof (mdb_cmd_t), UM_NOSLEEP); if (cp == NULL) { warn("failed to allocate memory for command"); longjmp(mdb.m_frame->f_pcb, MDB_ERR_NOMEM); } mdb_list_append(&mdb.m_frame->f_cmds, cp); mdb_argvec_copy(&cp->c_argv, argv); mdb_argvec_zero(argv); cp->c_dcmd = idcp; return (cp); } void mdb_cmd_destroy(mdb_cmd_t *cp) { mdb_addrvec_destroy(&cp->c_addrv); mdb_argvec_destroy(&cp->c_argv); mdb_vcb_purge(cp->c_vcbs); mdb_free(cp, sizeof (mdb_cmd_t)); } void mdb_cmd_reset(mdb_cmd_t *cp) { mdb_addrvec_destroy(&cp->c_addrv); mdb_vcb_purge(cp->c_vcbs); cp->c_vcbs = NULL; } void mdb_frame_reset(mdb_frame_t *fp) { mdb_cmd_t *cp; while ((cp = mdb_list_next(&fp->f_cmds)) != NULL) { mdb_list_delete(&fp->f_cmds, cp); mdb_cmd_destroy(cp); } fp->f_cp = NULL; fp->f_pcmd = NULL; while (mdb_iob_stack_size(&fp->f_ostk) != 0) { mdb_iob_destroy(mdb.m_out); mdb.m_out = mdb_iob_stack_pop(&fp->f_ostk); } mdb_wcb_purge(&fp->f_wcbs); mdb_recycle(&fp->f_mblks); } void mdb_frame_push(mdb_frame_t *fp) { mdb_intr_disable(); if (mdb.m_fmark == NULL) mdb.m_fmark = fp; mdb_lex_state_save(mdb.m_frame->f_lstate); bzero(fp, sizeof (mdb_frame_t)); mdb_lex_state_create(fp); mdb_list_append(&mdb.m_flist, fp); fp->f_flags = mdb.m_flags & MDB_FL_VOLATILE; fp->f_pcmd = mdb.m_frame->f_pcmd; fp->f_id = mdb.m_fid++; mdb.m_frame->f_dot = mdb_nv_get_value(mdb.m_dot); mdb.m_frame = fp; mdb.m_depth++; mdb_dprintf(MDB_DBG_DSTK, "push frame <%u> mark=%p in=%s out=%s\n", fp->f_id, (void *)mdb.m_fmark, mdb_iob_name(mdb.m_in), mdb_iob_name(mdb.m_out)); mdb_intr_enable(); } void mdb_frame_pop(mdb_frame_t *fp, int err) { mdb_intr_disable(); ASSERT(mdb_iob_stack_size(&fp->f_istk) == 0); ASSERT(mdb_iob_stack_size(&fp->f_ostk) == 0); ASSERT(mdb_list_next(&fp->f_cmds) == NULL); ASSERT(fp->f_mblks == NULL); ASSERT(fp->f_wcbs == NULL); mdb_dprintf(MDB_DBG_DSTK, "pop frame <%u> status=%s\n", fp->f_id, mdb_err2str(err)); if (mdb.m_frame == fp) { mdb.m_flags &= ~MDB_FL_VOLATILE; mdb.m_flags |= fp->f_flags; mdb_frame_switch(mdb_list_prev(fp)); } if (mdb.m_fmark == fp) mdb.m_fmark = NULL; mdb_lex_state_destroy(fp); mdb_list_delete(&mdb.m_flist, fp); ASSERT(mdb.m_depth != 0); mdb.m_depth--; mdb_intr_enable(); } void mdb_frame_switch(mdb_frame_t *frame) { mdb_lex_state_save(mdb.m_frame->f_lstate); mdb.m_frame->f_dot = mdb_nv_get_value(mdb.m_dot); mdb.m_frame = frame; mdb_lex_state_restore(mdb.m_frame->f_lstate); mdb_dprintf(MDB_DBG_DSTK, "switch to frame <%u>\n", mdb.m_frame->f_id); mdb_nv_set_value(mdb.m_dot, frame->f_dot); } void mdb_frame_set_pipe(mdb_frame_t *frame) { frame->pipe = TRUE; } void mdb_frame_clear_pipe(mdb_frame_t *frame) { frame->pipe = FALSE; } mdb_frame_t * mdb_frame_pipe(void) { mdb_frame_t *frame = mdb_list_prev(mdb.m_frame); while (frame && frame->pipe == FALSE) frame = mdb_list_prev(frame); return (frame); }