xref: /titanic_41/usr/src/lib/efcode/engine/debug.c (revision 360e6f5e7a29d5950aa1985f56811731715da7e5)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
57c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
67c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
77c478bd9Sstevel@tonic-gate  * with the License.
87c478bd9Sstevel@tonic-gate  *
97c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
107c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
117c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
127c478bd9Sstevel@tonic-gate  * and limitations under the License.
137c478bd9Sstevel@tonic-gate  *
147c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
157c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
167c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
177c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
187c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
197c478bd9Sstevel@tonic-gate  *
207c478bd9Sstevel@tonic-gate  * CDDL HEADER END
217c478bd9Sstevel@tonic-gate  */
227c478bd9Sstevel@tonic-gate /*
23*360e6f5eSmathue  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
247c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
257c478bd9Sstevel@tonic-gate  */
267c478bd9Sstevel@tonic-gate 
277c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
287c478bd9Sstevel@tonic-gate 
297c478bd9Sstevel@tonic-gate #include <stdio.h>
307c478bd9Sstevel@tonic-gate #include <string.h>
317c478bd9Sstevel@tonic-gate #include <stdlib.h>
327c478bd9Sstevel@tonic-gate #include <stdarg.h>
337c478bd9Sstevel@tonic-gate #include <unistd.h>
347c478bd9Sstevel@tonic-gate #include <errno.h>
357c478bd9Sstevel@tonic-gate #include <ctype.h>
367c478bd9Sstevel@tonic-gate 
377c478bd9Sstevel@tonic-gate #include <fcode/private.h>
387c478bd9Sstevel@tonic-gate #include <fcode/log.h>
397c478bd9Sstevel@tonic-gate 
407c478bd9Sstevel@tonic-gate #ifndef DEBUG_LVL
417c478bd9Sstevel@tonic-gate #define	DEBUG_LVL	0
427c478bd9Sstevel@tonic-gate #endif
437c478bd9Sstevel@tonic-gate 
447c478bd9Sstevel@tonic-gate struct bitab {
457c478bd9Sstevel@tonic-gate 	token_t bi_ptr;
467c478bd9Sstevel@tonic-gate 	char *bi_name;
477c478bd9Sstevel@tonic-gate 	int bi_type;
487c478bd9Sstevel@tonic-gate };
497c478bd9Sstevel@tonic-gate 
507c478bd9Sstevel@tonic-gate struct bitab *lookup_builtin(token_t);
517c478bd9Sstevel@tonic-gate 
527c478bd9Sstevel@tonic-gate static int debug_level = DEBUG_LVL;
537c478bd9Sstevel@tonic-gate 
547c478bd9Sstevel@tonic-gate void
set_interpreter_debug_level(long lvl)557c478bd9Sstevel@tonic-gate set_interpreter_debug_level(long lvl)
567c478bd9Sstevel@tonic-gate {
577c478bd9Sstevel@tonic-gate 	debug_level = lvl;
587c478bd9Sstevel@tonic-gate }
597c478bd9Sstevel@tonic-gate 
607c478bd9Sstevel@tonic-gate long
get_interpreter_debug_level(void)617c478bd9Sstevel@tonic-gate get_interpreter_debug_level(void)
627c478bd9Sstevel@tonic-gate {
637c478bd9Sstevel@tonic-gate 	return (debug_level);
647c478bd9Sstevel@tonic-gate }
657c478bd9Sstevel@tonic-gate 
667c478bd9Sstevel@tonic-gate void
output_data_stack(fcode_env_t * env,int msglevel)677c478bd9Sstevel@tonic-gate output_data_stack(fcode_env_t *env, int msglevel)
687c478bd9Sstevel@tonic-gate {
697c478bd9Sstevel@tonic-gate 	int i;
707c478bd9Sstevel@tonic-gate 
717c478bd9Sstevel@tonic-gate 	log_message(msglevel, "( ");
727c478bd9Sstevel@tonic-gate 	if (DS > env->ds0) {
737c478bd9Sstevel@tonic-gate 		for (i = 0; i < (DS - env->ds0); i++)
747c478bd9Sstevel@tonic-gate 			log_message(msglevel, "%llx ",
757c478bd9Sstevel@tonic-gate 			    (uint64_t)(env->ds0[i + 1]));
767c478bd9Sstevel@tonic-gate 	} else
777c478bd9Sstevel@tonic-gate 		log_message(msglevel, "<empty> ");
787c478bd9Sstevel@tonic-gate 	log_message(msglevel, ") ");
797c478bd9Sstevel@tonic-gate }
807c478bd9Sstevel@tonic-gate 
817c478bd9Sstevel@tonic-gate void
output_return_stack(fcode_env_t * env,int show_wa,int msglevel)827c478bd9Sstevel@tonic-gate output_return_stack(fcode_env_t *env, int show_wa, int msglevel)
837c478bd9Sstevel@tonic-gate {
847c478bd9Sstevel@tonic-gate 	int i;
857c478bd9Sstevel@tonic-gate 	int anyout = 0;
867c478bd9Sstevel@tonic-gate 
877c478bd9Sstevel@tonic-gate 	log_message(msglevel, "R:( ");
887c478bd9Sstevel@tonic-gate 	if (show_wa) {
897c478bd9Sstevel@tonic-gate 		log_message(msglevel, "%s ",
907c478bd9Sstevel@tonic-gate 		    acf_backup_search(env, (acf_t)WA));
917c478bd9Sstevel@tonic-gate 		anyout++;
927c478bd9Sstevel@tonic-gate 	}
937c478bd9Sstevel@tonic-gate 	if (IP) {
947c478bd9Sstevel@tonic-gate 		anyout++;
957c478bd9Sstevel@tonic-gate 		log_message(msglevel, "%s ", acf_backup_search(env, IP));
967c478bd9Sstevel@tonic-gate 	}
977c478bd9Sstevel@tonic-gate 	for (i = (RS - env->rs0) - 1; i > 0; i--) {
987c478bd9Sstevel@tonic-gate 		anyout++;
997c478bd9Sstevel@tonic-gate 		log_message(msglevel, "%s ",
1007c478bd9Sstevel@tonic-gate 			    acf_backup_search(env, (acf_t)env->rs0[i+1]));
1017c478bd9Sstevel@tonic-gate 	}
1027c478bd9Sstevel@tonic-gate 	if (!anyout)
1037c478bd9Sstevel@tonic-gate 		log_message(msglevel, "<empty> ");
1047c478bd9Sstevel@tonic-gate 	log_message(msglevel, ") ");
1057c478bd9Sstevel@tonic-gate }
1067c478bd9Sstevel@tonic-gate 
1077c478bd9Sstevel@tonic-gate void
dump_comma(fcode_env_t * env,char * type)1087c478bd9Sstevel@tonic-gate dump_comma(fcode_env_t *env, char *type)
1097c478bd9Sstevel@tonic-gate {
1107c478bd9Sstevel@tonic-gate 	xforth_t d;
1117c478bd9Sstevel@tonic-gate 
1127c478bd9Sstevel@tonic-gate 	if (strcmp(type, "x,") == 0)
1137c478bd9Sstevel@tonic-gate 		d = peek_xforth(env);
1147c478bd9Sstevel@tonic-gate 	else
1157c478bd9Sstevel@tonic-gate 		d = TOS;
1167c478bd9Sstevel@tonic-gate 	log_message(MSG_FC_DEBUG, "%s %p, %llx\n", type, HERE, (uint64_t)d);
1177c478bd9Sstevel@tonic-gate }
1187c478bd9Sstevel@tonic-gate 
1197c478bd9Sstevel@tonic-gate static int ndebug_names;
1207c478bd9Sstevel@tonic-gate #define	MAXDEBUG_NAMES	10
1217c478bd9Sstevel@tonic-gate static char *debug_names[MAXDEBUG_NAMES];
1227c478bd9Sstevel@tonic-gate 
1237c478bd9Sstevel@tonic-gate static int ndebug_acfs;
1247c478bd9Sstevel@tonic-gate #define	MAXDEBUG_ACFS	10
1257c478bd9Sstevel@tonic-gate static acf_t debug_acfs[MAXDEBUG_ACFS];
1267c478bd9Sstevel@tonic-gate 
1277c478bd9Sstevel@tonic-gate void
add_debug_acf(fcode_env_t * env,acf_t acf)1287c478bd9Sstevel@tonic-gate add_debug_acf(fcode_env_t *env, acf_t acf)
1297c478bd9Sstevel@tonic-gate {
1307c478bd9Sstevel@tonic-gate 	int i;
1317c478bd9Sstevel@tonic-gate 
1327c478bd9Sstevel@tonic-gate 	for (i = 0; i < ndebug_acfs; i++)
1337c478bd9Sstevel@tonic-gate 		if (acf == debug_acfs[i])
1347c478bd9Sstevel@tonic-gate 			return;
1357c478bd9Sstevel@tonic-gate 
1367c478bd9Sstevel@tonic-gate 	if (!within_dictionary(env, acf))
1377c478bd9Sstevel@tonic-gate 		log_message(MSG_ERROR, "Can't debug builtin\n");
1387c478bd9Sstevel@tonic-gate 	else if (ndebug_acfs >= MAXDEBUG_ACFS)
1397c478bd9Sstevel@tonic-gate 		log_message(MSG_ERROR, "Too many debug ACF's\n");
1407c478bd9Sstevel@tonic-gate 	else {
1417c478bd9Sstevel@tonic-gate 		debug_acfs[ndebug_acfs++] = acf;
1427c478bd9Sstevel@tonic-gate 		*LINK_TO_FLAGS(ACF_TO_LINK(acf)) |= FLAG_DEBUG;
1437c478bd9Sstevel@tonic-gate 	}
1447c478bd9Sstevel@tonic-gate }
1457c478bd9Sstevel@tonic-gate 
1467c478bd9Sstevel@tonic-gate static void
paren_debug(fcode_env_t * env)1477c478bd9Sstevel@tonic-gate paren_debug(fcode_env_t *env)
1487c478bd9Sstevel@tonic-gate {
1497c478bd9Sstevel@tonic-gate 	acf_t acf;
1507c478bd9Sstevel@tonic-gate 
1517c478bd9Sstevel@tonic-gate 	acf = (acf_t)POP(DS);
1527c478bd9Sstevel@tonic-gate 	if (!within_dictionary(env, acf)) {
1537c478bd9Sstevel@tonic-gate 		log_message(MSG_INFO, "acf: %llx not in dictionary\n",
1547c478bd9Sstevel@tonic-gate 		    (uint64_t)acf);
1557c478bd9Sstevel@tonic-gate 		return;
1567c478bd9Sstevel@tonic-gate 	}
1577c478bd9Sstevel@tonic-gate 	if ((acf_t)_ALIGN(acf, token_t) != acf) {
1587c478bd9Sstevel@tonic-gate 		log_message(MSG_INFO, "acf: %llx not aligned\n",
1597c478bd9Sstevel@tonic-gate 		    (uint64_t)acf);
1607c478bd9Sstevel@tonic-gate 		return;
1617c478bd9Sstevel@tonic-gate 	}
1627c478bd9Sstevel@tonic-gate 	if (*acf != (token_t)(&do_colon)) {
1637c478bd9Sstevel@tonic-gate 		log_message(MSG_INFO, "acf: %llx not a colon-def\n",
1647c478bd9Sstevel@tonic-gate 		    (uint64_t)acf);
1657c478bd9Sstevel@tonic-gate 		return;
1667c478bd9Sstevel@tonic-gate 	}
1677c478bd9Sstevel@tonic-gate 	add_debug_acf(env, acf);
1687c478bd9Sstevel@tonic-gate }
1697c478bd9Sstevel@tonic-gate 
1707c478bd9Sstevel@tonic-gate static void
debug(fcode_env_t * env)1717c478bd9Sstevel@tonic-gate debug(fcode_env_t *env)
1727c478bd9Sstevel@tonic-gate {
1737c478bd9Sstevel@tonic-gate 	fstack_t d;
1747c478bd9Sstevel@tonic-gate 	char *word;
1757c478bd9Sstevel@tonic-gate 	acf_t acf;
1767c478bd9Sstevel@tonic-gate 
1777c478bd9Sstevel@tonic-gate 	parse_word(env);
1787c478bd9Sstevel@tonic-gate 	dollar_find(env);
1797c478bd9Sstevel@tonic-gate 	d = POP(DS);
1807c478bd9Sstevel@tonic-gate 	if (d) {
1817c478bd9Sstevel@tonic-gate 		acf = (acf_t)POP(DS);
1827c478bd9Sstevel@tonic-gate 		add_debug_acf(env, acf);
1837c478bd9Sstevel@tonic-gate 	} else if (ndebug_names >= MAXDEBUG_NAMES) {
1847c478bd9Sstevel@tonic-gate 		log_message(MSG_ERROR, "Too many forward debug words\n");
1857c478bd9Sstevel@tonic-gate 		two_drop(env);
1867c478bd9Sstevel@tonic-gate 	} else {
1877c478bd9Sstevel@tonic-gate 		word = pop_a_duped_string(env, NULL);
1887c478bd9Sstevel@tonic-gate 		log_message(MSG_INFO, "Forward defined word: %s\n", word);
1897c478bd9Sstevel@tonic-gate 		debug_names[ndebug_names++] = word;
1907c478bd9Sstevel@tonic-gate 	}
1917c478bd9Sstevel@tonic-gate }
1927c478bd9Sstevel@tonic-gate 
1937c478bd9Sstevel@tonic-gate /*
1947c478bd9Sstevel@tonic-gate  * Eliminate dups and add vocabulary forth to end if not already on list.
1957c478bd9Sstevel@tonic-gate  */
1967c478bd9Sstevel@tonic-gate static void
order_to_dict_list(fcode_env_t * env,token_t * order[])1977c478bd9Sstevel@tonic-gate order_to_dict_list(fcode_env_t *env, token_t *order[])
1987c478bd9Sstevel@tonic-gate {
1997c478bd9Sstevel@tonic-gate 	int i, j, norder = 0;
2007c478bd9Sstevel@tonic-gate 
2017c478bd9Sstevel@tonic-gate 	if (env->current)
2027c478bd9Sstevel@tonic-gate 		order[norder++] = env->current;
2037c478bd9Sstevel@tonic-gate 	for (i = env->order_depth; i >= 0; i--) {
2047c478bd9Sstevel@tonic-gate 		for (j = 0; j < norder && order[j] != env->order[i]; j++)
2057c478bd9Sstevel@tonic-gate 			;
2067c478bd9Sstevel@tonic-gate 		if (j == norder)
2077c478bd9Sstevel@tonic-gate 			order[norder++] = env->order[i];
2087c478bd9Sstevel@tonic-gate 	}
2097c478bd9Sstevel@tonic-gate 	for (j = 0; j < norder && order[j] != (token_t *)&env->forth_voc_link;
2107c478bd9Sstevel@tonic-gate 	    j++)
2117c478bd9Sstevel@tonic-gate 		;
2127c478bd9Sstevel@tonic-gate 	if (j == norder)
2137c478bd9Sstevel@tonic-gate 		order[norder++] = (token_t *)&env->forth_voc_link;
2147c478bd9Sstevel@tonic-gate 	order[norder] = NULL;
2157c478bd9Sstevel@tonic-gate }
2167c478bd9Sstevel@tonic-gate 
2177c478bd9Sstevel@tonic-gate static acf_t
search_all_dictionaries(fcode_env_t * env,acf_t (* fn)(fcode_env_t *,acf_t,void *),void * arg)2187c478bd9Sstevel@tonic-gate search_all_dictionaries(fcode_env_t *env,
2197c478bd9Sstevel@tonic-gate     acf_t (*fn)(fcode_env_t *, acf_t, void *),
2207c478bd9Sstevel@tonic-gate     void *arg)
2217c478bd9Sstevel@tonic-gate {
2227c478bd9Sstevel@tonic-gate 	token_t *order[MAX_ORDER+1];
2237c478bd9Sstevel@tonic-gate 	int i;
2247c478bd9Sstevel@tonic-gate 	token_t *dptr;
2257c478bd9Sstevel@tonic-gate 	acf_t acf;
2267c478bd9Sstevel@tonic-gate 
2277c478bd9Sstevel@tonic-gate 	order_to_dict_list(env, order);
2287c478bd9Sstevel@tonic-gate 	for (i = 0; (dptr = order[i]) != NULL; i++) {
2297c478bd9Sstevel@tonic-gate 		for (dptr = (token_t *)(*dptr); dptr;
2307c478bd9Sstevel@tonic-gate 		    dptr = (token_t *)(*dptr))
2317c478bd9Sstevel@tonic-gate 			if ((acf = (*fn)(env, LINK_TO_ACF(dptr), arg)) != NULL)
2327c478bd9Sstevel@tonic-gate 				return (acf);
2337c478bd9Sstevel@tonic-gate 	}
2347c478bd9Sstevel@tonic-gate 	return (NULL);
2357c478bd9Sstevel@tonic-gate }
2367c478bd9Sstevel@tonic-gate 
2377c478bd9Sstevel@tonic-gate char *
acf_to_str(acf_t acf)2387c478bd9Sstevel@tonic-gate acf_to_str(acf_t acf)
2397c478bd9Sstevel@tonic-gate {
2407c478bd9Sstevel@tonic-gate 	static char msg[(sizeof (acf) * 2) + 3];
2417c478bd9Sstevel@tonic-gate 
2427c478bd9Sstevel@tonic-gate 	sprintf(msg, "(%08p)", acf);
2437c478bd9Sstevel@tonic-gate 	return (msg);
2447c478bd9Sstevel@tonic-gate }
2457c478bd9Sstevel@tonic-gate 
2467c478bd9Sstevel@tonic-gate char *
get_name_or_acf(token_t * dptr)2477c478bd9Sstevel@tonic-gate get_name_or_acf(token_t *dptr)
2487c478bd9Sstevel@tonic-gate {
2497c478bd9Sstevel@tonic-gate 	char *name;
2507c478bd9Sstevel@tonic-gate 
2517c478bd9Sstevel@tonic-gate 	if ((name = get_name(dptr)) != NULL)
2527c478bd9Sstevel@tonic-gate 		return (name);
2537c478bd9Sstevel@tonic-gate 	return (acf_to_str(LINK_TO_ACF(dptr)));
2547c478bd9Sstevel@tonic-gate }
2557c478bd9Sstevel@tonic-gate 
2567c478bd9Sstevel@tonic-gate static void
output_acf_name(acf_t acf)2577c478bd9Sstevel@tonic-gate output_acf_name(acf_t acf)
2587c478bd9Sstevel@tonic-gate {
2597c478bd9Sstevel@tonic-gate 	char *name;
2607c478bd9Sstevel@tonic-gate 	token_t *dptr;
2617c478bd9Sstevel@tonic-gate 	static int acf_count = 0;
2627c478bd9Sstevel@tonic-gate 
2637c478bd9Sstevel@tonic-gate 	if (acf == NULL) {
2647c478bd9Sstevel@tonic-gate 		if (acf_count)
2657c478bd9Sstevel@tonic-gate 			log_message(MSG_INFO, "\n");
2667c478bd9Sstevel@tonic-gate 		acf_count = 0;
2677c478bd9Sstevel@tonic-gate 		return;
2687c478bd9Sstevel@tonic-gate 	}
2697c478bd9Sstevel@tonic-gate 	dptr = ACF_TO_LINK(acf);
2707c478bd9Sstevel@tonic-gate 	if ((name = get_name(dptr)) == NULL)
2717c478bd9Sstevel@tonic-gate 		name = "<noname>";
2727c478bd9Sstevel@tonic-gate 
2737c478bd9Sstevel@tonic-gate 	log_message(MSG_INFO, "%24s (%08p)", name, acf);
2747c478bd9Sstevel@tonic-gate 	if (++acf_count >= 2) {
2757c478bd9Sstevel@tonic-gate 		log_message(MSG_INFO, "\n");
2767c478bd9Sstevel@tonic-gate 		acf_count = 0;
2777c478bd9Sstevel@tonic-gate 	} else
2787c478bd9Sstevel@tonic-gate 		log_message(MSG_INFO, "    ");
2797c478bd9Sstevel@tonic-gate }
2807c478bd9Sstevel@tonic-gate 
2817c478bd9Sstevel@tonic-gate static void
dot_debug(fcode_env_t * env)2827c478bd9Sstevel@tonic-gate dot_debug(fcode_env_t *env)
2837c478bd9Sstevel@tonic-gate {
2847c478bd9Sstevel@tonic-gate 	int i;
2857c478bd9Sstevel@tonic-gate 	token_t *dptr;
2867c478bd9Sstevel@tonic-gate 
2877c478bd9Sstevel@tonic-gate 	if (ndebug_names == 0)
2887c478bd9Sstevel@tonic-gate 		log_message(MSG_INFO, "No forward debug words\n");
2897c478bd9Sstevel@tonic-gate 	else {
2907c478bd9Sstevel@tonic-gate 		for (i = 0; i < ndebug_names; i++)
2917c478bd9Sstevel@tonic-gate 			log_message(MSG_INFO, "%s Forward\n", debug_names[i]);
2927c478bd9Sstevel@tonic-gate 	}
2937c478bd9Sstevel@tonic-gate 	if (ndebug_acfs == 0)
2947c478bd9Sstevel@tonic-gate 		log_message(MSG_INFO, "No debug words\n");
2957c478bd9Sstevel@tonic-gate 	else {
2967c478bd9Sstevel@tonic-gate 		for (i = 0; i < ndebug_acfs; i++)
2977c478bd9Sstevel@tonic-gate 			log_message(MSG_INFO, "%s\n",
2987c478bd9Sstevel@tonic-gate 			    get_name_or_acf(ACF_TO_LINK(debug_acfs[i])));
2997c478bd9Sstevel@tonic-gate 	}
3007c478bd9Sstevel@tonic-gate }
3017c478bd9Sstevel@tonic-gate 
3027c478bd9Sstevel@tonic-gate static void
do_undebug(fcode_env_t * env,char * name)3037c478bd9Sstevel@tonic-gate do_undebug(fcode_env_t *env, char *name)
3047c478bd9Sstevel@tonic-gate {
3057c478bd9Sstevel@tonic-gate 	int i;
3067c478bd9Sstevel@tonic-gate 
3077c478bd9Sstevel@tonic-gate 	for (i = 0; i < ndebug_names; i++) {
3087c478bd9Sstevel@tonic-gate 		if (strcmp(debug_names[i], name) == 0) {
3097c478bd9Sstevel@tonic-gate 			log_message(MSG_INFO, "Undebugging forward word %s\n",
3107c478bd9Sstevel@tonic-gate 			    name);
3117c478bd9Sstevel@tonic-gate 			FREE(debug_names[i]);
3127c478bd9Sstevel@tonic-gate 			for (i++; i < ndebug_names; i++)
3137c478bd9Sstevel@tonic-gate 				debug_names[i - 1] = debug_names[i];
3147c478bd9Sstevel@tonic-gate 			ndebug_names--;
3157c478bd9Sstevel@tonic-gate 			break;
3167c478bd9Sstevel@tonic-gate 		}
3177c478bd9Sstevel@tonic-gate 	}
3187c478bd9Sstevel@tonic-gate }
3197c478bd9Sstevel@tonic-gate 
3207c478bd9Sstevel@tonic-gate static void
undebug(fcode_env_t * env)3217c478bd9Sstevel@tonic-gate undebug(fcode_env_t *env)
3227c478bd9Sstevel@tonic-gate {
3237c478bd9Sstevel@tonic-gate 	fstack_t d;
3247c478bd9Sstevel@tonic-gate 	acf_t acf;
3257c478bd9Sstevel@tonic-gate 	flag_t *flagp;
3267c478bd9Sstevel@tonic-gate 	char *name;
3277c478bd9Sstevel@tonic-gate 	int i, j;
3287c478bd9Sstevel@tonic-gate 
3297c478bd9Sstevel@tonic-gate 	parse_word(env);
3307c478bd9Sstevel@tonic-gate 	two_dup(env);
3317c478bd9Sstevel@tonic-gate 	dollar_find(env);
3327c478bd9Sstevel@tonic-gate 	d = POP(DS);
3337c478bd9Sstevel@tonic-gate 	if (d) {
3347c478bd9Sstevel@tonic-gate 		acf = (acf_t)POP(DS);
3357c478bd9Sstevel@tonic-gate 		flagp = LINK_TO_FLAGS(ACF_TO_LINK(acf));
3367c478bd9Sstevel@tonic-gate 		if ((*flagp & FLAG_DEBUG) == 0)
3377c478bd9Sstevel@tonic-gate 			log_message(MSG_WARN, "Word not debugged?\n");
3387c478bd9Sstevel@tonic-gate 		else {
3397c478bd9Sstevel@tonic-gate 			log_message(MSG_INFO, "Undebugging acf: %p\n", acf);
3407c478bd9Sstevel@tonic-gate 			*flagp &= ~FLAG_DEBUG;
3417c478bd9Sstevel@tonic-gate 			for (i = 0; i < ndebug_acfs; i++) {
3427c478bd9Sstevel@tonic-gate 				if (debug_acfs[i] == acf) {
3437c478bd9Sstevel@tonic-gate 					for (j = i + 1; j < ndebug_acfs; j++)
3447c478bd9Sstevel@tonic-gate 						debug_acfs[j-1] = debug_acfs[j];
3457c478bd9Sstevel@tonic-gate 					ndebug_acfs--;
3467c478bd9Sstevel@tonic-gate 					break;
3477c478bd9Sstevel@tonic-gate 				}
3487c478bd9Sstevel@tonic-gate 			}
3497c478bd9Sstevel@tonic-gate 		}
3507c478bd9Sstevel@tonic-gate 	} else
3517c478bd9Sstevel@tonic-gate 		two_drop(env);
3527c478bd9Sstevel@tonic-gate 	name = pop_a_string(env, NULL);
3537c478bd9Sstevel@tonic-gate 	do_undebug(env, name);
3547c478bd9Sstevel@tonic-gate }
3557c478bd9Sstevel@tonic-gate 
3567c478bd9Sstevel@tonic-gate int
name_is_debugged(fcode_env_t * env,char * name)3577c478bd9Sstevel@tonic-gate name_is_debugged(fcode_env_t *env, char *name)
3587c478bd9Sstevel@tonic-gate {
3597c478bd9Sstevel@tonic-gate 	int i;
3607c478bd9Sstevel@tonic-gate 
3617c478bd9Sstevel@tonic-gate 	if (ndebug_names <= 0)
3627c478bd9Sstevel@tonic-gate 		return (0);
3637c478bd9Sstevel@tonic-gate 	for (i = 0; i < ndebug_names; i++)
3647c478bd9Sstevel@tonic-gate 		if (strcmp(debug_names[i], name) == 0)
3657c478bd9Sstevel@tonic-gate 			return (1);
3667c478bd9Sstevel@tonic-gate 	return (0);
3677c478bd9Sstevel@tonic-gate }
3687c478bd9Sstevel@tonic-gate 
3697c478bd9Sstevel@tonic-gate /*
3707c478bd9Sstevel@tonic-gate  * This is complicated by being given ACF's to temporary compile words which
3717c478bd9Sstevel@tonic-gate  * don't have a header.
3727c478bd9Sstevel@tonic-gate  */
3737c478bd9Sstevel@tonic-gate int
is_debug_word(fcode_env_t * env,acf_t acf)3747c478bd9Sstevel@tonic-gate is_debug_word(fcode_env_t *env, acf_t acf)
3757c478bd9Sstevel@tonic-gate {
3767c478bd9Sstevel@tonic-gate 	flag_t *flagp;
3777c478bd9Sstevel@tonic-gate 	int i;
3787c478bd9Sstevel@tonic-gate 
3797c478bd9Sstevel@tonic-gate 	/* check to see if any words are being debugged */
3807c478bd9Sstevel@tonic-gate 	if (ndebug_acfs == 0)
3817c478bd9Sstevel@tonic-gate 		return (0);
3827c478bd9Sstevel@tonic-gate 
3837c478bd9Sstevel@tonic-gate 	/* only words in dictionary can be debugged */
3847c478bd9Sstevel@tonic-gate 	if (!within_dictionary(env, acf))
3857c478bd9Sstevel@tonic-gate 		return (0);
3867c478bd9Sstevel@tonic-gate 
3877c478bd9Sstevel@tonic-gate 	/* check that word has "FLAG_DEBUG" on */
3887c478bd9Sstevel@tonic-gate 	flagp = LINK_TO_FLAGS(ACF_TO_LINK(acf));
3897c478bd9Sstevel@tonic-gate 	if ((*flagp & FLAG_DEBUG) == 0)
3907c478bd9Sstevel@tonic-gate 		return (0);
3917c478bd9Sstevel@tonic-gate 
3927c478bd9Sstevel@tonic-gate 	/* look in table of debug acf's */
3937c478bd9Sstevel@tonic-gate 	for (i = 0; i < ndebug_acfs; i++)
3947c478bd9Sstevel@tonic-gate 		if (debug_acfs[i] == acf)
3957c478bd9Sstevel@tonic-gate 			return (1);
3967c478bd9Sstevel@tonic-gate 	return (0);
3977c478bd9Sstevel@tonic-gate }
3987c478bd9Sstevel@tonic-gate 
3997c478bd9Sstevel@tonic-gate #define	MAX_DEBUG_STACK	100
4007c478bd9Sstevel@tonic-gate token_t debug_low[MAX_DEBUG_STACK], debug_high[MAX_DEBUG_STACK];
4017c478bd9Sstevel@tonic-gate int debug_prev_level[MAX_DEBUG_STACK];
4027c478bd9Sstevel@tonic-gate int debug_curr_level[MAX_DEBUG_STACK];
4037c478bd9Sstevel@tonic-gate int ndebug_stack = 0;
4047c478bd9Sstevel@tonic-gate 
4057c478bd9Sstevel@tonic-gate void
debug_set_level(fcode_env_t * env,int level)4067c478bd9Sstevel@tonic-gate debug_set_level(fcode_env_t *env, int level)
4077c478bd9Sstevel@tonic-gate {
4087c478bd9Sstevel@tonic-gate 	debug_curr_level[ndebug_stack - 1] = level;
4097c478bd9Sstevel@tonic-gate 	set_interpreter_debug_level(level);
4107c478bd9Sstevel@tonic-gate }
4117c478bd9Sstevel@tonic-gate 
4127c478bd9Sstevel@tonic-gate token_t
find_semi_in_colon_def(fcode_env_t * env,acf_t acf)4137c478bd9Sstevel@tonic-gate find_semi_in_colon_def(fcode_env_t *env, acf_t acf)
4147c478bd9Sstevel@tonic-gate {
4157c478bd9Sstevel@tonic-gate 	for (; within_dictionary(env, acf); acf++)
4167c478bd9Sstevel@tonic-gate 		if (*acf == (token_t)(&semi_ptr))
4177c478bd9Sstevel@tonic-gate 			return ((token_t)acf);
4187c478bd9Sstevel@tonic-gate 	return (0);
4197c478bd9Sstevel@tonic-gate }
4207c478bd9Sstevel@tonic-gate 
4217c478bd9Sstevel@tonic-gate void
check_for_debug_entry(fcode_env_t * env)4227c478bd9Sstevel@tonic-gate check_for_debug_entry(fcode_env_t *env)
4237c478bd9Sstevel@tonic-gate {
4247c478bd9Sstevel@tonic-gate 	int top;
4257c478bd9Sstevel@tonic-gate 
4267c478bd9Sstevel@tonic-gate 	if (is_debug_word(env, WA) && ndebug_stack < MAX_DEBUG_STACK) {
4277c478bd9Sstevel@tonic-gate 		top = ndebug_stack++;
4287c478bd9Sstevel@tonic-gate 		debug_prev_level[top] = get_interpreter_debug_level();
4297c478bd9Sstevel@tonic-gate 		debug_low[top] = (token_t)WA;
4307c478bd9Sstevel@tonic-gate 		if (*WA == (token_t)(&do_colon)) {
4317c478bd9Sstevel@tonic-gate 			debug_high[top] =
4327c478bd9Sstevel@tonic-gate 			    find_semi_in_colon_def(env, WA);
4337c478bd9Sstevel@tonic-gate 		} else {
4347c478bd9Sstevel@tonic-gate 			debug_high[top] = 0;	/* marker... */
4357c478bd9Sstevel@tonic-gate 		}
4367c478bd9Sstevel@tonic-gate 		debug_set_level(env, DEBUG_STEPPING);
4377c478bd9Sstevel@tonic-gate 		output_step_message(env);
4387c478bd9Sstevel@tonic-gate 	}
4397c478bd9Sstevel@tonic-gate }
4407c478bd9Sstevel@tonic-gate 
4417c478bd9Sstevel@tonic-gate void
check_for_debug_exit(fcode_env_t * env)4427c478bd9Sstevel@tonic-gate check_for_debug_exit(fcode_env_t *env)
4437c478bd9Sstevel@tonic-gate {
4447c478bd9Sstevel@tonic-gate 	if (ndebug_stack) {
4457c478bd9Sstevel@tonic-gate 		int top = ndebug_stack - 1;
4467c478bd9Sstevel@tonic-gate 
4477c478bd9Sstevel@tonic-gate 		if (debug_high[top] == 0) {
4487c478bd9Sstevel@tonic-gate 			set_interpreter_debug_level(debug_prev_level[top]);
4497c478bd9Sstevel@tonic-gate 			ndebug_stack--;
4507c478bd9Sstevel@tonic-gate 		} else if ((token_t)IP >= debug_low[top] &&
4517c478bd9Sstevel@tonic-gate 		    (token_t)IP <= debug_high[top]) {
4527c478bd9Sstevel@tonic-gate 			set_interpreter_debug_level(debug_curr_level[top]);
4537c478bd9Sstevel@tonic-gate 		} else {
4547c478bd9Sstevel@tonic-gate 			set_interpreter_debug_level(debug_prev_level[top]);
4557c478bd9Sstevel@tonic-gate 		}
4567c478bd9Sstevel@tonic-gate 	}
4577c478bd9Sstevel@tonic-gate }
4587c478bd9Sstevel@tonic-gate 
4597c478bd9Sstevel@tonic-gate void
check_semi_debug_exit(fcode_env_t * env)4607c478bd9Sstevel@tonic-gate check_semi_debug_exit(fcode_env_t *env)
4617c478bd9Sstevel@tonic-gate {
4627c478bd9Sstevel@tonic-gate 	if (ndebug_stack) {
4637c478bd9Sstevel@tonic-gate 		int top = ndebug_stack - 1;
4647c478bd9Sstevel@tonic-gate 
4657c478bd9Sstevel@tonic-gate 		if ((token_t)(IP - 1) == debug_high[top]) {
4667c478bd9Sstevel@tonic-gate 			set_interpreter_debug_level(debug_prev_level[top]);
4677c478bd9Sstevel@tonic-gate 			ndebug_stack--;
4687c478bd9Sstevel@tonic-gate 		}
4697c478bd9Sstevel@tonic-gate 	}
4707c478bd9Sstevel@tonic-gate }
4717c478bd9Sstevel@tonic-gate 
4727c478bd9Sstevel@tonic-gate /*
4737c478bd9Sstevel@tonic-gate  * Really entering do_run, since this may be a recursive entry to do_run,
4747c478bd9Sstevel@tonic-gate  * we need to set the debug level to what it was previously.
4757c478bd9Sstevel@tonic-gate  */
4767c478bd9Sstevel@tonic-gate int
current_debug_state(fcode_env_t * env)4777c478bd9Sstevel@tonic-gate current_debug_state(fcode_env_t *env)
4787c478bd9Sstevel@tonic-gate {
4797c478bd9Sstevel@tonic-gate 	if (ndebug_stack) {
4807c478bd9Sstevel@tonic-gate 		int top = ndebug_stack - 1;
4817c478bd9Sstevel@tonic-gate 		set_interpreter_debug_level(debug_prev_level[top]);
4827c478bd9Sstevel@tonic-gate 	}
4837c478bd9Sstevel@tonic-gate 	return (ndebug_stack);
4847c478bd9Sstevel@tonic-gate }
4857c478bd9Sstevel@tonic-gate 
4867c478bd9Sstevel@tonic-gate void
clear_debug_state(fcode_env_t * env,int oldstate)4877c478bd9Sstevel@tonic-gate clear_debug_state(fcode_env_t *env, int oldstate)
4887c478bd9Sstevel@tonic-gate {
4897c478bd9Sstevel@tonic-gate 	if (ndebug_stack && oldstate <= ndebug_stack) {
4907c478bd9Sstevel@tonic-gate 		set_interpreter_debug_level(debug_prev_level[oldstate]);
4917c478bd9Sstevel@tonic-gate 		ndebug_stack = oldstate;
4927c478bd9Sstevel@tonic-gate 	}
4937c478bd9Sstevel@tonic-gate }
4947c478bd9Sstevel@tonic-gate 
4957c478bd9Sstevel@tonic-gate void
unbug(fcode_env_t * env)4967c478bd9Sstevel@tonic-gate unbug(fcode_env_t *env)
4977c478bd9Sstevel@tonic-gate {
4987c478bd9Sstevel@tonic-gate 	int i;
4997c478bd9Sstevel@tonic-gate 	token_t *link;
5007c478bd9Sstevel@tonic-gate 	flag_t *flag;
5017c478bd9Sstevel@tonic-gate 
5027c478bd9Sstevel@tonic-gate 	for (i = ndebug_stack - 1; i >= 0; i--) {
5037c478bd9Sstevel@tonic-gate 		link = ACF_TO_LINK(debug_low[i]);
5047c478bd9Sstevel@tonic-gate 		flag = LINK_TO_FLAGS(link);
5057c478bd9Sstevel@tonic-gate 		*flag &= ~FLAG_DEBUG;
5067c478bd9Sstevel@tonic-gate 	}
5077c478bd9Sstevel@tonic-gate 	clear_debug_state(env, 0);
5087c478bd9Sstevel@tonic-gate }
5097c478bd9Sstevel@tonic-gate 
5107c478bd9Sstevel@tonic-gate void
output_vitals(fcode_env_t * env)5117c478bd9Sstevel@tonic-gate output_vitals(fcode_env_t *env)
5127c478bd9Sstevel@tonic-gate {
5137c478bd9Sstevel@tonic-gate 	log_message(MSG_FC_DEBUG, "IP=%p, *IP=%p, WA=%p, *WA=%p ", IP,
5147c478bd9Sstevel@tonic-gate 	    (IP ? *IP : 0), WA, (WA ? *WA : 0));
5157c478bd9Sstevel@tonic-gate }
5167c478bd9Sstevel@tonic-gate 
5177c478bd9Sstevel@tonic-gate int
do_exec_debug(fcode_env_t * env,void * fn)5187c478bd9Sstevel@tonic-gate do_exec_debug(fcode_env_t *env, void *fn)
5197c478bd9Sstevel@tonic-gate {
5207c478bd9Sstevel@tonic-gate 	int dl = debug_level;
5217c478bd9Sstevel@tonic-gate 	int show_wa = 1;
5227c478bd9Sstevel@tonic-gate 
5237c478bd9Sstevel@tonic-gate 	if ((dl & (DEBUG_EXEC_DUMP_DS | DEBUG_EXEC_DUMP_RS |
5247c478bd9Sstevel@tonic-gate 	    DEBUG_EXEC_SHOW_VITALS | DEBUG_EXEC_TRACE | DEBUG_TRACING |
5257c478bd9Sstevel@tonic-gate 	    DEBUG_STEPPING)) == 0)
5267c478bd9Sstevel@tonic-gate 		return (0);
5277c478bd9Sstevel@tonic-gate 
5287c478bd9Sstevel@tonic-gate 	if (dl & DEBUG_STEPPING) {
5297c478bd9Sstevel@tonic-gate 		dl |= DEBUG_EXEC_DUMP_DS;
5307c478bd9Sstevel@tonic-gate 	}
5317c478bd9Sstevel@tonic-gate 	if (dl & (DEBUG_STEPPING | DEBUG_EXEC_TRACE)) {
5327c478bd9Sstevel@tonic-gate 		log_message(MSG_FC_DEBUG, "%-15s ", acf_to_name(env, WA));
5337c478bd9Sstevel@tonic-gate 		show_wa = 0;
5347c478bd9Sstevel@tonic-gate 	}
5357c478bd9Sstevel@tonic-gate 	if (dl & DEBUG_EXEC_DUMP_DS)
5367c478bd9Sstevel@tonic-gate 		output_data_stack(env, MSG_FC_DEBUG);
5377c478bd9Sstevel@tonic-gate 	if (dl & DEBUG_EXEC_DUMP_RS)
5387c478bd9Sstevel@tonic-gate 		output_return_stack(env, show_wa, MSG_FC_DEBUG);
5397c478bd9Sstevel@tonic-gate 	if (dl & DEBUG_EXEC_SHOW_VITALS)
5407c478bd9Sstevel@tonic-gate 		output_vitals(env);
5417c478bd9Sstevel@tonic-gate 	if (dl & DEBUG_TRACING)
5427c478bd9Sstevel@tonic-gate 		do_fclib_trace(env, (void *) fn);
5437c478bd9Sstevel@tonic-gate 	log_message(MSG_FC_DEBUG, "\n");
5447c478bd9Sstevel@tonic-gate 	if (dl & DEBUG_STEPPING)
5457c478bd9Sstevel@tonic-gate 		return (do_fclib_step(env));
5467c478bd9Sstevel@tonic-gate 	return (0);
5477c478bd9Sstevel@tonic-gate }
5487c478bd9Sstevel@tonic-gate 
5497c478bd9Sstevel@tonic-gate static void
smatch(fcode_env_t * env)5507c478bd9Sstevel@tonic-gate smatch(fcode_env_t *env)
5517c478bd9Sstevel@tonic-gate {
5527c478bd9Sstevel@tonic-gate 	int len;
5537c478bd9Sstevel@tonic-gate 	char *str, *p;
5547c478bd9Sstevel@tonic-gate 
5557c478bd9Sstevel@tonic-gate 	if ((str = parse_a_string(env, &len)) == NULL)
5567c478bd9Sstevel@tonic-gate 		log_message(MSG_INFO, "smatch: no string\n");
5577c478bd9Sstevel@tonic-gate 	else {
5587c478bd9Sstevel@tonic-gate 		for (p = (char *)env->base; p < (char *)HERE; p++)
5597c478bd9Sstevel@tonic-gate 			if (memcmp(p, str, len) == 0)
5607c478bd9Sstevel@tonic-gate 				log_message(MSG_DEBUG, "%p\n", p);
5617c478bd9Sstevel@tonic-gate 	}
5627c478bd9Sstevel@tonic-gate }
5637c478bd9Sstevel@tonic-gate 
5647c478bd9Sstevel@tonic-gate void
check_vitals(fcode_env_t * env)5657c478bd9Sstevel@tonic-gate check_vitals(fcode_env_t *env)
5667c478bd9Sstevel@tonic-gate {
5677c478bd9Sstevel@tonic-gate 	int i;
5687c478bd9Sstevel@tonic-gate 	token_t *dptr;
5697c478bd9Sstevel@tonic-gate 
5707c478bd9Sstevel@tonic-gate 	dptr = env->current;
5717c478bd9Sstevel@tonic-gate 	if (*dptr && !within_dictionary(env, (uchar_t *)*dptr))
5727c478bd9Sstevel@tonic-gate 		log_message(MSG_ERROR, "Current: %p outside dictionary\n",
5737c478bd9Sstevel@tonic-gate 		    *dptr);
5747c478bd9Sstevel@tonic-gate 	for (i = env->order_depth; i >= 0; i--) {
5757c478bd9Sstevel@tonic-gate 		dptr = env->order[i];
5767c478bd9Sstevel@tonic-gate 		if (!dptr)
5777c478bd9Sstevel@tonic-gate 			continue;
5787c478bd9Sstevel@tonic-gate 		if (*dptr && !within_dictionary(env, (uchar_t *)*dptr))
5797c478bd9Sstevel@tonic-gate 			log_message(MSG_ERROR, "Order%d: %p outside"
5807c478bd9Sstevel@tonic-gate 			    " dictionary\n", i, *dptr);
5817c478bd9Sstevel@tonic-gate 	}
5827c478bd9Sstevel@tonic-gate 	if (HERE < env->base || HERE >= env->base + dict_size) {
5837c478bd9Sstevel@tonic-gate 		log_message(MSG_ERROR, "HERE: %p outside range\n", HERE);
5847c478bd9Sstevel@tonic-gate 	}
5857c478bd9Sstevel@tonic-gate 	if (DS < env->ds0 || DS >= &env->ds0[stack_size]) {
5867c478bd9Sstevel@tonic-gate 		forth_abort(env, "DS: %p outside range\n", DS);
5877c478bd9Sstevel@tonic-gate 	}
5887c478bd9Sstevel@tonic-gate 	if (RS < env->rs0 || RS >= &env->rs0[stack_size]) {
5897c478bd9Sstevel@tonic-gate 		log_message(MSG_ERROR, "RS: %p outside range\n", RS);
5907c478bd9Sstevel@tonic-gate 		RS = env->rs0;
5917c478bd9Sstevel@tonic-gate 	}
5927c478bd9Sstevel@tonic-gate 	if (IP && !within_dictionary(env, IP))
5937c478bd9Sstevel@tonic-gate 		log_message(MSG_ERROR, "IP: %p outside dictionary\n", IP);
5947c478bd9Sstevel@tonic-gate 	if (!within_dictionary(env, (void *)env->forth_voc_link))
5957c478bd9Sstevel@tonic-gate 		log_message(MSG_ERROR, "forth_voc_link: %p outside"
5967c478bd9Sstevel@tonic-gate 		    " dictionary\n", env->forth_voc_link);
5977c478bd9Sstevel@tonic-gate }
5987c478bd9Sstevel@tonic-gate 
5997c478bd9Sstevel@tonic-gate static void
dump_table(fcode_env_t * env)6007c478bd9Sstevel@tonic-gate dump_table(fcode_env_t *env)
6017c478bd9Sstevel@tonic-gate {
6027c478bd9Sstevel@tonic-gate 	int i;
6037c478bd9Sstevel@tonic-gate 
6047c478bd9Sstevel@tonic-gate 	for (i = 0; i < MAX_FCODE; i++) {
6057c478bd9Sstevel@tonic-gate 		if (*(env->table[i].apf) != (token_t)(&f_error)) {
6067c478bd9Sstevel@tonic-gate 			log_message(MSG_DEBUG, "Token: %4x %32s acf = %8p,"
6077c478bd9Sstevel@tonic-gate 			    " %8p\n", i, env->table[i].name, env->table[i].apf,
6087c478bd9Sstevel@tonic-gate 			    *(env->table[i].apf));
6097c478bd9Sstevel@tonic-gate 		}
6107c478bd9Sstevel@tonic-gate 	}
6117c478bd9Sstevel@tonic-gate 	log_message(MSG_DEBUG, "%d FCODES implemented\n", fcode_impl_count);
6127c478bd9Sstevel@tonic-gate }
6137c478bd9Sstevel@tonic-gate 
6147c478bd9Sstevel@tonic-gate void
verify_usage(fcode_env_t * env)6157c478bd9Sstevel@tonic-gate verify_usage(fcode_env_t *env)
6167c478bd9Sstevel@tonic-gate {
6177c478bd9Sstevel@tonic-gate 	int i, untested = 0;
6187c478bd9Sstevel@tonic-gate 
6197c478bd9Sstevel@tonic-gate 	for (i = 0; i < MAX_FCODE; i++) {
6207c478bd9Sstevel@tonic-gate 		int verify;
6217c478bd9Sstevel@tonic-gate 
6227c478bd9Sstevel@tonic-gate 		verify = env->table[i].flags & (ANSI_WORD|P1275_WORD);
6237c478bd9Sstevel@tonic-gate 		if ((verify) &&
6247c478bd9Sstevel@tonic-gate #ifdef DEBUG
6257c478bd9Sstevel@tonic-gate 			(env->table[i].usage == 0) &&
6267c478bd9Sstevel@tonic-gate #endif
6277c478bd9Sstevel@tonic-gate 			(env->table[i].apf)) {
6287c478bd9Sstevel@tonic-gate 			log_message(MSG_DEBUG,
6297c478bd9Sstevel@tonic-gate 			    "Untested: %4x %32s acf = %8p, %8p\n", i,
6307c478bd9Sstevel@tonic-gate 			    env->table[i].name, env->table[i].apf,
6317c478bd9Sstevel@tonic-gate 			    *(env->table[i].apf));
6327c478bd9Sstevel@tonic-gate 			untested++;
6337c478bd9Sstevel@tonic-gate 		}
6347c478bd9Sstevel@tonic-gate 	}
6357c478bd9Sstevel@tonic-gate 	if (untested)
6367c478bd9Sstevel@tonic-gate 		log_message(MSG_DEBUG, "%d untested tokens\n", untested);
6377c478bd9Sstevel@tonic-gate }
6387c478bd9Sstevel@tonic-gate 
6397c478bd9Sstevel@tonic-gate static void
debugf(fcode_env_t * env)6407c478bd9Sstevel@tonic-gate debugf(fcode_env_t *env)
6417c478bd9Sstevel@tonic-gate {
6427c478bd9Sstevel@tonic-gate 	PUSH(DS, (fstack_t)&debug_level);
6437c478bd9Sstevel@tonic-gate }
6447c478bd9Sstevel@tonic-gate 
6457c478bd9Sstevel@tonic-gate static void
control(fcode_env_t * env)6467c478bd9Sstevel@tonic-gate control(fcode_env_t *env)
6477c478bd9Sstevel@tonic-gate {
6487c478bd9Sstevel@tonic-gate 	PUSH(DS, (fstack_t)&env->control);
6497c478bd9Sstevel@tonic-gate }
6507c478bd9Sstevel@tonic-gate 
6517c478bd9Sstevel@tonic-gate struct bittab {
6527c478bd9Sstevel@tonic-gate 	int b_bitval;
6537c478bd9Sstevel@tonic-gate 	char *b_bitname;
6547c478bd9Sstevel@tonic-gate } bittab[] = {
6557c478bd9Sstevel@tonic-gate 	DEBUG_CONTEXT,		"context",
6567c478bd9Sstevel@tonic-gate 	DEBUG_BYTELOAD_DS,	"byteload-ds",
6577c478bd9Sstevel@tonic-gate 	DEBUG_BYTELOAD_RS,	"byteload-rs",
6587c478bd9Sstevel@tonic-gate 	DEBUG_BYTELOAD_TOKENS,	"byteload-tokens",
6597c478bd9Sstevel@tonic-gate 	DEBUG_NEW_TOKEN,	"new-token",
6607c478bd9Sstevel@tonic-gate 	DEBUG_EXEC_TRACE,	"exec-trace",
6617c478bd9Sstevel@tonic-gate 	DEBUG_EXEC_SHOW_VITALS,	"exec-show-vitals",
6627c478bd9Sstevel@tonic-gate 	DEBUG_EXEC_DUMP_DS,	"exec-dump-ds",
6637c478bd9Sstevel@tonic-gate 	DEBUG_EXEC_DUMP_RS,	"exec-dump-rs",
6647c478bd9Sstevel@tonic-gate 	DEBUG_COMMA,		"comma",
6657c478bd9Sstevel@tonic-gate 	DEBUG_HEADER,		"header",
6667c478bd9Sstevel@tonic-gate 	DEBUG_EXIT_WORDS,	"exit-words",
6677c478bd9Sstevel@tonic-gate 	DEBUG_EXIT_DUMP,	"exit-dump",
6687c478bd9Sstevel@tonic-gate 	DEBUG_DUMP_TOKENS,	"dump-tokens",
6697c478bd9Sstevel@tonic-gate 	DEBUG_COLON,		"colon",
6707c478bd9Sstevel@tonic-gate 	DEBUG_NEXT_VITALS,	"next-vitals",
6717c478bd9Sstevel@tonic-gate 	DEBUG_VOC_FIND,		"voc-find",
6727c478bd9Sstevel@tonic-gate 	DEBUG_DUMP_DICT_TOKENS,	"dump-dict-tokens",
6737c478bd9Sstevel@tonic-gate 	DEBUG_TOKEN_USAGE,	"token-usage",
6747c478bd9Sstevel@tonic-gate 	DEBUG_DUMP_TOKEN_TABLE,	"dump-token-table",
6757c478bd9Sstevel@tonic-gate 	DEBUG_SHOW_STACK,	"show-stack",
6767c478bd9Sstevel@tonic-gate 	DEBUG_SHOW_RS,		"show-rs",
6777c478bd9Sstevel@tonic-gate 	DEBUG_TRACING,		"tracing",
6787c478bd9Sstevel@tonic-gate 	DEBUG_TRACE_STACK,	"trace-stack",
6797c478bd9Sstevel@tonic-gate 	DEBUG_CALL_METHOD,	"call-method",
6807c478bd9Sstevel@tonic-gate 	DEBUG_ACTIONS,		"actions",
6817c478bd9Sstevel@tonic-gate 	DEBUG_STEPPING,		"stepping",
6827c478bd9Sstevel@tonic-gate 	DEBUG_REG_ACCESS,	"reg-access",
6837c478bd9Sstevel@tonic-gate 	DEBUG_ADDR_ABUSE,	"addr-abuse",
6847c478bd9Sstevel@tonic-gate 	DEBUG_FIND_FCODE,	"find-fcode",
6857c478bd9Sstevel@tonic-gate 	DEBUG_UPLOAD,		"upload",
6867c478bd9Sstevel@tonic-gate 	0
6877c478bd9Sstevel@tonic-gate };
6887c478bd9Sstevel@tonic-gate 
6897c478bd9Sstevel@tonic-gate void
debug_flags_to_output(fcode_env_t * env,int flags)6907c478bd9Sstevel@tonic-gate debug_flags_to_output(fcode_env_t *env, int flags)
6917c478bd9Sstevel@tonic-gate {
6927c478bd9Sstevel@tonic-gate 	int first = 1, i;
6937c478bd9Sstevel@tonic-gate 
6947c478bd9Sstevel@tonic-gate 	for (i = 0; bittab[i].b_bitval != 0; i++)
6957c478bd9Sstevel@tonic-gate 		if (bittab[i].b_bitval & flags) {
6967c478bd9Sstevel@tonic-gate 			if (!first)
6977c478bd9Sstevel@tonic-gate 				log_message(MSG_INFO, ",");
6987c478bd9Sstevel@tonic-gate 			first = 0;
6997c478bd9Sstevel@tonic-gate 			log_message(MSG_INFO, bittab[i].b_bitname);
7007c478bd9Sstevel@tonic-gate 		}
7017c478bd9Sstevel@tonic-gate 	if (first)
7027c478bd9Sstevel@tonic-gate 		log_message(MSG_INFO, "<empty>");
7037c478bd9Sstevel@tonic-gate 	log_message(MSG_INFO, "\n");
7047c478bd9Sstevel@tonic-gate }
7057c478bd9Sstevel@tonic-gate 
7067c478bd9Sstevel@tonic-gate static void
dot_debugf(fcode_env_t * env)7077c478bd9Sstevel@tonic-gate dot_debugf(fcode_env_t *env)
7087c478bd9Sstevel@tonic-gate {
7097c478bd9Sstevel@tonic-gate 	debug_flags_to_output(env, debug_level);
7107c478bd9Sstevel@tonic-gate }
7117c478bd9Sstevel@tonic-gate 
7127c478bd9Sstevel@tonic-gate static void
debugf_qmark(fcode_env_t * env)7137c478bd9Sstevel@tonic-gate debugf_qmark(fcode_env_t *env)
7147c478bd9Sstevel@tonic-gate {
7157c478bd9Sstevel@tonic-gate 	debug_flags_to_output(env, 0xffffffff);
7167c478bd9Sstevel@tonic-gate }
7177c478bd9Sstevel@tonic-gate 
7187c478bd9Sstevel@tonic-gate int
debug_flags_to_mask(char * str)7197c478bd9Sstevel@tonic-gate debug_flags_to_mask(char *str)
7207c478bd9Sstevel@tonic-gate {
7217c478bd9Sstevel@tonic-gate 	int flags = 0;
7227c478bd9Sstevel@tonic-gate 	char *p;
7237c478bd9Sstevel@tonic-gate 	int i;
7247c478bd9Sstevel@tonic-gate 
7257c478bd9Sstevel@tonic-gate 	if (isdigit(*str)) {
7267c478bd9Sstevel@tonic-gate 		if (*str == '0') {
7277c478bd9Sstevel@tonic-gate 			str++;
7287c478bd9Sstevel@tonic-gate 			if (*str == 'x' || *str == 'X') {
7297c478bd9Sstevel@tonic-gate 				sscanf(str + 1, "%x", &flags);
7307c478bd9Sstevel@tonic-gate 			} else
7317c478bd9Sstevel@tonic-gate 				sscanf(str, "%o", &flags);
7327c478bd9Sstevel@tonic-gate 		} else
7337c478bd9Sstevel@tonic-gate 			sscanf(str, "%d", &flags);
7347c478bd9Sstevel@tonic-gate 		return (flags);
7357c478bd9Sstevel@tonic-gate 	}
7367c478bd9Sstevel@tonic-gate 	if (strcmp(str, "clear") == 0)
7377c478bd9Sstevel@tonic-gate 		return (0);
7387c478bd9Sstevel@tonic-gate 	if (strcmp(str, "all") == 0)
7397c478bd9Sstevel@tonic-gate 		return (0xffffffff & ~DEBUG_STEPPING);
7407c478bd9Sstevel@tonic-gate 	if (*str) {
7417c478bd9Sstevel@tonic-gate 		do {
7427c478bd9Sstevel@tonic-gate 			if (p = strchr(str, ','))
7437c478bd9Sstevel@tonic-gate 				*p++ = '\0';
7447c478bd9Sstevel@tonic-gate 			for (i = 0; bittab[i].b_bitname != 0; i++)
7457c478bd9Sstevel@tonic-gate 				if (strcmp(str, bittab[i].b_bitname) == 0) {
7467c478bd9Sstevel@tonic-gate 					flags |= bittab[i].b_bitval;
7477c478bd9Sstevel@tonic-gate 					break;
7487c478bd9Sstevel@tonic-gate 			}
7497c478bd9Sstevel@tonic-gate 			if (bittab[i].b_bitname == 0)
7507c478bd9Sstevel@tonic-gate 				log_message(MSG_WARN,
7517c478bd9Sstevel@tonic-gate 				    "Unknown debug flag: '%s'\n", str);
7527c478bd9Sstevel@tonic-gate 			str = p;
7537c478bd9Sstevel@tonic-gate 		} while (p);
7547c478bd9Sstevel@tonic-gate 	}
7557c478bd9Sstevel@tonic-gate 	return (flags);
7567c478bd9Sstevel@tonic-gate }
7577c478bd9Sstevel@tonic-gate 
7587c478bd9Sstevel@tonic-gate static void
set_debugf(fcode_env_t * env)7597c478bd9Sstevel@tonic-gate set_debugf(fcode_env_t *env)
7607c478bd9Sstevel@tonic-gate {
7617c478bd9Sstevel@tonic-gate 	char *str;
7627c478bd9Sstevel@tonic-gate 
7637c478bd9Sstevel@tonic-gate 	str = parse_a_string(env, NULL);
7647c478bd9Sstevel@tonic-gate 	debug_level = debug_flags_to_mask(str);
7657c478bd9Sstevel@tonic-gate }
7667c478bd9Sstevel@tonic-gate 
7677c478bd9Sstevel@tonic-gate static acf_t
show_a_word(fcode_env_t * env,acf_t acf,void * arg)7687c478bd9Sstevel@tonic-gate show_a_word(fcode_env_t *env, acf_t acf, void *arg)
7697c478bd9Sstevel@tonic-gate {
7707c478bd9Sstevel@tonic-gate 	static int nshow_words = 0;
7717c478bd9Sstevel@tonic-gate 
7727c478bd9Sstevel@tonic-gate 	if (acf == NULL) {
7737c478bd9Sstevel@tonic-gate 		if (nshow_words > 0) {
7747c478bd9Sstevel@tonic-gate 			log_message(MSG_DEBUG, "\n");
7757c478bd9Sstevel@tonic-gate 			nshow_words = 0;
7767c478bd9Sstevel@tonic-gate 		}
7777c478bd9Sstevel@tonic-gate 		return (NULL);
7787c478bd9Sstevel@tonic-gate 	}
7797c478bd9Sstevel@tonic-gate 	log_message(MSG_DEBUG, "%15s  ", get_name_or_acf(ACF_TO_LINK(acf)));
7807c478bd9Sstevel@tonic-gate 	nshow_words++;
7817c478bd9Sstevel@tonic-gate 	if (nshow_words >= 4) {
7827c478bd9Sstevel@tonic-gate 		log_message(MSG_DEBUG, "\n");
7837c478bd9Sstevel@tonic-gate 		nshow_words = 0;
7847c478bd9Sstevel@tonic-gate 	}
7857c478bd9Sstevel@tonic-gate 	return (NULL);
7867c478bd9Sstevel@tonic-gate }
7877c478bd9Sstevel@tonic-gate 
7887c478bd9Sstevel@tonic-gate void
words(fcode_env_t * env)7897c478bd9Sstevel@tonic-gate words(fcode_env_t *env)
7907c478bd9Sstevel@tonic-gate {
7917c478bd9Sstevel@tonic-gate 	(void) search_all_dictionaries(env, show_a_word, NULL);
7927c478bd9Sstevel@tonic-gate 	(void) show_a_word(env, NULL, NULL);
7937c478bd9Sstevel@tonic-gate }
7947c478bd9Sstevel@tonic-gate 
7957c478bd9Sstevel@tonic-gate static acf_t
dump_a_word(fcode_env_t * env,acf_t acf,void * arg)7967c478bd9Sstevel@tonic-gate dump_a_word(fcode_env_t *env, acf_t acf, void *arg)
7977c478bd9Sstevel@tonic-gate {
7987c478bd9Sstevel@tonic-gate 	output_acf_name(acf);
7997c478bd9Sstevel@tonic-gate 	return (NULL);
8007c478bd9Sstevel@tonic-gate }
8017c478bd9Sstevel@tonic-gate 
8027c478bd9Sstevel@tonic-gate void
dump_words(fcode_env_t * env)8037c478bd9Sstevel@tonic-gate dump_words(fcode_env_t *env)
8047c478bd9Sstevel@tonic-gate {
8057c478bd9Sstevel@tonic-gate 	(void) search_all_dictionaries(env, dump_a_word, NULL);
8067c478bd9Sstevel@tonic-gate 	output_acf_name(NULL);
8077c478bd9Sstevel@tonic-gate }
8087c478bd9Sstevel@tonic-gate 
8097c478bd9Sstevel@tonic-gate static void
dump_line(uchar_t * ptr)8107c478bd9Sstevel@tonic-gate dump_line(uchar_t *ptr)
8117c478bd9Sstevel@tonic-gate {
8127c478bd9Sstevel@tonic-gate 	uchar_t *byte;
8137c478bd9Sstevel@tonic-gate 	int i;
8147c478bd9Sstevel@tonic-gate 
815*360e6f5eSmathue 	log_message(MSG_INFO, "%p  ", ptr);
8167c478bd9Sstevel@tonic-gate 	for (i = 0, byte = ptr; i < 16; i++) {
8177c478bd9Sstevel@tonic-gate 		if (i == 8)
8187c478bd9Sstevel@tonic-gate 			log_message(MSG_INFO, " ");
8197c478bd9Sstevel@tonic-gate 		log_message(MSG_INFO, "%02.2x ", *byte++);
8207c478bd9Sstevel@tonic-gate 	}
8217c478bd9Sstevel@tonic-gate 	log_message(MSG_INFO, " ");
8227c478bd9Sstevel@tonic-gate 	for (i = 0, byte = ptr; i < 16; i++, byte++) {
8237c478bd9Sstevel@tonic-gate 		log_message(MSG_INFO, "%c",
8247c478bd9Sstevel@tonic-gate 		    ((*byte < 0x20) || (*byte > 0x7f)) ? '.' : *byte);
8257c478bd9Sstevel@tonic-gate 	}
8267c478bd9Sstevel@tonic-gate 	log_message(MSG_INFO, "\n");
8277c478bd9Sstevel@tonic-gate }
8287c478bd9Sstevel@tonic-gate 
8297c478bd9Sstevel@tonic-gate void
dump_dictionary(fcode_env_t * env)8307c478bd9Sstevel@tonic-gate dump_dictionary(fcode_env_t *env)
8317c478bd9Sstevel@tonic-gate {
8327c478bd9Sstevel@tonic-gate 	uchar_t *ptr;
8337c478bd9Sstevel@tonic-gate 
8347c478bd9Sstevel@tonic-gate 	log_message(MSG_INFO, "Dictionary dump: base: %p\n", env->base);
8357c478bd9Sstevel@tonic-gate 	for (ptr = (uchar_t *)(((long)(env->base)) & ~0xf); ptr < HERE;
8367c478bd9Sstevel@tonic-gate 	    ptr += 16)
8377c478bd9Sstevel@tonic-gate 		dump_line(ptr);
8387c478bd9Sstevel@tonic-gate }
8397c478bd9Sstevel@tonic-gate 
8407c478bd9Sstevel@tonic-gate static char *
acf_to_fcode_name(fcode_env_t * env,acf_t acf)8417c478bd9Sstevel@tonic-gate acf_to_fcode_name(fcode_env_t *env, acf_t acf)
8427c478bd9Sstevel@tonic-gate {
8437c478bd9Sstevel@tonic-gate 	int i;
8447c478bd9Sstevel@tonic-gate 
8457c478bd9Sstevel@tonic-gate 	for (i = 0; i < MAX_FCODE; i++)
8467c478bd9Sstevel@tonic-gate 		if (env->table[i].apf == acf)
8477c478bd9Sstevel@tonic-gate 			return (env->table[i].name);
8487c478bd9Sstevel@tonic-gate 	return (NULL);
8497c478bd9Sstevel@tonic-gate }
8507c478bd9Sstevel@tonic-gate 
8517c478bd9Sstevel@tonic-gate static acf_t
acf_match(fcode_env_t * env,acf_t sacf,void * macf)8527c478bd9Sstevel@tonic-gate acf_match(fcode_env_t *env, acf_t sacf, void *macf)
8537c478bd9Sstevel@tonic-gate {
8547c478bd9Sstevel@tonic-gate 	if (sacf == (acf_t)macf)
8557c478bd9Sstevel@tonic-gate 		return (sacf);
8567c478bd9Sstevel@tonic-gate 	return (NULL);
8577c478bd9Sstevel@tonic-gate }
8587c478bd9Sstevel@tonic-gate 
8597c478bd9Sstevel@tonic-gate /*
8607c478bd9Sstevel@tonic-gate  * Given an ACF, return ptr to name or "unknown" string.
8617c478bd9Sstevel@tonic-gate  */
8627c478bd9Sstevel@tonic-gate char *
acf_to_name(fcode_env_t * env,acf_t acf)8637c478bd9Sstevel@tonic-gate acf_to_name(fcode_env_t *env, acf_t acf)
8647c478bd9Sstevel@tonic-gate {
8657c478bd9Sstevel@tonic-gate 	struct bitab *bip;
8667c478bd9Sstevel@tonic-gate 	static char name_buf[256];
8677c478bd9Sstevel@tonic-gate 	uchar_t *p, *np;
8687c478bd9Sstevel@tonic-gate 	int i, n;
8697c478bd9Sstevel@tonic-gate 
8707c478bd9Sstevel@tonic-gate 	if (!within_dictionary(env, acf)) {
8717c478bd9Sstevel@tonic-gate 		if ((bip = lookup_builtin((token_t)acf)) != NULL)
8727c478bd9Sstevel@tonic-gate 			return (bip->bi_name);
8737c478bd9Sstevel@tonic-gate 		return (NULL);
8747c478bd9Sstevel@tonic-gate 	}
8757c478bd9Sstevel@tonic-gate 	return (get_name_or_acf(ACF_TO_LINK(acf)));
8767c478bd9Sstevel@tonic-gate }
8777c478bd9Sstevel@tonic-gate 
8787c478bd9Sstevel@tonic-gate int
within_dictionary(fcode_env_t * env,void * addr)8797c478bd9Sstevel@tonic-gate within_dictionary(fcode_env_t *env, void *addr)
8807c478bd9Sstevel@tonic-gate {
8817c478bd9Sstevel@tonic-gate 	return ((uchar_t *)addr >= env->base &&
8827c478bd9Sstevel@tonic-gate 	    (uchar_t *)addr < env->base + dict_size);
8837c478bd9Sstevel@tonic-gate }
8847c478bd9Sstevel@tonic-gate 
8857c478bd9Sstevel@tonic-gate static int
within_word(fcode_env_t * env,acf_t acf,acf_t wacf)8867c478bd9Sstevel@tonic-gate within_word(fcode_env_t *env, acf_t acf, acf_t wacf)
8877c478bd9Sstevel@tonic-gate {
8887c478bd9Sstevel@tonic-gate 	if (acf == wacf || acf + 1 == wacf)
8897c478bd9Sstevel@tonic-gate 		return (1);
8907c478bd9Sstevel@tonic-gate 	if (*acf == (token_t)(&do_colon)) {
8917c478bd9Sstevel@tonic-gate 		do {
8927c478bd9Sstevel@tonic-gate 			if (acf == wacf)
8937c478bd9Sstevel@tonic-gate 				return (1);
8947c478bd9Sstevel@tonic-gate 		} while (*acf++ != (token_t)(&semi_ptr));
8957c478bd9Sstevel@tonic-gate 	}
8967c478bd9Sstevel@tonic-gate 	return (0);
8977c478bd9Sstevel@tonic-gate }
8987c478bd9Sstevel@tonic-gate 
8997c478bd9Sstevel@tonic-gate /*
9007c478bd9Sstevel@tonic-gate  * Given an ACF in the middle of a colon definition, search dictionary towards
9017c478bd9Sstevel@tonic-gate  * beginning for "colon" acf.  If we find a "semi" acf first, we're not in
9027c478bd9Sstevel@tonic-gate  * the middle of a colon-def (temporary execute?).
9037c478bd9Sstevel@tonic-gate  */
9047c478bd9Sstevel@tonic-gate char *
acf_backup_search(fcode_env_t * env,acf_t acf)9057c478bd9Sstevel@tonic-gate acf_backup_search(fcode_env_t *env, acf_t acf)
9067c478bd9Sstevel@tonic-gate {
9077c478bd9Sstevel@tonic-gate 	acf_t nacf;
9087c478bd9Sstevel@tonic-gate 	char *name;
9097c478bd9Sstevel@tonic-gate 
9107c478bd9Sstevel@tonic-gate 	if ((acf_t)_ALIGN(acf, token_t) == acf && within_dictionary(env, acf)) {
9117c478bd9Sstevel@tonic-gate 		for (nacf = acf; nacf >= (acf_t)env->base; nacf--)
9127c478bd9Sstevel@tonic-gate 			if (*nacf == (token_t)(&do_colon) ||
9137c478bd9Sstevel@tonic-gate 			    *nacf == (token_t)(&semi_ptr))
9147c478bd9Sstevel@tonic-gate 				break;
9157c478bd9Sstevel@tonic-gate 		if (nacf >= (acf_t)env->base && *nacf == (token_t)(&do_colon) &&
9167c478bd9Sstevel@tonic-gate 		    (name = get_name(ACF_TO_LINK(nacf))) != NULL)
9177c478bd9Sstevel@tonic-gate 			return (name);
9187c478bd9Sstevel@tonic-gate 	}
9197c478bd9Sstevel@tonic-gate 	return (acf_to_str(acf));
9207c478bd9Sstevel@tonic-gate }
9217c478bd9Sstevel@tonic-gate 
9227c478bd9Sstevel@tonic-gate /*
9237c478bd9Sstevel@tonic-gate  * Print out current process's C stack using /usr/proc/bin/pstack
9247c478bd9Sstevel@tonic-gate  */
9257c478bd9Sstevel@tonic-gate void
ctrace(fcode_env_t * env)9267c478bd9Sstevel@tonic-gate ctrace(fcode_env_t *env)
9277c478bd9Sstevel@tonic-gate {
9287c478bd9Sstevel@tonic-gate 	char buf[256];
9297c478bd9Sstevel@tonic-gate 	FILE *fd;
9307c478bd9Sstevel@tonic-gate 
9317c478bd9Sstevel@tonic-gate 	log_message(MSG_DEBUG, "Interpreter C Stack:\n");
9327c478bd9Sstevel@tonic-gate 	sprintf(buf, "/usr/proc/bin/pstack %d", getpid());
9337c478bd9Sstevel@tonic-gate 	if ((fd = popen(buf, "r")) == NULL)
9347c478bd9Sstevel@tonic-gate 		log_perror(MSG_ERROR, "Can't run: %s", buf);
9357c478bd9Sstevel@tonic-gate 	else {
9367c478bd9Sstevel@tonic-gate 		while (fgets(buf, sizeof (buf), fd))
9377c478bd9Sstevel@tonic-gate 			log_message(MSG_DEBUG, buf);
9387c478bd9Sstevel@tonic-gate 		fclose(fd);
9397c478bd9Sstevel@tonic-gate 	}
9407c478bd9Sstevel@tonic-gate }
9417c478bd9Sstevel@tonic-gate 
9427c478bd9Sstevel@tonic-gate /*
9437c478bd9Sstevel@tonic-gate  * Dump data, return stacks, try to unthread forth calling stack.
9447c478bd9Sstevel@tonic-gate  */
9457c478bd9Sstevel@tonic-gate void
ftrace(fcode_env_t * env)9467c478bd9Sstevel@tonic-gate ftrace(fcode_env_t *env)
9477c478bd9Sstevel@tonic-gate {
9487c478bd9Sstevel@tonic-gate 	log_message(MSG_DEBUG, "Forth Interpreter Stacks:\n");
9497c478bd9Sstevel@tonic-gate 	output_data_stack(env, MSG_DEBUG);
9507c478bd9Sstevel@tonic-gate 	output_return_stack(env, 1, MSG_DEBUG);
9517c478bd9Sstevel@tonic-gate 	log_message(MSG_DEBUG, "\n");
9527c478bd9Sstevel@tonic-gate }
9537c478bd9Sstevel@tonic-gate 
9547c478bd9Sstevel@tonic-gate int in_forth_abort;
9557c478bd9Sstevel@tonic-gate 
9567c478bd9Sstevel@tonic-gate /*
9577c478bd9Sstevel@tonic-gate  * Handle fatal error, if interactive mode, return to ok prompt.
9587c478bd9Sstevel@tonic-gate  */
9597c478bd9Sstevel@tonic-gate void
forth_abort(fcode_env_t * env,char * fmt,...)9607c478bd9Sstevel@tonic-gate forth_abort(fcode_env_t *env, char *fmt, ...)
9617c478bd9Sstevel@tonic-gate {
9627c478bd9Sstevel@tonic-gate 	va_list ap;
9637c478bd9Sstevel@tonic-gate 	char msg[256];
9647c478bd9Sstevel@tonic-gate 
9657c478bd9Sstevel@tonic-gate 	if (in_forth_abort) {
9667c478bd9Sstevel@tonic-gate 		log_message(MSG_FATAL, "ABORT: abort within forth_abort\n");
9677c478bd9Sstevel@tonic-gate 		abort();
9687c478bd9Sstevel@tonic-gate 	}
9697c478bd9Sstevel@tonic-gate 	in_forth_abort++;
9707c478bd9Sstevel@tonic-gate 
9717c478bd9Sstevel@tonic-gate 	va_start(ap, fmt);
9727c478bd9Sstevel@tonic-gate 	vsprintf(msg, fmt, ap);
9737c478bd9Sstevel@tonic-gate 	log_message(MSG_ERROR, "ABORT: %s\n", msg);
9747c478bd9Sstevel@tonic-gate 
9757c478bd9Sstevel@tonic-gate 	if (env) {
9767c478bd9Sstevel@tonic-gate 		ctrace(env);
9777c478bd9Sstevel@tonic-gate 		ftrace(env);
9787c478bd9Sstevel@tonic-gate 	}
9797c478bd9Sstevel@tonic-gate 
9807c478bd9Sstevel@tonic-gate 	return_to_interact(env);
9817c478bd9Sstevel@tonic-gate 	/*
9827c478bd9Sstevel@tonic-gate 	 * If not in interactive mode, return_to_interact just returns.
9837c478bd9Sstevel@tonic-gate 	 */
9847c478bd9Sstevel@tonic-gate 	exit(1);
9857c478bd9Sstevel@tonic-gate }
9867c478bd9Sstevel@tonic-gate 
9877c478bd9Sstevel@tonic-gate /*
9887c478bd9Sstevel@tonic-gate  * Handle fatal system call error
9897c478bd9Sstevel@tonic-gate  */
9907c478bd9Sstevel@tonic-gate void
forth_perror(fcode_env_t * env,char * fmt,...)9917c478bd9Sstevel@tonic-gate forth_perror(fcode_env_t *env, char *fmt, ...)
9927c478bd9Sstevel@tonic-gate {
9937c478bd9Sstevel@tonic-gate 	va_list ap;
9947c478bd9Sstevel@tonic-gate 	char msg[256];
9957c478bd9Sstevel@tonic-gate 	int save_errno = errno;	/* just in case... */
9967c478bd9Sstevel@tonic-gate 
9977c478bd9Sstevel@tonic-gate 	va_start(ap, fmt);
9987c478bd9Sstevel@tonic-gate 	vsprintf(msg, fmt, ap);
9997c478bd9Sstevel@tonic-gate 
10007c478bd9Sstevel@tonic-gate 	forth_abort(env, "%s: %s", msg, strerror(save_errno));
10017c478bd9Sstevel@tonic-gate }
10027c478bd9Sstevel@tonic-gate 
10037c478bd9Sstevel@tonic-gate static void
show_stack(fcode_env_t * env)10047c478bd9Sstevel@tonic-gate show_stack(fcode_env_t *env)
10057c478bd9Sstevel@tonic-gate {
10067c478bd9Sstevel@tonic-gate #ifdef DEBUG
10077c478bd9Sstevel@tonic-gate 	debug_level ^= DEBUG_SHOW_STACK;
10087c478bd9Sstevel@tonic-gate #else
10097c478bd9Sstevel@tonic-gate 	/*EMPTY*/
10107c478bd9Sstevel@tonic-gate #endif
10117c478bd9Sstevel@tonic-gate }
10127c478bd9Sstevel@tonic-gate 
10137c478bd9Sstevel@tonic-gate static void
print_bytes_header(int width,int offset)10147c478bd9Sstevel@tonic-gate print_bytes_header(int width, int offset)
10157c478bd9Sstevel@tonic-gate {
10167c478bd9Sstevel@tonic-gate 	int i;
10177c478bd9Sstevel@tonic-gate 
10187c478bd9Sstevel@tonic-gate 	for (i = 0; i < width; i++)
10197c478bd9Sstevel@tonic-gate 		log_message(MSG_INFO, " ");
10207c478bd9Sstevel@tonic-gate 	log_message(MSG_INFO, "  ");
10217c478bd9Sstevel@tonic-gate 	for (i = 0; i < 16; i++) {
10227c478bd9Sstevel@tonic-gate 		if (i == 8)
10237c478bd9Sstevel@tonic-gate 			log_message(MSG_INFO, " ");
10247c478bd9Sstevel@tonic-gate 		if (i == offset)
10257c478bd9Sstevel@tonic-gate 			log_message(MSG_INFO, "\\/ ");
10267c478bd9Sstevel@tonic-gate 		else
10277c478bd9Sstevel@tonic-gate 			log_message(MSG_INFO, "%2x ", i);
10287c478bd9Sstevel@tonic-gate 	}
10297c478bd9Sstevel@tonic-gate 	log_message(MSG_INFO, " ");
10307c478bd9Sstevel@tonic-gate 	for (i = 0; i < 16; i++) {
10317c478bd9Sstevel@tonic-gate 		if (i == offset)
10327c478bd9Sstevel@tonic-gate 			log_message(MSG_INFO, "v");
10337c478bd9Sstevel@tonic-gate 		else
10347c478bd9Sstevel@tonic-gate 			log_message(MSG_INFO, "%x", i);
10357c478bd9Sstevel@tonic-gate 	}
10367c478bd9Sstevel@tonic-gate 	log_message(MSG_INFO, "\n");
10377c478bd9Sstevel@tonic-gate }
10387c478bd9Sstevel@tonic-gate 
10397c478bd9Sstevel@tonic-gate static void
dump(fcode_env_t * env)10407c478bd9Sstevel@tonic-gate dump(fcode_env_t *env)
10417c478bd9Sstevel@tonic-gate {
10427c478bd9Sstevel@tonic-gate 	uchar_t *data;
10437c478bd9Sstevel@tonic-gate 	int len, offset;
10447c478bd9Sstevel@tonic-gate 	char buf[20];
10457c478bd9Sstevel@tonic-gate 
10467c478bd9Sstevel@tonic-gate 	len = POP(DS);
10477c478bd9Sstevel@tonic-gate 	data = (uchar_t *)POP(DS);
10487c478bd9Sstevel@tonic-gate 	offset = ((long)data) & 0xf;
10497c478bd9Sstevel@tonic-gate 	len += offset;
10507c478bd9Sstevel@tonic-gate 	data = (uchar_t *)((long)data & ~0xf);
1051*360e6f5eSmathue 	sprintf(buf, "%p", data);
10527c478bd9Sstevel@tonic-gate 	print_bytes_header(strlen(buf), offset);
10537c478bd9Sstevel@tonic-gate 	for (len += offset; len > 0; len -= 16, data += 16)
10547c478bd9Sstevel@tonic-gate 		dump_line(data);
10557c478bd9Sstevel@tonic-gate }
10567c478bd9Sstevel@tonic-gate 
10577c478bd9Sstevel@tonic-gate static acf_t
do_sifting(fcode_env_t * env,acf_t acf,void * pat)10587c478bd9Sstevel@tonic-gate do_sifting(fcode_env_t *env, acf_t acf, void *pat)
10597c478bd9Sstevel@tonic-gate {
10607c478bd9Sstevel@tonic-gate 	char *name;
10617c478bd9Sstevel@tonic-gate 
10627c478bd9Sstevel@tonic-gate 	if ((name = get_name(ACF_TO_LINK(acf))) != NULL && strstr(name, pat))
10637c478bd9Sstevel@tonic-gate 		output_acf_name(acf);
10647c478bd9Sstevel@tonic-gate 	return (NULL);
10657c478bd9Sstevel@tonic-gate }
10667c478bd9Sstevel@tonic-gate 
10677c478bd9Sstevel@tonic-gate static void
sifting(fcode_env_t * env)10687c478bd9Sstevel@tonic-gate sifting(fcode_env_t *env)
10697c478bd9Sstevel@tonic-gate {
10707c478bd9Sstevel@tonic-gate 	char *pat;
10717c478bd9Sstevel@tonic-gate 
10727c478bd9Sstevel@tonic-gate 	if ((pat = parse_a_string(env, NULL)) != NULL) {
10737c478bd9Sstevel@tonic-gate 		(void) search_all_dictionaries(env, do_sifting, pat);
10747c478bd9Sstevel@tonic-gate 		output_acf_name(NULL);
10757c478bd9Sstevel@tonic-gate 	}
10767c478bd9Sstevel@tonic-gate }
10777c478bd9Sstevel@tonic-gate 
10787c478bd9Sstevel@tonic-gate void
print_level(int level,int * doprint)10797c478bd9Sstevel@tonic-gate print_level(int level, int *doprint)
10807c478bd9Sstevel@tonic-gate {
10817c478bd9Sstevel@tonic-gate 	int i;
10827c478bd9Sstevel@tonic-gate 
10837c478bd9Sstevel@tonic-gate 	if (*doprint) {
10847c478bd9Sstevel@tonic-gate 		log_message(MSG_DEBUG, "\n    ");
10857c478bd9Sstevel@tonic-gate 		for (i = 0; i < level; i++)
10867c478bd9Sstevel@tonic-gate 			log_message(MSG_DEBUG, "    ");
10877c478bd9Sstevel@tonic-gate 		*doprint = 0;
10887c478bd9Sstevel@tonic-gate 	}
10897c478bd9Sstevel@tonic-gate }
10907c478bd9Sstevel@tonic-gate 
10917c478bd9Sstevel@tonic-gate #define	BI_QUOTE	1
10927c478bd9Sstevel@tonic-gate #define	BI_BLIT		2
10937c478bd9Sstevel@tonic-gate #define	BI_BDO		3
10947c478bd9Sstevel@tonic-gate #define	BI_QDO		4
10957c478bd9Sstevel@tonic-gate #define	BI_BR		5
10967c478bd9Sstevel@tonic-gate #define	BI_QBR		6
10977c478bd9Sstevel@tonic-gate #define	BI_BOF		7
10987c478bd9Sstevel@tonic-gate #define	BI_LOOP		8
10997c478bd9Sstevel@tonic-gate #define	BI_PLOOP	9
11007c478bd9Sstevel@tonic-gate #define	BI_TO		10
11017c478bd9Sstevel@tonic-gate #define	BI_SEMI		11
11027c478bd9Sstevel@tonic-gate #define	BI_COLON	12
11037c478bd9Sstevel@tonic-gate #define	BI_NOOP		13
11047c478bd9Sstevel@tonic-gate #define	BI_NOTYET	14	/* unimplented in "see" */
11057c478bd9Sstevel@tonic-gate 
11067c478bd9Sstevel@tonic-gate struct bitab bitab[] = {
11077c478bd9Sstevel@tonic-gate 	(token_t)(&quote_ptr),			"\"",		BI_QUOTE,
11087c478bd9Sstevel@tonic-gate 	(token_t)(&blit_ptr),			"blit",		BI_BLIT,
11097c478bd9Sstevel@tonic-gate 	(token_t)(&do_bdo_ptr),			"do",		BI_BDO,
11107c478bd9Sstevel@tonic-gate 	(token_t)(&do_bqdo_ptr),		"?do",		BI_QDO,
11117c478bd9Sstevel@tonic-gate 	(token_t)(&bbranch_ptrs[0]),		"br",		BI_BR,
11127c478bd9Sstevel@tonic-gate 	(token_t)(&bbranch_ptrs[1]),		"qbr",		BI_QBR,
11137c478bd9Sstevel@tonic-gate 	(token_t)(&bbranch_ptrs[2]),		"bof",		BI_BOF,
11147c478bd9Sstevel@tonic-gate 	(token_t)(&do_loop_ptr),		"loop",		BI_LOOP,
11157c478bd9Sstevel@tonic-gate 	(token_t)(&do_ploop_ptr),		"+loop",	BI_PLOOP,
11167c478bd9Sstevel@tonic-gate 	(token_t)(&to_ptr),			"to",		BI_NOOP,
11177c478bd9Sstevel@tonic-gate 	(token_t)(&semi_ptr),			";",		BI_SEMI,
11187c478bd9Sstevel@tonic-gate 	(token_t)(&do_colon),			":",		BI_COLON,
11197c478bd9Sstevel@tonic-gate 	(token_t)(&tlit_ptr),			"[']",		BI_NOOP,
11207c478bd9Sstevel@tonic-gate 	(token_t)(&do_leave_ptr),		"leave",	BI_NOTYET,
11217c478bd9Sstevel@tonic-gate 	(token_t)(&create_ptr),			"create",	BI_NOTYET,
11227c478bd9Sstevel@tonic-gate 	(token_t)(&does_ptr),			"does>",	BI_NOTYET,
11237c478bd9Sstevel@tonic-gate 	(token_t)(&value_defines[0][0]),	"a.@",		BI_NOTYET,
11247c478bd9Sstevel@tonic-gate 	(token_t)(&value_defines[0][1]),	"a.!",		BI_NOTYET,
11257c478bd9Sstevel@tonic-gate 	(token_t)(&value_defines[0][2]),	"a.nop",	BI_NOTYET,
11267c478bd9Sstevel@tonic-gate 	(token_t)(&value_defines[1][0]),	"a.i@",		BI_NOTYET,
11277c478bd9Sstevel@tonic-gate 	(token_t)(&value_defines[1][1]),	"a.i!",		BI_NOTYET,
11287c478bd9Sstevel@tonic-gate 	(token_t)(&value_defines[1][2]),	"a.iad",	BI_NOTYET,
11297c478bd9Sstevel@tonic-gate 	(token_t)(&value_defines[2][0]),	"a.defer",	BI_NOTYET,
11307c478bd9Sstevel@tonic-gate 	(token_t)(&value_defines[2][1]),	"a.@",		BI_NOTYET,
11317c478bd9Sstevel@tonic-gate 	(token_t)(&value_defines[2][2]),	"a.nop",	BI_NOTYET,
11327c478bd9Sstevel@tonic-gate 	(token_t)(&value_defines[3][0]),	"a.defexec",	BI_NOTYET,
11337c478bd9Sstevel@tonic-gate 	(token_t)(&value_defines[3][1]),	"a.iset",	BI_NOTYET,
11347c478bd9Sstevel@tonic-gate 	(token_t)(&value_defines[3][2]),	"a.iad",	BI_NOTYET,
11357c478bd9Sstevel@tonic-gate 	(token_t)(&value_defines[4][0]),	"a.binit",	BI_NOTYET,
11367c478bd9Sstevel@tonic-gate 	(token_t)(&value_defines[4][1]),	"a.2drop",	BI_NOTYET,
11377c478bd9Sstevel@tonic-gate 	(token_t)(&value_defines[4][2]),	"a.nop",	BI_NOTYET,
11387c478bd9Sstevel@tonic-gate 	(token_t)(&value_defines[5][0]),	"a.ibinit",	BI_NOTYET,
11397c478bd9Sstevel@tonic-gate 	(token_t)(&value_defines[5][1]),	"a.2drop",	BI_NOTYET,
11407c478bd9Sstevel@tonic-gate 	(token_t)(&value_defines[5][2]),	"a.iad",	BI_NOTYET,
11417c478bd9Sstevel@tonic-gate 	0
11427c478bd9Sstevel@tonic-gate };
11437c478bd9Sstevel@tonic-gate 
11447c478bd9Sstevel@tonic-gate struct bitab *
lookup_builtin(token_t builtin)11457c478bd9Sstevel@tonic-gate lookup_builtin(token_t builtin)
11467c478bd9Sstevel@tonic-gate {
11477c478bd9Sstevel@tonic-gate 	int i;
11487c478bd9Sstevel@tonic-gate 
11497c478bd9Sstevel@tonic-gate 	for (i = 0; bitab[i].bi_ptr; i++)
11507c478bd9Sstevel@tonic-gate 		if (bitab[i].bi_ptr == builtin)
11517c478bd9Sstevel@tonic-gate 			return (&bitab[i]);
11527c478bd9Sstevel@tonic-gate 	return (NULL);
11537c478bd9Sstevel@tonic-gate }
11547c478bd9Sstevel@tonic-gate 
11557c478bd9Sstevel@tonic-gate static void
paren_see(fcode_env_t * env)11567c478bd9Sstevel@tonic-gate paren_see(fcode_env_t *env)
11577c478bd9Sstevel@tonic-gate {
11587c478bd9Sstevel@tonic-gate 	acf_t save_acf = (acf_t)POP(DS);
11597c478bd9Sstevel@tonic-gate 	acf_t acf = save_acf;
11607c478bd9Sstevel@tonic-gate 	int i, n, pass;
11617c478bd9Sstevel@tonic-gate 	token_t brtab[30], thentab[30], brstk[30];
11627c478bd9Sstevel@tonic-gate 	int nbrtab = 0, nthentab = 0, nbrstk = 0;
11637c478bd9Sstevel@tonic-gate 	uchar_t *p;
11647c478bd9Sstevel@tonic-gate 	int level = 0, doprintlevel = 1, nthen;
11657c478bd9Sstevel@tonic-gate 	struct bitab *bip;
11667c478bd9Sstevel@tonic-gate 	token_t last_lit = 0, case_lit = 0, endof_loc = 0, endcase_loc = 0;
11677c478bd9Sstevel@tonic-gate 
11687c478bd9Sstevel@tonic-gate 	if ((bip = lookup_builtin(*acf)) == NULL ||
11697c478bd9Sstevel@tonic-gate 	    bip->bi_type != BI_COLON) {
11707c478bd9Sstevel@tonic-gate 		if (bip = lookup_builtin((token_t)acf))
11717c478bd9Sstevel@tonic-gate 			log_message(MSG_INFO, "%s: builtin\n", bip->bi_name);
11727c478bd9Sstevel@tonic-gate 		else
11737c478bd9Sstevel@tonic-gate 			log_message(MSG_INFO, "%s: builtin\n",
11747c478bd9Sstevel@tonic-gate 			    acf_to_name(env, acf));
11757c478bd9Sstevel@tonic-gate 		return;
11767c478bd9Sstevel@tonic-gate 	}
11777c478bd9Sstevel@tonic-gate 	log_message(MSG_INFO, ": %s", acf_to_name(env, acf));
11787c478bd9Sstevel@tonic-gate 	for (pass = 0; pass < 2; pass++) {
11797c478bd9Sstevel@tonic-gate 		acf = save_acf;
11807c478bd9Sstevel@tonic-gate 		for (acf++; ; acf++) {
11817c478bd9Sstevel@tonic-gate 			if (pass) {
11827c478bd9Sstevel@tonic-gate 				print_level(level, &doprintlevel);
11837c478bd9Sstevel@tonic-gate 				for (nthen = 0; nthentab > 0 &&
11847c478bd9Sstevel@tonic-gate 				    thentab[nthentab-1] == (token_t)acf;
11857c478bd9Sstevel@tonic-gate 				    nthentab--)
11867c478bd9Sstevel@tonic-gate 					nthen++;
11877c478bd9Sstevel@tonic-gate 				if (nthen) {
11887c478bd9Sstevel@tonic-gate 					level -= nthen;
11897c478bd9Sstevel@tonic-gate 					doprintlevel = 1;
11907c478bd9Sstevel@tonic-gate 					print_level(level, &doprintlevel);
11917c478bd9Sstevel@tonic-gate 					for (i = 0; i < nthen; i++)
11927c478bd9Sstevel@tonic-gate 						log_message(MSG_INFO, "then ");
11937c478bd9Sstevel@tonic-gate 				}
11947c478bd9Sstevel@tonic-gate 				print_level(level, &doprintlevel);
11957c478bd9Sstevel@tonic-gate 				for (i = 0; i < nbrtab; i += 2)
11967c478bd9Sstevel@tonic-gate 					if ((token_t)acf == brtab[i]) {
11977c478bd9Sstevel@tonic-gate 						log_message(MSG_INFO, "begin ");
11987c478bd9Sstevel@tonic-gate 						brstk[nbrstk++] = brtab[i+1];
11997c478bd9Sstevel@tonic-gate 						level++;
12007c478bd9Sstevel@tonic-gate 						doprintlevel = 1;
12017c478bd9Sstevel@tonic-gate 					}
12027c478bd9Sstevel@tonic-gate 				print_level(level, &doprintlevel);
12037c478bd9Sstevel@tonic-gate 				if (case_lit == (token_t)acf) {
12047c478bd9Sstevel@tonic-gate 					log_message(MSG_INFO, "case ");
12057c478bd9Sstevel@tonic-gate 					doprintlevel = 1;
12067c478bd9Sstevel@tonic-gate 					print_level(level, &doprintlevel);
12077c478bd9Sstevel@tonic-gate 				}
12087c478bd9Sstevel@tonic-gate 				if (endof_loc == (token_t)acf) {
12097c478bd9Sstevel@tonic-gate 					log_message(MSG_INFO, "endof ");
12107c478bd9Sstevel@tonic-gate 					doprintlevel = 1;
12117c478bd9Sstevel@tonic-gate 					print_level(level, &doprintlevel);
12127c478bd9Sstevel@tonic-gate 				}
12137c478bd9Sstevel@tonic-gate 				if (endcase_loc == (token_t)acf) {
12147c478bd9Sstevel@tonic-gate 					doprintlevel = 1;
12157c478bd9Sstevel@tonic-gate 					print_level(level, &doprintlevel);
12167c478bd9Sstevel@tonic-gate 					log_message(MSG_INFO, "endcase ");
12177c478bd9Sstevel@tonic-gate 				}
12187c478bd9Sstevel@tonic-gate 			}
12197c478bd9Sstevel@tonic-gate 			if ((bip = lookup_builtin((token_t)*acf)) == 0) {
12207c478bd9Sstevel@tonic-gate 				last_lit = (token_t)acf;
12217c478bd9Sstevel@tonic-gate 				if (pass)
12227c478bd9Sstevel@tonic-gate 					log_message(MSG_INFO, "%s ",
12237c478bd9Sstevel@tonic-gate 					    acf_to_name(env, (acf_t)*acf));
12247c478bd9Sstevel@tonic-gate 				continue;
12257c478bd9Sstevel@tonic-gate 			}
12267c478bd9Sstevel@tonic-gate 			if (bip->bi_type == BI_SEMI) {
12277c478bd9Sstevel@tonic-gate 				if (pass) {
12287c478bd9Sstevel@tonic-gate 					log_message(MSG_INFO, "\n");
12297c478bd9Sstevel@tonic-gate 					log_message(MSG_INFO, "%s\n",
12307c478bd9Sstevel@tonic-gate 					    bip->bi_name);
12317c478bd9Sstevel@tonic-gate 				}
12327c478bd9Sstevel@tonic-gate 				break;
12337c478bd9Sstevel@tonic-gate 			}
12347c478bd9Sstevel@tonic-gate 			switch (bip->bi_type) {
12357c478bd9Sstevel@tonic-gate 
12367c478bd9Sstevel@tonic-gate 			case BI_NOOP:
12377c478bd9Sstevel@tonic-gate 			case BI_NOTYET:
12387c478bd9Sstevel@tonic-gate 				if (pass)
12397c478bd9Sstevel@tonic-gate 					log_message(MSG_INFO, "%s ",
12407c478bd9Sstevel@tonic-gate 					    bip->bi_name);
12417c478bd9Sstevel@tonic-gate 				break;
12427c478bd9Sstevel@tonic-gate 
12437c478bd9Sstevel@tonic-gate 			case BI_QUOTE:
12447c478bd9Sstevel@tonic-gate 				if (pass)
12457c478bd9Sstevel@tonic-gate 					log_message(MSG_INFO, "\" ");
12467c478bd9Sstevel@tonic-gate 				acf++;
12477c478bd9Sstevel@tonic-gate 				p = (uchar_t *)acf;
12487c478bd9Sstevel@tonic-gate 				n = *p++;
12497c478bd9Sstevel@tonic-gate 				if (pass)
12507c478bd9Sstevel@tonic-gate 					log_message(MSG_INFO, "%s\" ", p);
12517c478bd9Sstevel@tonic-gate 				p += n + 1;
12527c478bd9Sstevel@tonic-gate 				for (; ((token_t)(p)) & (sizeof (token_t) - 1);
12537c478bd9Sstevel@tonic-gate 				    p++)
12547c478bd9Sstevel@tonic-gate 					;
12557c478bd9Sstevel@tonic-gate 				acf = (acf_t)p;
12567c478bd9Sstevel@tonic-gate 				acf--;
12577c478bd9Sstevel@tonic-gate 				break;
12587c478bd9Sstevel@tonic-gate 
12597c478bd9Sstevel@tonic-gate 			case BI_BLIT:
12607c478bd9Sstevel@tonic-gate 				acf++;
12617c478bd9Sstevel@tonic-gate 				if (pass)
12627c478bd9Sstevel@tonic-gate 					log_message(MSG_INFO, "%x ", *acf);
12637c478bd9Sstevel@tonic-gate 				break;
12647c478bd9Sstevel@tonic-gate 
12657c478bd9Sstevel@tonic-gate 			case BI_BDO:
12667c478bd9Sstevel@tonic-gate 			case BI_QDO:
12677c478bd9Sstevel@tonic-gate 				if (pass) {
12687c478bd9Sstevel@tonic-gate 					log_message(MSG_INFO, "%s ",
12697c478bd9Sstevel@tonic-gate 					    bip->bi_name);
12707c478bd9Sstevel@tonic-gate 					doprintlevel = 1;
12717c478bd9Sstevel@tonic-gate 					level++;
12727c478bd9Sstevel@tonic-gate 				}
12737c478bd9Sstevel@tonic-gate 				acf++;
12747c478bd9Sstevel@tonic-gate 				break;
12757c478bd9Sstevel@tonic-gate 
12767c478bd9Sstevel@tonic-gate 			case BI_BR:
12777c478bd9Sstevel@tonic-gate 				acf++;
12787c478bd9Sstevel@tonic-gate 				if (pass) {
12797c478bd9Sstevel@tonic-gate 					if (*acf < (token_t)acf) {
12807c478bd9Sstevel@tonic-gate 						if (nbrstk) {
12817c478bd9Sstevel@tonic-gate 							doprintlevel = 1;
12827c478bd9Sstevel@tonic-gate 							level--;
12837c478bd9Sstevel@tonic-gate 							print_level(level,
12847c478bd9Sstevel@tonic-gate 							    &doprintlevel);
12857c478bd9Sstevel@tonic-gate 							log_message(MSG_INFO,
12867c478bd9Sstevel@tonic-gate 							    "repeat ");
12877c478bd9Sstevel@tonic-gate 							nbrstk--;
12887c478bd9Sstevel@tonic-gate 						} else
12897c478bd9Sstevel@tonic-gate 							log_message(MSG_INFO,
12907c478bd9Sstevel@tonic-gate 							    "[br back?]");
12917c478bd9Sstevel@tonic-gate 					} else if (nthentab) {
12927c478bd9Sstevel@tonic-gate 						doprintlevel = 1;
12937c478bd9Sstevel@tonic-gate 						print_level(level - 1,
12947c478bd9Sstevel@tonic-gate 						    &doprintlevel);
12957c478bd9Sstevel@tonic-gate 						log_message(MSG_INFO, "else ");
12967c478bd9Sstevel@tonic-gate 						doprintlevel = 1;
12977c478bd9Sstevel@tonic-gate 						thentab[nthentab - 1] = *acf;
12987c478bd9Sstevel@tonic-gate 					}
12997c478bd9Sstevel@tonic-gate 				} else {
13007c478bd9Sstevel@tonic-gate 					if (*acf < (token_t)acf) {
13017c478bd9Sstevel@tonic-gate 						brtab[nbrtab++] = *acf;
13027c478bd9Sstevel@tonic-gate 						brtab[nbrtab++] = (token_t)acf;
13037c478bd9Sstevel@tonic-gate 					}
13047c478bd9Sstevel@tonic-gate 					if (endcase_loc == 0 &&
13057c478bd9Sstevel@tonic-gate 					    case_lit) {
13067c478bd9Sstevel@tonic-gate 						endcase_loc = *acf;
13077c478bd9Sstevel@tonic-gate 					}
13087c478bd9Sstevel@tonic-gate 				}
13097c478bd9Sstevel@tonic-gate 				break;
13107c478bd9Sstevel@tonic-gate 
13117c478bd9Sstevel@tonic-gate 			case BI_QBR:
13127c478bd9Sstevel@tonic-gate 				acf++;
13137c478bd9Sstevel@tonic-gate 				if (pass) {
13147c478bd9Sstevel@tonic-gate 					if (*acf < (token_t)acf) {
13157c478bd9Sstevel@tonic-gate 						if (nbrstk) {
13167c478bd9Sstevel@tonic-gate 							doprintlevel = 1;
13177c478bd9Sstevel@tonic-gate 							level--;
13187c478bd9Sstevel@tonic-gate 							print_level(level,
13197c478bd9Sstevel@tonic-gate 							    &doprintlevel);
13207c478bd9Sstevel@tonic-gate 							log_message(MSG_INFO,
13217c478bd9Sstevel@tonic-gate 							    "until ");
13227c478bd9Sstevel@tonic-gate 							nbrstk--;
13237c478bd9Sstevel@tonic-gate 						} else
13247c478bd9Sstevel@tonic-gate 							log_message(MSG_INFO,
13257c478bd9Sstevel@tonic-gate 							    "[br back?]");
13267c478bd9Sstevel@tonic-gate 					} else if (nbrstk > 0 &&
13277c478bd9Sstevel@tonic-gate 					    *acf >= brstk[nbrstk - 1]) {
13287c478bd9Sstevel@tonic-gate 						doprintlevel = 1;
13297c478bd9Sstevel@tonic-gate 						print_level(level - 1,
13307c478bd9Sstevel@tonic-gate 						    &doprintlevel);
13317c478bd9Sstevel@tonic-gate 						log_message(MSG_INFO,
13327c478bd9Sstevel@tonic-gate 						    "while ");
13337c478bd9Sstevel@tonic-gate 						doprintlevel = 1;
13347c478bd9Sstevel@tonic-gate 					} else {
13357c478bd9Sstevel@tonic-gate 						log_message(MSG_INFO, "if ");
13367c478bd9Sstevel@tonic-gate 						doprintlevel = 1;
13377c478bd9Sstevel@tonic-gate 						level++;
13387c478bd9Sstevel@tonic-gate 						thentab[nthentab++] = *acf;
13397c478bd9Sstevel@tonic-gate 					}
13407c478bd9Sstevel@tonic-gate 				} else if (*acf < (token_t)acf) {
13417c478bd9Sstevel@tonic-gate 					brtab[nbrtab++] = *acf;
13427c478bd9Sstevel@tonic-gate 					brtab[nbrtab++] = (token_t)acf;
13437c478bd9Sstevel@tonic-gate 				}
13447c478bd9Sstevel@tonic-gate 				break;
13457c478bd9Sstevel@tonic-gate 
13467c478bd9Sstevel@tonic-gate 			case BI_BOF:
13477c478bd9Sstevel@tonic-gate 				acf++;
13487c478bd9Sstevel@tonic-gate 				if (pass) {
13497c478bd9Sstevel@tonic-gate 					log_message(MSG_INFO, "of ");
13507c478bd9Sstevel@tonic-gate 					endof_loc = *acf;
13517c478bd9Sstevel@tonic-gate 				} else if (case_lit == 0) {
13527c478bd9Sstevel@tonic-gate 					case_lit = last_lit;
13537c478bd9Sstevel@tonic-gate 				}
13547c478bd9Sstevel@tonic-gate 				break;
13557c478bd9Sstevel@tonic-gate 
13567c478bd9Sstevel@tonic-gate 			case BI_LOOP:
13577c478bd9Sstevel@tonic-gate 			case BI_PLOOP:
13587c478bd9Sstevel@tonic-gate 				if (pass) {
13597c478bd9Sstevel@tonic-gate 					level--;
13607c478bd9Sstevel@tonic-gate 					doprintlevel = 1;
13617c478bd9Sstevel@tonic-gate 					print_level(level, &doprintlevel);
13627c478bd9Sstevel@tonic-gate 					log_message(MSG_INFO, "%s ",
13637c478bd9Sstevel@tonic-gate 					    bip->bi_name);
13647c478bd9Sstevel@tonic-gate 				}
13657c478bd9Sstevel@tonic-gate 				acf++;
13667c478bd9Sstevel@tonic-gate 				break;
13677c478bd9Sstevel@tonic-gate 
13687c478bd9Sstevel@tonic-gate 			default:
13697c478bd9Sstevel@tonic-gate 				log_message(MSG_ERROR, "Invalid builtin %s\n",
13707c478bd9Sstevel@tonic-gate 				    bip->bi_name);
13717c478bd9Sstevel@tonic-gate 			}
13727c478bd9Sstevel@tonic-gate 		}
13737c478bd9Sstevel@tonic-gate 	}
13747c478bd9Sstevel@tonic-gate }
13757c478bd9Sstevel@tonic-gate 
13767c478bd9Sstevel@tonic-gate static void
see(fcode_env_t * env)13777c478bd9Sstevel@tonic-gate see(fcode_env_t *env)
13787c478bd9Sstevel@tonic-gate {
13797c478bd9Sstevel@tonic-gate 	fstack_t d;
13807c478bd9Sstevel@tonic-gate 
13817c478bd9Sstevel@tonic-gate 	parse_word(env);
13827c478bd9Sstevel@tonic-gate 	dollar_find(env);
13837c478bd9Sstevel@tonic-gate 	d = POP(DS);
13847c478bd9Sstevel@tonic-gate 	if (d)
13857c478bd9Sstevel@tonic-gate 		paren_see(env);
13867c478bd9Sstevel@tonic-gate 	else {
13877c478bd9Sstevel@tonic-gate 		log_message(MSG_WARN, "?");
13887c478bd9Sstevel@tonic-gate 		two_drop(env);
13897c478bd9Sstevel@tonic-gate 	}
13907c478bd9Sstevel@tonic-gate }
13917c478bd9Sstevel@tonic-gate 
13927c478bd9Sstevel@tonic-gate static acf_t
do_dot_calls(fcode_env_t * env,acf_t acf,void * cacf)13937c478bd9Sstevel@tonic-gate do_dot_calls(fcode_env_t *env, acf_t acf, void *cacf)
13947c478bd9Sstevel@tonic-gate {
13957c478bd9Sstevel@tonic-gate 	token_t *dptr = ACF_TO_LINK(acf);
13967c478bd9Sstevel@tonic-gate 	token_t *wptr = acf;
13977c478bd9Sstevel@tonic-gate 
13987c478bd9Sstevel@tonic-gate 	if (*wptr == (token_t)(&do_colon)) {
13997c478bd9Sstevel@tonic-gate 		do {
14007c478bd9Sstevel@tonic-gate 			if ((acf_t)(*wptr) == (acf_t)cacf)
14017c478bd9Sstevel@tonic-gate 				output_acf_name(acf);
14027c478bd9Sstevel@tonic-gate 		} while (*wptr++ != (token_t)(&semi_ptr));
14037c478bd9Sstevel@tonic-gate 	} else if ((acf_t)(*wptr) == cacf)
14047c478bd9Sstevel@tonic-gate 		output_acf_name(acf);
14057c478bd9Sstevel@tonic-gate 	else if (wptr == (token_t *)cacf)
14067c478bd9Sstevel@tonic-gate 		output_acf_name(acf);
14077c478bd9Sstevel@tonic-gate 	return (NULL);
14087c478bd9Sstevel@tonic-gate }
14097c478bd9Sstevel@tonic-gate 
14107c478bd9Sstevel@tonic-gate static void
dot_calls(fcode_env_t * env)14117c478bd9Sstevel@tonic-gate dot_calls(fcode_env_t *env)
14127c478bd9Sstevel@tonic-gate {
14137c478bd9Sstevel@tonic-gate 	acf_t acf = (acf_t)POP(DS);
14147c478bd9Sstevel@tonic-gate 
14157c478bd9Sstevel@tonic-gate 	search_all_dictionaries(env, do_dot_calls, acf);
14167c478bd9Sstevel@tonic-gate 	output_acf_name(NULL);
14177c478bd9Sstevel@tonic-gate }
14187c478bd9Sstevel@tonic-gate 
14197c478bd9Sstevel@tonic-gate static void
dot_pci_space(fcode_env_t * env)14207c478bd9Sstevel@tonic-gate dot_pci_space(fcode_env_t *env)
14217c478bd9Sstevel@tonic-gate {
14227c478bd9Sstevel@tonic-gate 	fstack_t d = POP(DS);
14237c478bd9Sstevel@tonic-gate 
14247c478bd9Sstevel@tonic-gate 	switch ((d >> 24) & 0x3) {
14257c478bd9Sstevel@tonic-gate 	case 0: log_message(MSG_INFO, "Config,"); break;
14267c478bd9Sstevel@tonic-gate 	case 1: log_message(MSG_INFO, "IO,"); break;
14277c478bd9Sstevel@tonic-gate 	case 2: log_message(MSG_INFO, "Memory32,"); break;
14287c478bd9Sstevel@tonic-gate 	case 3: log_message(MSG_INFO, "Memory64,"); break;
14297c478bd9Sstevel@tonic-gate 	}
14307c478bd9Sstevel@tonic-gate 	if (d & 0x80000000)
14317c478bd9Sstevel@tonic-gate 		log_message(MSG_INFO, "Not_reloc,");
14327c478bd9Sstevel@tonic-gate 	if (d & 0x400000000)
14337c478bd9Sstevel@tonic-gate 		log_message(MSG_INFO, "Prefetch,");
14347c478bd9Sstevel@tonic-gate 	if (d & 0x200000000)
14357c478bd9Sstevel@tonic-gate 		log_message(MSG_INFO, "Alias,");
14367c478bd9Sstevel@tonic-gate 	log_message(MSG_INFO, "Bus%d,", (d >> 16) & 0xff);
14377c478bd9Sstevel@tonic-gate 	log_message(MSG_INFO, "Dev%d,", (d >> 11) & 0x1f);
14387c478bd9Sstevel@tonic-gate 	log_message(MSG_INFO, "Func%d,", (d >> 8) & 0x7);
14397c478bd9Sstevel@tonic-gate 	log_message(MSG_INFO, "Reg%x", d & 0xff);
14407c478bd9Sstevel@tonic-gate 	log_message(MSG_INFO, "\n");
14417c478bd9Sstevel@tonic-gate }
14427c478bd9Sstevel@tonic-gate 
14437c478bd9Sstevel@tonic-gate void
fcode_debug(fcode_env_t * env)14447c478bd9Sstevel@tonic-gate fcode_debug(fcode_env_t *env)
14457c478bd9Sstevel@tonic-gate {
14467c478bd9Sstevel@tonic-gate 	PUSH(DS, (fstack_t)(&env->fcode_debug));
14477c478bd9Sstevel@tonic-gate }
14487c478bd9Sstevel@tonic-gate 
14497c478bd9Sstevel@tonic-gate static void
base_addr(fcode_env_t * env)14507c478bd9Sstevel@tonic-gate base_addr(fcode_env_t *env)
14517c478bd9Sstevel@tonic-gate {
14527c478bd9Sstevel@tonic-gate 	PUSH(DS, (fstack_t)env->base);
14537c478bd9Sstevel@tonic-gate }
14547c478bd9Sstevel@tonic-gate 
14557c478bd9Sstevel@tonic-gate static int mw_valid;
14567c478bd9Sstevel@tonic-gate static int mw_size;
14577c478bd9Sstevel@tonic-gate static void *mw_addr;
14587c478bd9Sstevel@tonic-gate static fstack_t mw_value;
14597c478bd9Sstevel@tonic-gate static fstack_t mw_lastvalue;
14607c478bd9Sstevel@tonic-gate 
14617c478bd9Sstevel@tonic-gate static fstack_t
mw_fetch(void)14627c478bd9Sstevel@tonic-gate mw_fetch(void)
14637c478bd9Sstevel@tonic-gate {
14647c478bd9Sstevel@tonic-gate 	switch (mw_size) {
14657c478bd9Sstevel@tonic-gate 	case 1: return (*((uint8_t *)mw_addr));
14667c478bd9Sstevel@tonic-gate 	case 2: return (*((uint16_t *)mw_addr));
14677c478bd9Sstevel@tonic-gate 	case 4: return (*((uint32_t *)mw_addr));
14687c478bd9Sstevel@tonic-gate 	case 8: return (*((uint64_t *)mw_addr));
14697c478bd9Sstevel@tonic-gate 	}
14707c478bd9Sstevel@tonic-gate 	return (0);
14717c478bd9Sstevel@tonic-gate }
14727c478bd9Sstevel@tonic-gate 
14737c478bd9Sstevel@tonic-gate void
do_memory_watch(fcode_env_t * env)14747c478bd9Sstevel@tonic-gate do_memory_watch(fcode_env_t *env)
14757c478bd9Sstevel@tonic-gate {
14767c478bd9Sstevel@tonic-gate 	fstack_t value;
14777c478bd9Sstevel@tonic-gate 
14787c478bd9Sstevel@tonic-gate 	if (!mw_valid)
14797c478bd9Sstevel@tonic-gate 		return;
14807c478bd9Sstevel@tonic-gate 	value = mw_fetch();
14817c478bd9Sstevel@tonic-gate 	if (value != mw_lastvalue) {
14827c478bd9Sstevel@tonic-gate 		if (mw_valid == 1 || mw_value == value) {
14837c478bd9Sstevel@tonic-gate 			log_message(MSG_INFO,
14847c478bd9Sstevel@tonic-gate 			    "memory-watch: %p/%d: %llx -> %llx\n",
14857c478bd9Sstevel@tonic-gate 			    mw_addr, mw_size, (uint64_t)mw_lastvalue,
14867c478bd9Sstevel@tonic-gate 			    (uint64_t)value);
14877c478bd9Sstevel@tonic-gate 			do_fclib_step(env);
14887c478bd9Sstevel@tonic-gate 		}
14897c478bd9Sstevel@tonic-gate 		mw_lastvalue = value;
14907c478bd9Sstevel@tonic-gate 	}
14917c478bd9Sstevel@tonic-gate }
14927c478bd9Sstevel@tonic-gate 
14937c478bd9Sstevel@tonic-gate static void
set_memory_watch(fcode_env_t * env,int type,int size,void * addr,fstack_t value)14947c478bd9Sstevel@tonic-gate set_memory_watch(fcode_env_t *env, int type, int size, void *addr,
14957c478bd9Sstevel@tonic-gate     fstack_t value)
14967c478bd9Sstevel@tonic-gate {
14977c478bd9Sstevel@tonic-gate 	switch (size) {
14987c478bd9Sstevel@tonic-gate 	case 1: case 2: case 4: case 8:
14997c478bd9Sstevel@tonic-gate 		break;
15007c478bd9Sstevel@tonic-gate 	default:
15017c478bd9Sstevel@tonic-gate 		log_message(MSG_ERROR, "set_memory_watch: invalid size: %d\n",
15027c478bd9Sstevel@tonic-gate 		    size);
15037c478bd9Sstevel@tonic-gate 		return;
15047c478bd9Sstevel@tonic-gate 	}
15057c478bd9Sstevel@tonic-gate 	mw_valid = type;
15067c478bd9Sstevel@tonic-gate 	mw_size = size;
15077c478bd9Sstevel@tonic-gate 	mw_addr = addr;
15087c478bd9Sstevel@tonic-gate 	mw_value = value;
15097c478bd9Sstevel@tonic-gate 	mw_lastvalue = mw_fetch();
15107c478bd9Sstevel@tonic-gate }
15117c478bd9Sstevel@tonic-gate 
15127c478bd9Sstevel@tonic-gate static void
memory_watch(fcode_env_t * env)15137c478bd9Sstevel@tonic-gate memory_watch(fcode_env_t *env)
15147c478bd9Sstevel@tonic-gate {
15157c478bd9Sstevel@tonic-gate 	int size = POP(DS);
15167c478bd9Sstevel@tonic-gate 	void *addr = (void *)POP(DS);
15177c478bd9Sstevel@tonic-gate 
15187c478bd9Sstevel@tonic-gate 	set_memory_watch(env, 1, size, addr, 0);
15197c478bd9Sstevel@tonic-gate }
15207c478bd9Sstevel@tonic-gate 
15217c478bd9Sstevel@tonic-gate static void
memory_watch_value(fcode_env_t * env)15227c478bd9Sstevel@tonic-gate memory_watch_value(fcode_env_t *env)
15237c478bd9Sstevel@tonic-gate {
15247c478bd9Sstevel@tonic-gate 	int size = POP(DS);
15257c478bd9Sstevel@tonic-gate 	void *addr = (void *)POP(DS);
15267c478bd9Sstevel@tonic-gate 	fstack_t value = POP(DS);
15277c478bd9Sstevel@tonic-gate 
15287c478bd9Sstevel@tonic-gate 	set_memory_watch(env, 2, size, addr, value);
15297c478bd9Sstevel@tonic-gate }
15307c478bd9Sstevel@tonic-gate 
15317c478bd9Sstevel@tonic-gate static void
memory_watch_clear(fcode_env_t * env)15327c478bd9Sstevel@tonic-gate memory_watch_clear(fcode_env_t *env)
15337c478bd9Sstevel@tonic-gate {
15347c478bd9Sstevel@tonic-gate 	mw_valid = 0;
15357c478bd9Sstevel@tonic-gate }
15367c478bd9Sstevel@tonic-gate 
15377c478bd9Sstevel@tonic-gate static void
vsearch(fcode_env_t * env)15387c478bd9Sstevel@tonic-gate vsearch(fcode_env_t *env)
15397c478bd9Sstevel@tonic-gate {
15407c478bd9Sstevel@tonic-gate 	fstack_t value;
15417c478bd9Sstevel@tonic-gate 	int size = POP(DS);
15427c478bd9Sstevel@tonic-gate 	fstack_t match_value = POP(DS);
15437c478bd9Sstevel@tonic-gate 	uchar_t *toaddr = (uchar_t *)POP(DS);
15447c478bd9Sstevel@tonic-gate 	uchar_t *fromaddr = (uchar_t *)POP(DS);
15457c478bd9Sstevel@tonic-gate 
15467c478bd9Sstevel@tonic-gate 	log_message(MSG_INFO, "%p to %p by %d looking for %llx\n", fromaddr,
15477c478bd9Sstevel@tonic-gate 	    toaddr, size, (uint64_t)match_value);
15487c478bd9Sstevel@tonic-gate 	for (; fromaddr < toaddr; fromaddr += size) {
15497c478bd9Sstevel@tonic-gate 		switch (size) {
15507c478bd9Sstevel@tonic-gate 		case 1: value = *((uint8_t *)fromaddr); break;
15517c478bd9Sstevel@tonic-gate 		case 2: value = *((uint16_t *)fromaddr); break;
15527c478bd9Sstevel@tonic-gate 		case 4: value = *((uint32_t *)fromaddr); break;
15537c478bd9Sstevel@tonic-gate 		case 8: value = *((uint64_t *)fromaddr); break;
15547c478bd9Sstevel@tonic-gate 		default:
15557c478bd9Sstevel@tonic-gate 			log_message(MSG_INFO, "Invalid size: %d\n", size);
15567c478bd9Sstevel@tonic-gate 			return;
15577c478bd9Sstevel@tonic-gate 		}
15587c478bd9Sstevel@tonic-gate 		if (value == match_value)
15597c478bd9Sstevel@tonic-gate 			log_message(MSG_INFO, "%p\n", fromaddr);
15607c478bd9Sstevel@tonic-gate 	}
15617c478bd9Sstevel@tonic-gate }
15627c478bd9Sstevel@tonic-gate 
15637c478bd9Sstevel@tonic-gate #pragma init(_init)
15647c478bd9Sstevel@tonic-gate 
15657c478bd9Sstevel@tonic-gate static void
_init(void)15667c478bd9Sstevel@tonic-gate _init(void)
15677c478bd9Sstevel@tonic-gate {
15687c478bd9Sstevel@tonic-gate 	fcode_env_t *env = initial_env;
15697c478bd9Sstevel@tonic-gate 
15707c478bd9Sstevel@tonic-gate 	ASSERT(env);
15717c478bd9Sstevel@tonic-gate 	NOTICE;
15727c478bd9Sstevel@tonic-gate 
15737c478bd9Sstevel@tonic-gate 	FORTH(IMMEDIATE,	"words",		words);
15747c478bd9Sstevel@tonic-gate 	FORTH(IMMEDIATE,	"dump-words",		dump_words);
15757c478bd9Sstevel@tonic-gate 	FORTH(IMMEDIATE,	"dump-dict",		dump_dictionary);
15767c478bd9Sstevel@tonic-gate 	FORTH(IMMEDIATE,	"dump-table",		dump_table);
15777c478bd9Sstevel@tonic-gate 	FORTH(0,		"debugf",		debugf);
15787c478bd9Sstevel@tonic-gate 	FORTH(0,		".debugf",		dot_debugf);
15797c478bd9Sstevel@tonic-gate 	FORTH(0,		"set-debugf",		set_debugf);
15807c478bd9Sstevel@tonic-gate 	FORTH(0,		"debugf?",		debugf_qmark);
15817c478bd9Sstevel@tonic-gate 	FORTH(0,		"control",		control);
15827c478bd9Sstevel@tonic-gate 	FORTH(0,		"dump",			dump);
15837c478bd9Sstevel@tonic-gate 	FORTH(IMMEDIATE,	"showstack",		show_stack);
15847c478bd9Sstevel@tonic-gate 	FORTH(IMMEDIATE,	"sifting",		sifting);
15857c478bd9Sstevel@tonic-gate 	FORTH(IMMEDIATE,	"ctrace",		ctrace);
15867c478bd9Sstevel@tonic-gate 	FORTH(IMMEDIATE,	"ftrace",		ftrace);
15877c478bd9Sstevel@tonic-gate 	FORTH(0,		"see",			see);
15887c478bd9Sstevel@tonic-gate 	FORTH(0,		"(see)",		paren_see);
15897c478bd9Sstevel@tonic-gate 	FORTH(0,		"base-addr",		base_addr);
15907c478bd9Sstevel@tonic-gate 	FORTH(0,		"smatch",		smatch);
15917c478bd9Sstevel@tonic-gate 	FORTH(0,		".calls",		dot_calls);
15927c478bd9Sstevel@tonic-gate 	FORTH(0,		".pci-space",		dot_pci_space);
15937c478bd9Sstevel@tonic-gate 	FORTH(0,		"(debug)",		paren_debug);
15947c478bd9Sstevel@tonic-gate 	FORTH(0,		"debug",		debug);
15957c478bd9Sstevel@tonic-gate 	FORTH(0,		".debug",		dot_debug);
15967c478bd9Sstevel@tonic-gate 	FORTH(0,		"undebug",		undebug);
15977c478bd9Sstevel@tonic-gate 	FORTH(0,		"memory-watch",		memory_watch);
15987c478bd9Sstevel@tonic-gate 	FORTH(0,		"memory-watch-value",	memory_watch_value);
15997c478bd9Sstevel@tonic-gate 	FORTH(0,		"memory-watch-clear",	memory_watch_clear);
16007c478bd9Sstevel@tonic-gate 	FORTH(0,		"vsearch",		vsearch);
16017c478bd9Sstevel@tonic-gate }
1602