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 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 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 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 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 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 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 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 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 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 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 * 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 * 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 * 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 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 * 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 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 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 * 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 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 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 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 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 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 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 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 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 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 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)("e_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 * 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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