1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright 2000-2003 Sun Microsystems, Inc. All rights reserved. 24*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 25*7c478bd9Sstevel@tonic-gate */ 26*7c478bd9Sstevel@tonic-gate 27*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 28*7c478bd9Sstevel@tonic-gate 29*7c478bd9Sstevel@tonic-gate #include <stdio.h> 30*7c478bd9Sstevel@tonic-gate #include <string.h> 31*7c478bd9Sstevel@tonic-gate #include <stdlib.h> 32*7c478bd9Sstevel@tonic-gate #include <stdarg.h> 33*7c478bd9Sstevel@tonic-gate #include <unistd.h> 34*7c478bd9Sstevel@tonic-gate #include <errno.h> 35*7c478bd9Sstevel@tonic-gate #include <ctype.h> 36*7c478bd9Sstevel@tonic-gate 37*7c478bd9Sstevel@tonic-gate #include <fcode/private.h> 38*7c478bd9Sstevel@tonic-gate #include <fcode/log.h> 39*7c478bd9Sstevel@tonic-gate 40*7c478bd9Sstevel@tonic-gate #ifndef DEBUG_LVL 41*7c478bd9Sstevel@tonic-gate #define DEBUG_LVL 0 42*7c478bd9Sstevel@tonic-gate #endif 43*7c478bd9Sstevel@tonic-gate 44*7c478bd9Sstevel@tonic-gate struct bitab { 45*7c478bd9Sstevel@tonic-gate token_t bi_ptr; 46*7c478bd9Sstevel@tonic-gate char *bi_name; 47*7c478bd9Sstevel@tonic-gate int bi_type; 48*7c478bd9Sstevel@tonic-gate }; 49*7c478bd9Sstevel@tonic-gate 50*7c478bd9Sstevel@tonic-gate struct bitab *lookup_builtin(token_t); 51*7c478bd9Sstevel@tonic-gate 52*7c478bd9Sstevel@tonic-gate static int debug_level = DEBUG_LVL; 53*7c478bd9Sstevel@tonic-gate 54*7c478bd9Sstevel@tonic-gate void 55*7c478bd9Sstevel@tonic-gate set_interpreter_debug_level(long lvl) 56*7c478bd9Sstevel@tonic-gate { 57*7c478bd9Sstevel@tonic-gate debug_level = lvl; 58*7c478bd9Sstevel@tonic-gate } 59*7c478bd9Sstevel@tonic-gate 60*7c478bd9Sstevel@tonic-gate long 61*7c478bd9Sstevel@tonic-gate get_interpreter_debug_level(void) 62*7c478bd9Sstevel@tonic-gate { 63*7c478bd9Sstevel@tonic-gate return (debug_level); 64*7c478bd9Sstevel@tonic-gate } 65*7c478bd9Sstevel@tonic-gate 66*7c478bd9Sstevel@tonic-gate void 67*7c478bd9Sstevel@tonic-gate output_data_stack(fcode_env_t *env, int msglevel) 68*7c478bd9Sstevel@tonic-gate { 69*7c478bd9Sstevel@tonic-gate int i; 70*7c478bd9Sstevel@tonic-gate 71*7c478bd9Sstevel@tonic-gate log_message(msglevel, "( "); 72*7c478bd9Sstevel@tonic-gate if (DS > env->ds0) { 73*7c478bd9Sstevel@tonic-gate for (i = 0; i < (DS - env->ds0); i++) 74*7c478bd9Sstevel@tonic-gate log_message(msglevel, "%llx ", 75*7c478bd9Sstevel@tonic-gate (uint64_t)(env->ds0[i + 1])); 76*7c478bd9Sstevel@tonic-gate } else 77*7c478bd9Sstevel@tonic-gate log_message(msglevel, "<empty> "); 78*7c478bd9Sstevel@tonic-gate log_message(msglevel, ") "); 79*7c478bd9Sstevel@tonic-gate } 80*7c478bd9Sstevel@tonic-gate 81*7c478bd9Sstevel@tonic-gate void 82*7c478bd9Sstevel@tonic-gate output_return_stack(fcode_env_t *env, int show_wa, int msglevel) 83*7c478bd9Sstevel@tonic-gate { 84*7c478bd9Sstevel@tonic-gate int i; 85*7c478bd9Sstevel@tonic-gate int anyout = 0; 86*7c478bd9Sstevel@tonic-gate 87*7c478bd9Sstevel@tonic-gate log_message(msglevel, "R:( "); 88*7c478bd9Sstevel@tonic-gate if (show_wa) { 89*7c478bd9Sstevel@tonic-gate log_message(msglevel, "%s ", 90*7c478bd9Sstevel@tonic-gate acf_backup_search(env, (acf_t)WA)); 91*7c478bd9Sstevel@tonic-gate anyout++; 92*7c478bd9Sstevel@tonic-gate } 93*7c478bd9Sstevel@tonic-gate if (IP) { 94*7c478bd9Sstevel@tonic-gate anyout++; 95*7c478bd9Sstevel@tonic-gate log_message(msglevel, "%s ", acf_backup_search(env, IP)); 96*7c478bd9Sstevel@tonic-gate } 97*7c478bd9Sstevel@tonic-gate for (i = (RS - env->rs0) - 1; i > 0; i--) { 98*7c478bd9Sstevel@tonic-gate anyout++; 99*7c478bd9Sstevel@tonic-gate log_message(msglevel, "%s ", 100*7c478bd9Sstevel@tonic-gate acf_backup_search(env, (acf_t)env->rs0[i+1])); 101*7c478bd9Sstevel@tonic-gate } 102*7c478bd9Sstevel@tonic-gate if (!anyout) 103*7c478bd9Sstevel@tonic-gate log_message(msglevel, "<empty> "); 104*7c478bd9Sstevel@tonic-gate log_message(msglevel, ") "); 105*7c478bd9Sstevel@tonic-gate } 106*7c478bd9Sstevel@tonic-gate 107*7c478bd9Sstevel@tonic-gate void 108*7c478bd9Sstevel@tonic-gate dump_comma(fcode_env_t *env, char *type) 109*7c478bd9Sstevel@tonic-gate { 110*7c478bd9Sstevel@tonic-gate xforth_t d; 111*7c478bd9Sstevel@tonic-gate 112*7c478bd9Sstevel@tonic-gate if (strcmp(type, "x,") == 0) 113*7c478bd9Sstevel@tonic-gate d = peek_xforth(env); 114*7c478bd9Sstevel@tonic-gate else 115*7c478bd9Sstevel@tonic-gate d = TOS; 116*7c478bd9Sstevel@tonic-gate log_message(MSG_FC_DEBUG, "%s %p, %llx\n", type, HERE, (uint64_t)d); 117*7c478bd9Sstevel@tonic-gate } 118*7c478bd9Sstevel@tonic-gate 119*7c478bd9Sstevel@tonic-gate static int ndebug_names; 120*7c478bd9Sstevel@tonic-gate #define MAXDEBUG_NAMES 10 121*7c478bd9Sstevel@tonic-gate static char *debug_names[MAXDEBUG_NAMES]; 122*7c478bd9Sstevel@tonic-gate 123*7c478bd9Sstevel@tonic-gate static int ndebug_acfs; 124*7c478bd9Sstevel@tonic-gate #define MAXDEBUG_ACFS 10 125*7c478bd9Sstevel@tonic-gate static acf_t debug_acfs[MAXDEBUG_ACFS]; 126*7c478bd9Sstevel@tonic-gate 127*7c478bd9Sstevel@tonic-gate void 128*7c478bd9Sstevel@tonic-gate add_debug_acf(fcode_env_t *env, acf_t acf) 129*7c478bd9Sstevel@tonic-gate { 130*7c478bd9Sstevel@tonic-gate int i; 131*7c478bd9Sstevel@tonic-gate 132*7c478bd9Sstevel@tonic-gate for (i = 0; i < ndebug_acfs; i++) 133*7c478bd9Sstevel@tonic-gate if (acf == debug_acfs[i]) 134*7c478bd9Sstevel@tonic-gate return; 135*7c478bd9Sstevel@tonic-gate 136*7c478bd9Sstevel@tonic-gate if (!within_dictionary(env, acf)) 137*7c478bd9Sstevel@tonic-gate log_message(MSG_ERROR, "Can't debug builtin\n"); 138*7c478bd9Sstevel@tonic-gate else if (ndebug_acfs >= MAXDEBUG_ACFS) 139*7c478bd9Sstevel@tonic-gate log_message(MSG_ERROR, "Too many debug ACF's\n"); 140*7c478bd9Sstevel@tonic-gate else { 141*7c478bd9Sstevel@tonic-gate debug_acfs[ndebug_acfs++] = acf; 142*7c478bd9Sstevel@tonic-gate *LINK_TO_FLAGS(ACF_TO_LINK(acf)) |= FLAG_DEBUG; 143*7c478bd9Sstevel@tonic-gate } 144*7c478bd9Sstevel@tonic-gate } 145*7c478bd9Sstevel@tonic-gate 146*7c478bd9Sstevel@tonic-gate static void 147*7c478bd9Sstevel@tonic-gate paren_debug(fcode_env_t *env) 148*7c478bd9Sstevel@tonic-gate { 149*7c478bd9Sstevel@tonic-gate acf_t acf; 150*7c478bd9Sstevel@tonic-gate 151*7c478bd9Sstevel@tonic-gate acf = (acf_t)POP(DS); 152*7c478bd9Sstevel@tonic-gate if (!within_dictionary(env, acf)) { 153*7c478bd9Sstevel@tonic-gate log_message(MSG_INFO, "acf: %llx not in dictionary\n", 154*7c478bd9Sstevel@tonic-gate (uint64_t)acf); 155*7c478bd9Sstevel@tonic-gate return; 156*7c478bd9Sstevel@tonic-gate } 157*7c478bd9Sstevel@tonic-gate if ((acf_t)_ALIGN(acf, token_t) != acf) { 158*7c478bd9Sstevel@tonic-gate log_message(MSG_INFO, "acf: %llx not aligned\n", 159*7c478bd9Sstevel@tonic-gate (uint64_t)acf); 160*7c478bd9Sstevel@tonic-gate return; 161*7c478bd9Sstevel@tonic-gate } 162*7c478bd9Sstevel@tonic-gate if (*acf != (token_t)(&do_colon)) { 163*7c478bd9Sstevel@tonic-gate log_message(MSG_INFO, "acf: %llx not a colon-def\n", 164*7c478bd9Sstevel@tonic-gate (uint64_t)acf); 165*7c478bd9Sstevel@tonic-gate return; 166*7c478bd9Sstevel@tonic-gate } 167*7c478bd9Sstevel@tonic-gate add_debug_acf(env, acf); 168*7c478bd9Sstevel@tonic-gate } 169*7c478bd9Sstevel@tonic-gate 170*7c478bd9Sstevel@tonic-gate static void 171*7c478bd9Sstevel@tonic-gate debug(fcode_env_t *env) 172*7c478bd9Sstevel@tonic-gate { 173*7c478bd9Sstevel@tonic-gate fstack_t d; 174*7c478bd9Sstevel@tonic-gate char *word; 175*7c478bd9Sstevel@tonic-gate acf_t acf; 176*7c478bd9Sstevel@tonic-gate 177*7c478bd9Sstevel@tonic-gate parse_word(env); 178*7c478bd9Sstevel@tonic-gate dollar_find(env); 179*7c478bd9Sstevel@tonic-gate d = POP(DS); 180*7c478bd9Sstevel@tonic-gate if (d) { 181*7c478bd9Sstevel@tonic-gate acf = (acf_t)POP(DS); 182*7c478bd9Sstevel@tonic-gate add_debug_acf(env, acf); 183*7c478bd9Sstevel@tonic-gate } else if (ndebug_names >= MAXDEBUG_NAMES) { 184*7c478bd9Sstevel@tonic-gate log_message(MSG_ERROR, "Too many forward debug words\n"); 185*7c478bd9Sstevel@tonic-gate two_drop(env); 186*7c478bd9Sstevel@tonic-gate } else { 187*7c478bd9Sstevel@tonic-gate word = pop_a_duped_string(env, NULL); 188*7c478bd9Sstevel@tonic-gate log_message(MSG_INFO, "Forward defined word: %s\n", word); 189*7c478bd9Sstevel@tonic-gate debug_names[ndebug_names++] = word; 190*7c478bd9Sstevel@tonic-gate } 191*7c478bd9Sstevel@tonic-gate } 192*7c478bd9Sstevel@tonic-gate 193*7c478bd9Sstevel@tonic-gate /* 194*7c478bd9Sstevel@tonic-gate * Eliminate dups and add vocabulary forth to end if not already on list. 195*7c478bd9Sstevel@tonic-gate */ 196*7c478bd9Sstevel@tonic-gate static void 197*7c478bd9Sstevel@tonic-gate order_to_dict_list(fcode_env_t *env, token_t *order[]) 198*7c478bd9Sstevel@tonic-gate { 199*7c478bd9Sstevel@tonic-gate int i, j, norder = 0; 200*7c478bd9Sstevel@tonic-gate 201*7c478bd9Sstevel@tonic-gate if (env->current) 202*7c478bd9Sstevel@tonic-gate order[norder++] = env->current; 203*7c478bd9Sstevel@tonic-gate for (i = env->order_depth; i >= 0; i--) { 204*7c478bd9Sstevel@tonic-gate for (j = 0; j < norder && order[j] != env->order[i]; j++) 205*7c478bd9Sstevel@tonic-gate ; 206*7c478bd9Sstevel@tonic-gate if (j == norder) 207*7c478bd9Sstevel@tonic-gate order[norder++] = env->order[i]; 208*7c478bd9Sstevel@tonic-gate } 209*7c478bd9Sstevel@tonic-gate for (j = 0; j < norder && order[j] != (token_t *)&env->forth_voc_link; 210*7c478bd9Sstevel@tonic-gate j++) 211*7c478bd9Sstevel@tonic-gate ; 212*7c478bd9Sstevel@tonic-gate if (j == norder) 213*7c478bd9Sstevel@tonic-gate order[norder++] = (token_t *)&env->forth_voc_link; 214*7c478bd9Sstevel@tonic-gate order[norder] = NULL; 215*7c478bd9Sstevel@tonic-gate } 216*7c478bd9Sstevel@tonic-gate 217*7c478bd9Sstevel@tonic-gate static acf_t 218*7c478bd9Sstevel@tonic-gate search_all_dictionaries(fcode_env_t *env, 219*7c478bd9Sstevel@tonic-gate acf_t (*fn)(fcode_env_t *, acf_t, void *), 220*7c478bd9Sstevel@tonic-gate void *arg) 221*7c478bd9Sstevel@tonic-gate { 222*7c478bd9Sstevel@tonic-gate token_t *order[MAX_ORDER+1]; 223*7c478bd9Sstevel@tonic-gate int i; 224*7c478bd9Sstevel@tonic-gate token_t *dptr; 225*7c478bd9Sstevel@tonic-gate acf_t acf; 226*7c478bd9Sstevel@tonic-gate 227*7c478bd9Sstevel@tonic-gate order_to_dict_list(env, order); 228*7c478bd9Sstevel@tonic-gate for (i = 0; (dptr = order[i]) != NULL; i++) { 229*7c478bd9Sstevel@tonic-gate for (dptr = (token_t *)(*dptr); dptr; 230*7c478bd9Sstevel@tonic-gate dptr = (token_t *)(*dptr)) 231*7c478bd9Sstevel@tonic-gate if ((acf = (*fn)(env, LINK_TO_ACF(dptr), arg)) != NULL) 232*7c478bd9Sstevel@tonic-gate return (acf); 233*7c478bd9Sstevel@tonic-gate } 234*7c478bd9Sstevel@tonic-gate return (NULL); 235*7c478bd9Sstevel@tonic-gate } 236*7c478bd9Sstevel@tonic-gate 237*7c478bd9Sstevel@tonic-gate char * 238*7c478bd9Sstevel@tonic-gate acf_to_str(acf_t acf) 239*7c478bd9Sstevel@tonic-gate { 240*7c478bd9Sstevel@tonic-gate static char msg[(sizeof (acf) * 2) + 3]; 241*7c478bd9Sstevel@tonic-gate 242*7c478bd9Sstevel@tonic-gate sprintf(msg, "(%08p)", acf); 243*7c478bd9Sstevel@tonic-gate return (msg); 244*7c478bd9Sstevel@tonic-gate } 245*7c478bd9Sstevel@tonic-gate 246*7c478bd9Sstevel@tonic-gate char * 247*7c478bd9Sstevel@tonic-gate get_name_or_acf(token_t *dptr) 248*7c478bd9Sstevel@tonic-gate { 249*7c478bd9Sstevel@tonic-gate char *name; 250*7c478bd9Sstevel@tonic-gate 251*7c478bd9Sstevel@tonic-gate if ((name = get_name(dptr)) != NULL) 252*7c478bd9Sstevel@tonic-gate return (name); 253*7c478bd9Sstevel@tonic-gate return (acf_to_str(LINK_TO_ACF(dptr))); 254*7c478bd9Sstevel@tonic-gate } 255*7c478bd9Sstevel@tonic-gate 256*7c478bd9Sstevel@tonic-gate static void 257*7c478bd9Sstevel@tonic-gate output_acf_name(acf_t acf) 258*7c478bd9Sstevel@tonic-gate { 259*7c478bd9Sstevel@tonic-gate char *name; 260*7c478bd9Sstevel@tonic-gate token_t *dptr; 261*7c478bd9Sstevel@tonic-gate static int acf_count = 0; 262*7c478bd9Sstevel@tonic-gate 263*7c478bd9Sstevel@tonic-gate if (acf == NULL) { 264*7c478bd9Sstevel@tonic-gate if (acf_count) 265*7c478bd9Sstevel@tonic-gate log_message(MSG_INFO, "\n"); 266*7c478bd9Sstevel@tonic-gate acf_count = 0; 267*7c478bd9Sstevel@tonic-gate return; 268*7c478bd9Sstevel@tonic-gate } 269*7c478bd9Sstevel@tonic-gate dptr = ACF_TO_LINK(acf); 270*7c478bd9Sstevel@tonic-gate if ((name = get_name(dptr)) == NULL) 271*7c478bd9Sstevel@tonic-gate name = "<noname>"; 272*7c478bd9Sstevel@tonic-gate 273*7c478bd9Sstevel@tonic-gate log_message(MSG_INFO, "%24s (%08p)", name, acf); 274*7c478bd9Sstevel@tonic-gate if (++acf_count >= 2) { 275*7c478bd9Sstevel@tonic-gate log_message(MSG_INFO, "\n"); 276*7c478bd9Sstevel@tonic-gate acf_count = 0; 277*7c478bd9Sstevel@tonic-gate } else 278*7c478bd9Sstevel@tonic-gate log_message(MSG_INFO, " "); 279*7c478bd9Sstevel@tonic-gate } 280*7c478bd9Sstevel@tonic-gate 281*7c478bd9Sstevel@tonic-gate static void 282*7c478bd9Sstevel@tonic-gate dot_debug(fcode_env_t *env) 283*7c478bd9Sstevel@tonic-gate { 284*7c478bd9Sstevel@tonic-gate int i; 285*7c478bd9Sstevel@tonic-gate token_t *dptr; 286*7c478bd9Sstevel@tonic-gate 287*7c478bd9Sstevel@tonic-gate if (ndebug_names == 0) 288*7c478bd9Sstevel@tonic-gate log_message(MSG_INFO, "No forward debug words\n"); 289*7c478bd9Sstevel@tonic-gate else { 290*7c478bd9Sstevel@tonic-gate for (i = 0; i < ndebug_names; i++) 291*7c478bd9Sstevel@tonic-gate log_message(MSG_INFO, "%s Forward\n", debug_names[i]); 292*7c478bd9Sstevel@tonic-gate } 293*7c478bd9Sstevel@tonic-gate if (ndebug_acfs == 0) 294*7c478bd9Sstevel@tonic-gate log_message(MSG_INFO, "No debug words\n"); 295*7c478bd9Sstevel@tonic-gate else { 296*7c478bd9Sstevel@tonic-gate for (i = 0; i < ndebug_acfs; i++) 297*7c478bd9Sstevel@tonic-gate log_message(MSG_INFO, "%s\n", 298*7c478bd9Sstevel@tonic-gate get_name_or_acf(ACF_TO_LINK(debug_acfs[i]))); 299*7c478bd9Sstevel@tonic-gate } 300*7c478bd9Sstevel@tonic-gate } 301*7c478bd9Sstevel@tonic-gate 302*7c478bd9Sstevel@tonic-gate static void 303*7c478bd9Sstevel@tonic-gate do_undebug(fcode_env_t *env, char *name) 304*7c478bd9Sstevel@tonic-gate { 305*7c478bd9Sstevel@tonic-gate int i; 306*7c478bd9Sstevel@tonic-gate 307*7c478bd9Sstevel@tonic-gate for (i = 0; i < ndebug_names; i++) { 308*7c478bd9Sstevel@tonic-gate if (strcmp(debug_names[i], name) == 0) { 309*7c478bd9Sstevel@tonic-gate log_message(MSG_INFO, "Undebugging forward word %s\n", 310*7c478bd9Sstevel@tonic-gate name); 311*7c478bd9Sstevel@tonic-gate FREE(debug_names[i]); 312*7c478bd9Sstevel@tonic-gate for (i++; i < ndebug_names; i++) 313*7c478bd9Sstevel@tonic-gate debug_names[i - 1] = debug_names[i]; 314*7c478bd9Sstevel@tonic-gate ndebug_names--; 315*7c478bd9Sstevel@tonic-gate break; 316*7c478bd9Sstevel@tonic-gate } 317*7c478bd9Sstevel@tonic-gate } 318*7c478bd9Sstevel@tonic-gate } 319*7c478bd9Sstevel@tonic-gate 320*7c478bd9Sstevel@tonic-gate static void 321*7c478bd9Sstevel@tonic-gate undebug(fcode_env_t *env) 322*7c478bd9Sstevel@tonic-gate { 323*7c478bd9Sstevel@tonic-gate fstack_t d; 324*7c478bd9Sstevel@tonic-gate acf_t acf; 325*7c478bd9Sstevel@tonic-gate flag_t *flagp; 326*7c478bd9Sstevel@tonic-gate char *name; 327*7c478bd9Sstevel@tonic-gate int i, j; 328*7c478bd9Sstevel@tonic-gate 329*7c478bd9Sstevel@tonic-gate parse_word(env); 330*7c478bd9Sstevel@tonic-gate two_dup(env); 331*7c478bd9Sstevel@tonic-gate dollar_find(env); 332*7c478bd9Sstevel@tonic-gate d = POP(DS); 333*7c478bd9Sstevel@tonic-gate if (d) { 334*7c478bd9Sstevel@tonic-gate acf = (acf_t)POP(DS); 335*7c478bd9Sstevel@tonic-gate flagp = LINK_TO_FLAGS(ACF_TO_LINK(acf)); 336*7c478bd9Sstevel@tonic-gate if ((*flagp & FLAG_DEBUG) == 0) 337*7c478bd9Sstevel@tonic-gate log_message(MSG_WARN, "Word not debugged?\n"); 338*7c478bd9Sstevel@tonic-gate else { 339*7c478bd9Sstevel@tonic-gate log_message(MSG_INFO, "Undebugging acf: %p\n", acf); 340*7c478bd9Sstevel@tonic-gate *flagp &= ~FLAG_DEBUG; 341*7c478bd9Sstevel@tonic-gate for (i = 0; i < ndebug_acfs; i++) { 342*7c478bd9Sstevel@tonic-gate if (debug_acfs[i] == acf) { 343*7c478bd9Sstevel@tonic-gate for (j = i + 1; j < ndebug_acfs; j++) 344*7c478bd9Sstevel@tonic-gate debug_acfs[j-1] = debug_acfs[j]; 345*7c478bd9Sstevel@tonic-gate ndebug_acfs--; 346*7c478bd9Sstevel@tonic-gate break; 347*7c478bd9Sstevel@tonic-gate } 348*7c478bd9Sstevel@tonic-gate } 349*7c478bd9Sstevel@tonic-gate } 350*7c478bd9Sstevel@tonic-gate } else 351*7c478bd9Sstevel@tonic-gate two_drop(env); 352*7c478bd9Sstevel@tonic-gate name = pop_a_string(env, NULL); 353*7c478bd9Sstevel@tonic-gate do_undebug(env, name); 354*7c478bd9Sstevel@tonic-gate } 355*7c478bd9Sstevel@tonic-gate 356*7c478bd9Sstevel@tonic-gate int 357*7c478bd9Sstevel@tonic-gate name_is_debugged(fcode_env_t *env, char *name) 358*7c478bd9Sstevel@tonic-gate { 359*7c478bd9Sstevel@tonic-gate int i; 360*7c478bd9Sstevel@tonic-gate 361*7c478bd9Sstevel@tonic-gate if (ndebug_names <= 0) 362*7c478bd9Sstevel@tonic-gate return (0); 363*7c478bd9Sstevel@tonic-gate for (i = 0; i < ndebug_names; i++) 364*7c478bd9Sstevel@tonic-gate if (strcmp(debug_names[i], name) == 0) 365*7c478bd9Sstevel@tonic-gate return (1); 366*7c478bd9Sstevel@tonic-gate return (0); 367*7c478bd9Sstevel@tonic-gate } 368*7c478bd9Sstevel@tonic-gate 369*7c478bd9Sstevel@tonic-gate /* 370*7c478bd9Sstevel@tonic-gate * This is complicated by being given ACF's to temporary compile words which 371*7c478bd9Sstevel@tonic-gate * don't have a header. 372*7c478bd9Sstevel@tonic-gate */ 373*7c478bd9Sstevel@tonic-gate int 374*7c478bd9Sstevel@tonic-gate is_debug_word(fcode_env_t *env, acf_t acf) 375*7c478bd9Sstevel@tonic-gate { 376*7c478bd9Sstevel@tonic-gate flag_t *flagp; 377*7c478bd9Sstevel@tonic-gate int i; 378*7c478bd9Sstevel@tonic-gate 379*7c478bd9Sstevel@tonic-gate /* check to see if any words are being debugged */ 380*7c478bd9Sstevel@tonic-gate if (ndebug_acfs == 0) 381*7c478bd9Sstevel@tonic-gate return (0); 382*7c478bd9Sstevel@tonic-gate 383*7c478bd9Sstevel@tonic-gate /* only words in dictionary can be debugged */ 384*7c478bd9Sstevel@tonic-gate if (!within_dictionary(env, acf)) 385*7c478bd9Sstevel@tonic-gate return (0); 386*7c478bd9Sstevel@tonic-gate 387*7c478bd9Sstevel@tonic-gate /* check that word has "FLAG_DEBUG" on */ 388*7c478bd9Sstevel@tonic-gate flagp = LINK_TO_FLAGS(ACF_TO_LINK(acf)); 389*7c478bd9Sstevel@tonic-gate if ((*flagp & FLAG_DEBUG) == 0) 390*7c478bd9Sstevel@tonic-gate return (0); 391*7c478bd9Sstevel@tonic-gate 392*7c478bd9Sstevel@tonic-gate /* look in table of debug acf's */ 393*7c478bd9Sstevel@tonic-gate for (i = 0; i < ndebug_acfs; i++) 394*7c478bd9Sstevel@tonic-gate if (debug_acfs[i] == acf) 395*7c478bd9Sstevel@tonic-gate return (1); 396*7c478bd9Sstevel@tonic-gate return (0); 397*7c478bd9Sstevel@tonic-gate } 398*7c478bd9Sstevel@tonic-gate 399*7c478bd9Sstevel@tonic-gate #define MAX_DEBUG_STACK 100 400*7c478bd9Sstevel@tonic-gate token_t debug_low[MAX_DEBUG_STACK], debug_high[MAX_DEBUG_STACK]; 401*7c478bd9Sstevel@tonic-gate int debug_prev_level[MAX_DEBUG_STACK]; 402*7c478bd9Sstevel@tonic-gate int debug_curr_level[MAX_DEBUG_STACK]; 403*7c478bd9Sstevel@tonic-gate int ndebug_stack = 0; 404*7c478bd9Sstevel@tonic-gate 405*7c478bd9Sstevel@tonic-gate void 406*7c478bd9Sstevel@tonic-gate debug_set_level(fcode_env_t *env, int level) 407*7c478bd9Sstevel@tonic-gate { 408*7c478bd9Sstevel@tonic-gate debug_curr_level[ndebug_stack - 1] = level; 409*7c478bd9Sstevel@tonic-gate set_interpreter_debug_level(level); 410*7c478bd9Sstevel@tonic-gate } 411*7c478bd9Sstevel@tonic-gate 412*7c478bd9Sstevel@tonic-gate token_t 413*7c478bd9Sstevel@tonic-gate find_semi_in_colon_def(fcode_env_t *env, acf_t acf) 414*7c478bd9Sstevel@tonic-gate { 415*7c478bd9Sstevel@tonic-gate for (; within_dictionary(env, acf); acf++) 416*7c478bd9Sstevel@tonic-gate if (*acf == (token_t)(&semi_ptr)) 417*7c478bd9Sstevel@tonic-gate return ((token_t)acf); 418*7c478bd9Sstevel@tonic-gate return (0); 419*7c478bd9Sstevel@tonic-gate } 420*7c478bd9Sstevel@tonic-gate 421*7c478bd9Sstevel@tonic-gate void 422*7c478bd9Sstevel@tonic-gate check_for_debug_entry(fcode_env_t *env) 423*7c478bd9Sstevel@tonic-gate { 424*7c478bd9Sstevel@tonic-gate int top; 425*7c478bd9Sstevel@tonic-gate 426*7c478bd9Sstevel@tonic-gate if (is_debug_word(env, WA) && ndebug_stack < MAX_DEBUG_STACK) { 427*7c478bd9Sstevel@tonic-gate top = ndebug_stack++; 428*7c478bd9Sstevel@tonic-gate debug_prev_level[top] = get_interpreter_debug_level(); 429*7c478bd9Sstevel@tonic-gate debug_low[top] = (token_t)WA; 430*7c478bd9Sstevel@tonic-gate if (*WA == (token_t)(&do_colon)) { 431*7c478bd9Sstevel@tonic-gate debug_high[top] = 432*7c478bd9Sstevel@tonic-gate find_semi_in_colon_def(env, WA); 433*7c478bd9Sstevel@tonic-gate } else { 434*7c478bd9Sstevel@tonic-gate debug_high[top] = 0; /* marker... */ 435*7c478bd9Sstevel@tonic-gate } 436*7c478bd9Sstevel@tonic-gate debug_set_level(env, DEBUG_STEPPING); 437*7c478bd9Sstevel@tonic-gate output_step_message(env); 438*7c478bd9Sstevel@tonic-gate } 439*7c478bd9Sstevel@tonic-gate } 440*7c478bd9Sstevel@tonic-gate 441*7c478bd9Sstevel@tonic-gate void 442*7c478bd9Sstevel@tonic-gate check_for_debug_exit(fcode_env_t *env) 443*7c478bd9Sstevel@tonic-gate { 444*7c478bd9Sstevel@tonic-gate if (ndebug_stack) { 445*7c478bd9Sstevel@tonic-gate int top = ndebug_stack - 1; 446*7c478bd9Sstevel@tonic-gate 447*7c478bd9Sstevel@tonic-gate if (debug_high[top] == 0) { 448*7c478bd9Sstevel@tonic-gate set_interpreter_debug_level(debug_prev_level[top]); 449*7c478bd9Sstevel@tonic-gate ndebug_stack--; 450*7c478bd9Sstevel@tonic-gate } else if ((token_t)IP >= debug_low[top] && 451*7c478bd9Sstevel@tonic-gate (token_t)IP <= debug_high[top]) { 452*7c478bd9Sstevel@tonic-gate set_interpreter_debug_level(debug_curr_level[top]); 453*7c478bd9Sstevel@tonic-gate } else { 454*7c478bd9Sstevel@tonic-gate set_interpreter_debug_level(debug_prev_level[top]); 455*7c478bd9Sstevel@tonic-gate } 456*7c478bd9Sstevel@tonic-gate } 457*7c478bd9Sstevel@tonic-gate } 458*7c478bd9Sstevel@tonic-gate 459*7c478bd9Sstevel@tonic-gate void 460*7c478bd9Sstevel@tonic-gate check_semi_debug_exit(fcode_env_t *env) 461*7c478bd9Sstevel@tonic-gate { 462*7c478bd9Sstevel@tonic-gate if (ndebug_stack) { 463*7c478bd9Sstevel@tonic-gate int top = ndebug_stack - 1; 464*7c478bd9Sstevel@tonic-gate 465*7c478bd9Sstevel@tonic-gate if ((token_t)(IP - 1) == debug_high[top]) { 466*7c478bd9Sstevel@tonic-gate set_interpreter_debug_level(debug_prev_level[top]); 467*7c478bd9Sstevel@tonic-gate ndebug_stack--; 468*7c478bd9Sstevel@tonic-gate } 469*7c478bd9Sstevel@tonic-gate } 470*7c478bd9Sstevel@tonic-gate } 471*7c478bd9Sstevel@tonic-gate 472*7c478bd9Sstevel@tonic-gate /* 473*7c478bd9Sstevel@tonic-gate * Really entering do_run, since this may be a recursive entry to do_run, 474*7c478bd9Sstevel@tonic-gate * we need to set the debug level to what it was previously. 475*7c478bd9Sstevel@tonic-gate */ 476*7c478bd9Sstevel@tonic-gate int 477*7c478bd9Sstevel@tonic-gate current_debug_state(fcode_env_t *env) 478*7c478bd9Sstevel@tonic-gate { 479*7c478bd9Sstevel@tonic-gate if (ndebug_stack) { 480*7c478bd9Sstevel@tonic-gate int top = ndebug_stack - 1; 481*7c478bd9Sstevel@tonic-gate set_interpreter_debug_level(debug_prev_level[top]); 482*7c478bd9Sstevel@tonic-gate } 483*7c478bd9Sstevel@tonic-gate return (ndebug_stack); 484*7c478bd9Sstevel@tonic-gate } 485*7c478bd9Sstevel@tonic-gate 486*7c478bd9Sstevel@tonic-gate void 487*7c478bd9Sstevel@tonic-gate clear_debug_state(fcode_env_t *env, int oldstate) 488*7c478bd9Sstevel@tonic-gate { 489*7c478bd9Sstevel@tonic-gate if (ndebug_stack && oldstate <= ndebug_stack) { 490*7c478bd9Sstevel@tonic-gate set_interpreter_debug_level(debug_prev_level[oldstate]); 491*7c478bd9Sstevel@tonic-gate ndebug_stack = oldstate; 492*7c478bd9Sstevel@tonic-gate } 493*7c478bd9Sstevel@tonic-gate } 494*7c478bd9Sstevel@tonic-gate 495*7c478bd9Sstevel@tonic-gate void 496*7c478bd9Sstevel@tonic-gate unbug(fcode_env_t *env) 497*7c478bd9Sstevel@tonic-gate { 498*7c478bd9Sstevel@tonic-gate int i; 499*7c478bd9Sstevel@tonic-gate token_t *link; 500*7c478bd9Sstevel@tonic-gate flag_t *flag; 501*7c478bd9Sstevel@tonic-gate 502*7c478bd9Sstevel@tonic-gate for (i = ndebug_stack - 1; i >= 0; i--) { 503*7c478bd9Sstevel@tonic-gate link = ACF_TO_LINK(debug_low[i]); 504*7c478bd9Sstevel@tonic-gate flag = LINK_TO_FLAGS(link); 505*7c478bd9Sstevel@tonic-gate *flag &= ~FLAG_DEBUG; 506*7c478bd9Sstevel@tonic-gate } 507*7c478bd9Sstevel@tonic-gate clear_debug_state(env, 0); 508*7c478bd9Sstevel@tonic-gate } 509*7c478bd9Sstevel@tonic-gate 510*7c478bd9Sstevel@tonic-gate void 511*7c478bd9Sstevel@tonic-gate output_vitals(fcode_env_t *env) 512*7c478bd9Sstevel@tonic-gate { 513*7c478bd9Sstevel@tonic-gate log_message(MSG_FC_DEBUG, "IP=%p, *IP=%p, WA=%p, *WA=%p ", IP, 514*7c478bd9Sstevel@tonic-gate (IP ? *IP : 0), WA, (WA ? *WA : 0)); 515*7c478bd9Sstevel@tonic-gate } 516*7c478bd9Sstevel@tonic-gate 517*7c478bd9Sstevel@tonic-gate int 518*7c478bd9Sstevel@tonic-gate do_exec_debug(fcode_env_t *env, void *fn) 519*7c478bd9Sstevel@tonic-gate { 520*7c478bd9Sstevel@tonic-gate int dl = debug_level; 521*7c478bd9Sstevel@tonic-gate int show_wa = 1; 522*7c478bd9Sstevel@tonic-gate 523*7c478bd9Sstevel@tonic-gate if ((dl & (DEBUG_EXEC_DUMP_DS | DEBUG_EXEC_DUMP_RS | 524*7c478bd9Sstevel@tonic-gate DEBUG_EXEC_SHOW_VITALS | DEBUG_EXEC_TRACE | DEBUG_TRACING | 525*7c478bd9Sstevel@tonic-gate DEBUG_STEPPING)) == 0) 526*7c478bd9Sstevel@tonic-gate return (0); 527*7c478bd9Sstevel@tonic-gate 528*7c478bd9Sstevel@tonic-gate if (dl & DEBUG_STEPPING) { 529*7c478bd9Sstevel@tonic-gate dl |= DEBUG_EXEC_DUMP_DS; 530*7c478bd9Sstevel@tonic-gate } 531*7c478bd9Sstevel@tonic-gate if (dl & (DEBUG_STEPPING | DEBUG_EXEC_TRACE)) { 532*7c478bd9Sstevel@tonic-gate log_message(MSG_FC_DEBUG, "%-15s ", acf_to_name(env, WA)); 533*7c478bd9Sstevel@tonic-gate show_wa = 0; 534*7c478bd9Sstevel@tonic-gate } 535*7c478bd9Sstevel@tonic-gate if (dl & DEBUG_EXEC_DUMP_DS) 536*7c478bd9Sstevel@tonic-gate output_data_stack(env, MSG_FC_DEBUG); 537*7c478bd9Sstevel@tonic-gate if (dl & DEBUG_EXEC_DUMP_RS) 538*7c478bd9Sstevel@tonic-gate output_return_stack(env, show_wa, MSG_FC_DEBUG); 539*7c478bd9Sstevel@tonic-gate if (dl & DEBUG_EXEC_SHOW_VITALS) 540*7c478bd9Sstevel@tonic-gate output_vitals(env); 541*7c478bd9Sstevel@tonic-gate if (dl & DEBUG_TRACING) 542*7c478bd9Sstevel@tonic-gate do_fclib_trace(env, (void *) fn); 543*7c478bd9Sstevel@tonic-gate log_message(MSG_FC_DEBUG, "\n"); 544*7c478bd9Sstevel@tonic-gate if (dl & DEBUG_STEPPING) 545*7c478bd9Sstevel@tonic-gate return (do_fclib_step(env)); 546*7c478bd9Sstevel@tonic-gate return (0); 547*7c478bd9Sstevel@tonic-gate } 548*7c478bd9Sstevel@tonic-gate 549*7c478bd9Sstevel@tonic-gate static void 550*7c478bd9Sstevel@tonic-gate smatch(fcode_env_t *env) 551*7c478bd9Sstevel@tonic-gate { 552*7c478bd9Sstevel@tonic-gate int len; 553*7c478bd9Sstevel@tonic-gate char *str, *p; 554*7c478bd9Sstevel@tonic-gate 555*7c478bd9Sstevel@tonic-gate if ((str = parse_a_string(env, &len)) == NULL) 556*7c478bd9Sstevel@tonic-gate log_message(MSG_INFO, "smatch: no string\n"); 557*7c478bd9Sstevel@tonic-gate else { 558*7c478bd9Sstevel@tonic-gate for (p = (char *)env->base; p < (char *)HERE; p++) 559*7c478bd9Sstevel@tonic-gate if (memcmp(p, str, len) == 0) 560*7c478bd9Sstevel@tonic-gate log_message(MSG_DEBUG, "%p\n", p); 561*7c478bd9Sstevel@tonic-gate } 562*7c478bd9Sstevel@tonic-gate } 563*7c478bd9Sstevel@tonic-gate 564*7c478bd9Sstevel@tonic-gate void 565*7c478bd9Sstevel@tonic-gate check_vitals(fcode_env_t *env) 566*7c478bd9Sstevel@tonic-gate { 567*7c478bd9Sstevel@tonic-gate int i; 568*7c478bd9Sstevel@tonic-gate token_t *dptr; 569*7c478bd9Sstevel@tonic-gate 570*7c478bd9Sstevel@tonic-gate dptr = env->current; 571*7c478bd9Sstevel@tonic-gate if (*dptr && !within_dictionary(env, (uchar_t *)*dptr)) 572*7c478bd9Sstevel@tonic-gate log_message(MSG_ERROR, "Current: %p outside dictionary\n", 573*7c478bd9Sstevel@tonic-gate *dptr); 574*7c478bd9Sstevel@tonic-gate for (i = env->order_depth; i >= 0; i--) { 575*7c478bd9Sstevel@tonic-gate dptr = env->order[i]; 576*7c478bd9Sstevel@tonic-gate if (!dptr) 577*7c478bd9Sstevel@tonic-gate continue; 578*7c478bd9Sstevel@tonic-gate if (*dptr && !within_dictionary(env, (uchar_t *)*dptr)) 579*7c478bd9Sstevel@tonic-gate log_message(MSG_ERROR, "Order%d: %p outside" 580*7c478bd9Sstevel@tonic-gate " dictionary\n", i, *dptr); 581*7c478bd9Sstevel@tonic-gate } 582*7c478bd9Sstevel@tonic-gate if (HERE < env->base || HERE >= env->base + dict_size) { 583*7c478bd9Sstevel@tonic-gate log_message(MSG_ERROR, "HERE: %p outside range\n", HERE); 584*7c478bd9Sstevel@tonic-gate } 585*7c478bd9Sstevel@tonic-gate if (DS < env->ds0 || DS >= &env->ds0[stack_size]) { 586*7c478bd9Sstevel@tonic-gate forth_abort(env, "DS: %p outside range\n", DS); 587*7c478bd9Sstevel@tonic-gate } 588*7c478bd9Sstevel@tonic-gate if (RS < env->rs0 || RS >= &env->rs0[stack_size]) { 589*7c478bd9Sstevel@tonic-gate log_message(MSG_ERROR, "RS: %p outside range\n", RS); 590*7c478bd9Sstevel@tonic-gate RS = env->rs0; 591*7c478bd9Sstevel@tonic-gate } 592*7c478bd9Sstevel@tonic-gate if (IP && !within_dictionary(env, IP)) 593*7c478bd9Sstevel@tonic-gate log_message(MSG_ERROR, "IP: %p outside dictionary\n", IP); 594*7c478bd9Sstevel@tonic-gate if (!within_dictionary(env, (void *)env->forth_voc_link)) 595*7c478bd9Sstevel@tonic-gate log_message(MSG_ERROR, "forth_voc_link: %p outside" 596*7c478bd9Sstevel@tonic-gate " dictionary\n", env->forth_voc_link); 597*7c478bd9Sstevel@tonic-gate } 598*7c478bd9Sstevel@tonic-gate 599*7c478bd9Sstevel@tonic-gate static void 600*7c478bd9Sstevel@tonic-gate dump_table(fcode_env_t *env) 601*7c478bd9Sstevel@tonic-gate { 602*7c478bd9Sstevel@tonic-gate int i; 603*7c478bd9Sstevel@tonic-gate 604*7c478bd9Sstevel@tonic-gate for (i = 0; i < MAX_FCODE; i++) { 605*7c478bd9Sstevel@tonic-gate if (*(env->table[i].apf) != (token_t)(&f_error)) { 606*7c478bd9Sstevel@tonic-gate log_message(MSG_DEBUG, "Token: %4x %32s acf = %8p," 607*7c478bd9Sstevel@tonic-gate " %8p\n", i, env->table[i].name, env->table[i].apf, 608*7c478bd9Sstevel@tonic-gate *(env->table[i].apf)); 609*7c478bd9Sstevel@tonic-gate } 610*7c478bd9Sstevel@tonic-gate } 611*7c478bd9Sstevel@tonic-gate log_message(MSG_DEBUG, "%d FCODES implemented\n", fcode_impl_count); 612*7c478bd9Sstevel@tonic-gate } 613*7c478bd9Sstevel@tonic-gate 614*7c478bd9Sstevel@tonic-gate void 615*7c478bd9Sstevel@tonic-gate verify_usage(fcode_env_t *env) 616*7c478bd9Sstevel@tonic-gate { 617*7c478bd9Sstevel@tonic-gate int i, untested = 0; 618*7c478bd9Sstevel@tonic-gate 619*7c478bd9Sstevel@tonic-gate for (i = 0; i < MAX_FCODE; i++) { 620*7c478bd9Sstevel@tonic-gate int verify; 621*7c478bd9Sstevel@tonic-gate 622*7c478bd9Sstevel@tonic-gate verify = env->table[i].flags & (ANSI_WORD|P1275_WORD); 623*7c478bd9Sstevel@tonic-gate if ((verify) && 624*7c478bd9Sstevel@tonic-gate #ifdef DEBUG 625*7c478bd9Sstevel@tonic-gate (env->table[i].usage == 0) && 626*7c478bd9Sstevel@tonic-gate #endif 627*7c478bd9Sstevel@tonic-gate (env->table[i].apf)) { 628*7c478bd9Sstevel@tonic-gate log_message(MSG_DEBUG, 629*7c478bd9Sstevel@tonic-gate "Untested: %4x %32s acf = %8p, %8p\n", i, 630*7c478bd9Sstevel@tonic-gate env->table[i].name, env->table[i].apf, 631*7c478bd9Sstevel@tonic-gate *(env->table[i].apf)); 632*7c478bd9Sstevel@tonic-gate untested++; 633*7c478bd9Sstevel@tonic-gate } 634*7c478bd9Sstevel@tonic-gate } 635*7c478bd9Sstevel@tonic-gate if (untested) 636*7c478bd9Sstevel@tonic-gate log_message(MSG_DEBUG, "%d untested tokens\n", untested); 637*7c478bd9Sstevel@tonic-gate } 638*7c478bd9Sstevel@tonic-gate 639*7c478bd9Sstevel@tonic-gate static void 640*7c478bd9Sstevel@tonic-gate debugf(fcode_env_t *env) 641*7c478bd9Sstevel@tonic-gate { 642*7c478bd9Sstevel@tonic-gate PUSH(DS, (fstack_t)&debug_level); 643*7c478bd9Sstevel@tonic-gate } 644*7c478bd9Sstevel@tonic-gate 645*7c478bd9Sstevel@tonic-gate static void 646*7c478bd9Sstevel@tonic-gate control(fcode_env_t *env) 647*7c478bd9Sstevel@tonic-gate { 648*7c478bd9Sstevel@tonic-gate PUSH(DS, (fstack_t)&env->control); 649*7c478bd9Sstevel@tonic-gate } 650*7c478bd9Sstevel@tonic-gate 651*7c478bd9Sstevel@tonic-gate struct bittab { 652*7c478bd9Sstevel@tonic-gate int b_bitval; 653*7c478bd9Sstevel@tonic-gate char *b_bitname; 654*7c478bd9Sstevel@tonic-gate } bittab[] = { 655*7c478bd9Sstevel@tonic-gate DEBUG_CONTEXT, "context", 656*7c478bd9Sstevel@tonic-gate DEBUG_BYTELOAD_DS, "byteload-ds", 657*7c478bd9Sstevel@tonic-gate DEBUG_BYTELOAD_RS, "byteload-rs", 658*7c478bd9Sstevel@tonic-gate DEBUG_BYTELOAD_TOKENS, "byteload-tokens", 659*7c478bd9Sstevel@tonic-gate DEBUG_NEW_TOKEN, "new-token", 660*7c478bd9Sstevel@tonic-gate DEBUG_EXEC_TRACE, "exec-trace", 661*7c478bd9Sstevel@tonic-gate DEBUG_EXEC_SHOW_VITALS, "exec-show-vitals", 662*7c478bd9Sstevel@tonic-gate DEBUG_EXEC_DUMP_DS, "exec-dump-ds", 663*7c478bd9Sstevel@tonic-gate DEBUG_EXEC_DUMP_RS, "exec-dump-rs", 664*7c478bd9Sstevel@tonic-gate DEBUG_COMMA, "comma", 665*7c478bd9Sstevel@tonic-gate DEBUG_HEADER, "header", 666*7c478bd9Sstevel@tonic-gate DEBUG_EXIT_WORDS, "exit-words", 667*7c478bd9Sstevel@tonic-gate DEBUG_EXIT_DUMP, "exit-dump", 668*7c478bd9Sstevel@tonic-gate DEBUG_DUMP_TOKENS, "dump-tokens", 669*7c478bd9Sstevel@tonic-gate DEBUG_COLON, "colon", 670*7c478bd9Sstevel@tonic-gate DEBUG_NEXT_VITALS, "next-vitals", 671*7c478bd9Sstevel@tonic-gate DEBUG_VOC_FIND, "voc-find", 672*7c478bd9Sstevel@tonic-gate DEBUG_DUMP_DICT_TOKENS, "dump-dict-tokens", 673*7c478bd9Sstevel@tonic-gate DEBUG_TOKEN_USAGE, "token-usage", 674*7c478bd9Sstevel@tonic-gate DEBUG_DUMP_TOKEN_TABLE, "dump-token-table", 675*7c478bd9Sstevel@tonic-gate DEBUG_SHOW_STACK, "show-stack", 676*7c478bd9Sstevel@tonic-gate DEBUG_SHOW_RS, "show-rs", 677*7c478bd9Sstevel@tonic-gate DEBUG_TRACING, "tracing", 678*7c478bd9Sstevel@tonic-gate DEBUG_TRACE_STACK, "trace-stack", 679*7c478bd9Sstevel@tonic-gate DEBUG_CALL_METHOD, "call-method", 680*7c478bd9Sstevel@tonic-gate DEBUG_ACTIONS, "actions", 681*7c478bd9Sstevel@tonic-gate DEBUG_STEPPING, "stepping", 682*7c478bd9Sstevel@tonic-gate DEBUG_REG_ACCESS, "reg-access", 683*7c478bd9Sstevel@tonic-gate DEBUG_ADDR_ABUSE, "addr-abuse", 684*7c478bd9Sstevel@tonic-gate DEBUG_FIND_FCODE, "find-fcode", 685*7c478bd9Sstevel@tonic-gate DEBUG_UPLOAD, "upload", 686*7c478bd9Sstevel@tonic-gate 0 687*7c478bd9Sstevel@tonic-gate }; 688*7c478bd9Sstevel@tonic-gate 689*7c478bd9Sstevel@tonic-gate void 690*7c478bd9Sstevel@tonic-gate debug_flags_to_output(fcode_env_t *env, int flags) 691*7c478bd9Sstevel@tonic-gate { 692*7c478bd9Sstevel@tonic-gate int first = 1, i; 693*7c478bd9Sstevel@tonic-gate 694*7c478bd9Sstevel@tonic-gate for (i = 0; bittab[i].b_bitval != 0; i++) 695*7c478bd9Sstevel@tonic-gate if (bittab[i].b_bitval & flags) { 696*7c478bd9Sstevel@tonic-gate if (!first) 697*7c478bd9Sstevel@tonic-gate log_message(MSG_INFO, ","); 698*7c478bd9Sstevel@tonic-gate first = 0; 699*7c478bd9Sstevel@tonic-gate log_message(MSG_INFO, bittab[i].b_bitname); 700*7c478bd9Sstevel@tonic-gate } 701*7c478bd9Sstevel@tonic-gate if (first) 702*7c478bd9Sstevel@tonic-gate log_message(MSG_INFO, "<empty>"); 703*7c478bd9Sstevel@tonic-gate log_message(MSG_INFO, "\n"); 704*7c478bd9Sstevel@tonic-gate } 705*7c478bd9Sstevel@tonic-gate 706*7c478bd9Sstevel@tonic-gate static void 707*7c478bd9Sstevel@tonic-gate dot_debugf(fcode_env_t *env) 708*7c478bd9Sstevel@tonic-gate { 709*7c478bd9Sstevel@tonic-gate debug_flags_to_output(env, debug_level); 710*7c478bd9Sstevel@tonic-gate } 711*7c478bd9Sstevel@tonic-gate 712*7c478bd9Sstevel@tonic-gate static void 713*7c478bd9Sstevel@tonic-gate debugf_qmark(fcode_env_t *env) 714*7c478bd9Sstevel@tonic-gate { 715*7c478bd9Sstevel@tonic-gate debug_flags_to_output(env, 0xffffffff); 716*7c478bd9Sstevel@tonic-gate } 717*7c478bd9Sstevel@tonic-gate 718*7c478bd9Sstevel@tonic-gate int 719*7c478bd9Sstevel@tonic-gate debug_flags_to_mask(char *str) 720*7c478bd9Sstevel@tonic-gate { 721*7c478bd9Sstevel@tonic-gate int flags = 0; 722*7c478bd9Sstevel@tonic-gate char *p; 723*7c478bd9Sstevel@tonic-gate int i; 724*7c478bd9Sstevel@tonic-gate 725*7c478bd9Sstevel@tonic-gate if (isdigit(*str)) { 726*7c478bd9Sstevel@tonic-gate if (*str == '0') { 727*7c478bd9Sstevel@tonic-gate str++; 728*7c478bd9Sstevel@tonic-gate if (*str == 'x' || *str == 'X') { 729*7c478bd9Sstevel@tonic-gate sscanf(str + 1, "%x", &flags); 730*7c478bd9Sstevel@tonic-gate } else 731*7c478bd9Sstevel@tonic-gate sscanf(str, "%o", &flags); 732*7c478bd9Sstevel@tonic-gate } else 733*7c478bd9Sstevel@tonic-gate sscanf(str, "%d", &flags); 734*7c478bd9Sstevel@tonic-gate return (flags); 735*7c478bd9Sstevel@tonic-gate } 736*7c478bd9Sstevel@tonic-gate if (strcmp(str, "clear") == 0) 737*7c478bd9Sstevel@tonic-gate return (0); 738*7c478bd9Sstevel@tonic-gate if (strcmp(str, "all") == 0) 739*7c478bd9Sstevel@tonic-gate return (0xffffffff & ~DEBUG_STEPPING); 740*7c478bd9Sstevel@tonic-gate if (*str) { 741*7c478bd9Sstevel@tonic-gate do { 742*7c478bd9Sstevel@tonic-gate if (p = strchr(str, ',')) 743*7c478bd9Sstevel@tonic-gate *p++ = '\0'; 744*7c478bd9Sstevel@tonic-gate for (i = 0; bittab[i].b_bitname != 0; i++) 745*7c478bd9Sstevel@tonic-gate if (strcmp(str, bittab[i].b_bitname) == 0) { 746*7c478bd9Sstevel@tonic-gate flags |= bittab[i].b_bitval; 747*7c478bd9Sstevel@tonic-gate break; 748*7c478bd9Sstevel@tonic-gate } 749*7c478bd9Sstevel@tonic-gate if (bittab[i].b_bitname == 0) 750*7c478bd9Sstevel@tonic-gate log_message(MSG_WARN, 751*7c478bd9Sstevel@tonic-gate "Unknown debug flag: '%s'\n", str); 752*7c478bd9Sstevel@tonic-gate str = p; 753*7c478bd9Sstevel@tonic-gate } while (p); 754*7c478bd9Sstevel@tonic-gate } 755*7c478bd9Sstevel@tonic-gate return (flags); 756*7c478bd9Sstevel@tonic-gate } 757*7c478bd9Sstevel@tonic-gate 758*7c478bd9Sstevel@tonic-gate static void 759*7c478bd9Sstevel@tonic-gate set_debugf(fcode_env_t *env) 760*7c478bd9Sstevel@tonic-gate { 761*7c478bd9Sstevel@tonic-gate char *str; 762*7c478bd9Sstevel@tonic-gate 763*7c478bd9Sstevel@tonic-gate str = parse_a_string(env, NULL); 764*7c478bd9Sstevel@tonic-gate debug_level = debug_flags_to_mask(str); 765*7c478bd9Sstevel@tonic-gate } 766*7c478bd9Sstevel@tonic-gate 767*7c478bd9Sstevel@tonic-gate static acf_t 768*7c478bd9Sstevel@tonic-gate show_a_word(fcode_env_t *env, acf_t acf, void *arg) 769*7c478bd9Sstevel@tonic-gate { 770*7c478bd9Sstevel@tonic-gate static int nshow_words = 0; 771*7c478bd9Sstevel@tonic-gate 772*7c478bd9Sstevel@tonic-gate if (acf == NULL) { 773*7c478bd9Sstevel@tonic-gate if (nshow_words > 0) { 774*7c478bd9Sstevel@tonic-gate log_message(MSG_DEBUG, "\n"); 775*7c478bd9Sstevel@tonic-gate nshow_words = 0; 776*7c478bd9Sstevel@tonic-gate } 777*7c478bd9Sstevel@tonic-gate return (NULL); 778*7c478bd9Sstevel@tonic-gate } 779*7c478bd9Sstevel@tonic-gate log_message(MSG_DEBUG, "%15s ", get_name_or_acf(ACF_TO_LINK(acf))); 780*7c478bd9Sstevel@tonic-gate nshow_words++; 781*7c478bd9Sstevel@tonic-gate if (nshow_words >= 4) { 782*7c478bd9Sstevel@tonic-gate log_message(MSG_DEBUG, "\n"); 783*7c478bd9Sstevel@tonic-gate nshow_words = 0; 784*7c478bd9Sstevel@tonic-gate } 785*7c478bd9Sstevel@tonic-gate return (NULL); 786*7c478bd9Sstevel@tonic-gate } 787*7c478bd9Sstevel@tonic-gate 788*7c478bd9Sstevel@tonic-gate void 789*7c478bd9Sstevel@tonic-gate words(fcode_env_t *env) 790*7c478bd9Sstevel@tonic-gate { 791*7c478bd9Sstevel@tonic-gate (void) search_all_dictionaries(env, show_a_word, NULL); 792*7c478bd9Sstevel@tonic-gate (void) show_a_word(env, NULL, NULL); 793*7c478bd9Sstevel@tonic-gate } 794*7c478bd9Sstevel@tonic-gate 795*7c478bd9Sstevel@tonic-gate static acf_t 796*7c478bd9Sstevel@tonic-gate dump_a_word(fcode_env_t *env, acf_t acf, void *arg) 797*7c478bd9Sstevel@tonic-gate { 798*7c478bd9Sstevel@tonic-gate output_acf_name(acf); 799*7c478bd9Sstevel@tonic-gate return (NULL); 800*7c478bd9Sstevel@tonic-gate } 801*7c478bd9Sstevel@tonic-gate 802*7c478bd9Sstevel@tonic-gate void 803*7c478bd9Sstevel@tonic-gate dump_words(fcode_env_t *env) 804*7c478bd9Sstevel@tonic-gate { 805*7c478bd9Sstevel@tonic-gate (void) search_all_dictionaries(env, dump_a_word, NULL); 806*7c478bd9Sstevel@tonic-gate output_acf_name(NULL); 807*7c478bd9Sstevel@tonic-gate } 808*7c478bd9Sstevel@tonic-gate 809*7c478bd9Sstevel@tonic-gate static void 810*7c478bd9Sstevel@tonic-gate dump_line(uchar_t *ptr) 811*7c478bd9Sstevel@tonic-gate { 812*7c478bd9Sstevel@tonic-gate uchar_t *byte; 813*7c478bd9Sstevel@tonic-gate int i; 814*7c478bd9Sstevel@tonic-gate 815*7c478bd9Sstevel@tonic-gate log_message(MSG_INFO, "%p ", (uint32_t)ptr); 816*7c478bd9Sstevel@tonic-gate for (i = 0, byte = ptr; i < 16; i++) { 817*7c478bd9Sstevel@tonic-gate if (i == 8) 818*7c478bd9Sstevel@tonic-gate log_message(MSG_INFO, " "); 819*7c478bd9Sstevel@tonic-gate log_message(MSG_INFO, "%02.2x ", *byte++); 820*7c478bd9Sstevel@tonic-gate } 821*7c478bd9Sstevel@tonic-gate log_message(MSG_INFO, " "); 822*7c478bd9Sstevel@tonic-gate for (i = 0, byte = ptr; i < 16; i++, byte++) { 823*7c478bd9Sstevel@tonic-gate log_message(MSG_INFO, "%c", 824*7c478bd9Sstevel@tonic-gate ((*byte < 0x20) || (*byte > 0x7f)) ? '.' : *byte); 825*7c478bd9Sstevel@tonic-gate } 826*7c478bd9Sstevel@tonic-gate log_message(MSG_INFO, "\n"); 827*7c478bd9Sstevel@tonic-gate } 828*7c478bd9Sstevel@tonic-gate 829*7c478bd9Sstevel@tonic-gate void 830*7c478bd9Sstevel@tonic-gate dump_dictionary(fcode_env_t *env) 831*7c478bd9Sstevel@tonic-gate { 832*7c478bd9Sstevel@tonic-gate uchar_t *ptr; 833*7c478bd9Sstevel@tonic-gate 834*7c478bd9Sstevel@tonic-gate log_message(MSG_INFO, "Dictionary dump: base: %p\n", env->base); 835*7c478bd9Sstevel@tonic-gate for (ptr = (uchar_t *)(((long)(env->base)) & ~0xf); ptr < HERE; 836*7c478bd9Sstevel@tonic-gate ptr += 16) 837*7c478bd9Sstevel@tonic-gate dump_line(ptr); 838*7c478bd9Sstevel@tonic-gate } 839*7c478bd9Sstevel@tonic-gate 840*7c478bd9Sstevel@tonic-gate static char * 841*7c478bd9Sstevel@tonic-gate acf_to_fcode_name(fcode_env_t *env, acf_t acf) 842*7c478bd9Sstevel@tonic-gate { 843*7c478bd9Sstevel@tonic-gate int i; 844*7c478bd9Sstevel@tonic-gate 845*7c478bd9Sstevel@tonic-gate for (i = 0; i < MAX_FCODE; i++) 846*7c478bd9Sstevel@tonic-gate if (env->table[i].apf == acf) 847*7c478bd9Sstevel@tonic-gate return (env->table[i].name); 848*7c478bd9Sstevel@tonic-gate return (NULL); 849*7c478bd9Sstevel@tonic-gate } 850*7c478bd9Sstevel@tonic-gate 851*7c478bd9Sstevel@tonic-gate static acf_t 852*7c478bd9Sstevel@tonic-gate acf_match(fcode_env_t *env, acf_t sacf, void *macf) 853*7c478bd9Sstevel@tonic-gate { 854*7c478bd9Sstevel@tonic-gate if (sacf == (acf_t)macf) 855*7c478bd9Sstevel@tonic-gate return (sacf); 856*7c478bd9Sstevel@tonic-gate return (NULL); 857*7c478bd9Sstevel@tonic-gate } 858*7c478bd9Sstevel@tonic-gate 859*7c478bd9Sstevel@tonic-gate /* 860*7c478bd9Sstevel@tonic-gate * Given an ACF, return ptr to name or "unknown" string. 861*7c478bd9Sstevel@tonic-gate */ 862*7c478bd9Sstevel@tonic-gate char * 863*7c478bd9Sstevel@tonic-gate acf_to_name(fcode_env_t *env, acf_t acf) 864*7c478bd9Sstevel@tonic-gate { 865*7c478bd9Sstevel@tonic-gate struct bitab *bip; 866*7c478bd9Sstevel@tonic-gate static char name_buf[256]; 867*7c478bd9Sstevel@tonic-gate uchar_t *p, *np; 868*7c478bd9Sstevel@tonic-gate int i, n; 869*7c478bd9Sstevel@tonic-gate 870*7c478bd9Sstevel@tonic-gate if (!within_dictionary(env, acf)) { 871*7c478bd9Sstevel@tonic-gate if ((bip = lookup_builtin((token_t)acf)) != NULL) 872*7c478bd9Sstevel@tonic-gate return (bip->bi_name); 873*7c478bd9Sstevel@tonic-gate return (NULL); 874*7c478bd9Sstevel@tonic-gate } 875*7c478bd9Sstevel@tonic-gate return (get_name_or_acf(ACF_TO_LINK(acf))); 876*7c478bd9Sstevel@tonic-gate } 877*7c478bd9Sstevel@tonic-gate 878*7c478bd9Sstevel@tonic-gate int 879*7c478bd9Sstevel@tonic-gate within_dictionary(fcode_env_t *env, void *addr) 880*7c478bd9Sstevel@tonic-gate { 881*7c478bd9Sstevel@tonic-gate return ((uchar_t *)addr >= env->base && 882*7c478bd9Sstevel@tonic-gate (uchar_t *)addr < env->base + dict_size); 883*7c478bd9Sstevel@tonic-gate } 884*7c478bd9Sstevel@tonic-gate 885*7c478bd9Sstevel@tonic-gate static int 886*7c478bd9Sstevel@tonic-gate within_word(fcode_env_t *env, acf_t acf, acf_t wacf) 887*7c478bd9Sstevel@tonic-gate { 888*7c478bd9Sstevel@tonic-gate if (acf == wacf || acf + 1 == wacf) 889*7c478bd9Sstevel@tonic-gate return (1); 890*7c478bd9Sstevel@tonic-gate if (*acf == (token_t)(&do_colon)) { 891*7c478bd9Sstevel@tonic-gate do { 892*7c478bd9Sstevel@tonic-gate if (acf == wacf) 893*7c478bd9Sstevel@tonic-gate return (1); 894*7c478bd9Sstevel@tonic-gate } while (*acf++ != (token_t)(&semi_ptr)); 895*7c478bd9Sstevel@tonic-gate } 896*7c478bd9Sstevel@tonic-gate return (0); 897*7c478bd9Sstevel@tonic-gate } 898*7c478bd9Sstevel@tonic-gate 899*7c478bd9Sstevel@tonic-gate /* 900*7c478bd9Sstevel@tonic-gate * Given an ACF in the middle of a colon definition, search dictionary towards 901*7c478bd9Sstevel@tonic-gate * beginning for "colon" acf. If we find a "semi" acf first, we're not in 902*7c478bd9Sstevel@tonic-gate * the middle of a colon-def (temporary execute?). 903*7c478bd9Sstevel@tonic-gate */ 904*7c478bd9Sstevel@tonic-gate char * 905*7c478bd9Sstevel@tonic-gate acf_backup_search(fcode_env_t *env, acf_t acf) 906*7c478bd9Sstevel@tonic-gate { 907*7c478bd9Sstevel@tonic-gate acf_t nacf; 908*7c478bd9Sstevel@tonic-gate char *name; 909*7c478bd9Sstevel@tonic-gate 910*7c478bd9Sstevel@tonic-gate if ((acf_t)_ALIGN(acf, token_t) == acf && within_dictionary(env, acf)) { 911*7c478bd9Sstevel@tonic-gate for (nacf = acf; nacf >= (acf_t)env->base; nacf--) 912*7c478bd9Sstevel@tonic-gate if (*nacf == (token_t)(&do_colon) || 913*7c478bd9Sstevel@tonic-gate *nacf == (token_t)(&semi_ptr)) 914*7c478bd9Sstevel@tonic-gate break; 915*7c478bd9Sstevel@tonic-gate if (nacf >= (acf_t)env->base && *nacf == (token_t)(&do_colon) && 916*7c478bd9Sstevel@tonic-gate (name = get_name(ACF_TO_LINK(nacf))) != NULL) 917*7c478bd9Sstevel@tonic-gate return (name); 918*7c478bd9Sstevel@tonic-gate } 919*7c478bd9Sstevel@tonic-gate return (acf_to_str(acf)); 920*7c478bd9Sstevel@tonic-gate } 921*7c478bd9Sstevel@tonic-gate 922*7c478bd9Sstevel@tonic-gate /* 923*7c478bd9Sstevel@tonic-gate * Print out current process's C stack using /usr/proc/bin/pstack 924*7c478bd9Sstevel@tonic-gate */ 925*7c478bd9Sstevel@tonic-gate void 926*7c478bd9Sstevel@tonic-gate ctrace(fcode_env_t *env) 927*7c478bd9Sstevel@tonic-gate { 928*7c478bd9Sstevel@tonic-gate char buf[256]; 929*7c478bd9Sstevel@tonic-gate FILE *fd; 930*7c478bd9Sstevel@tonic-gate 931*7c478bd9Sstevel@tonic-gate log_message(MSG_DEBUG, "Interpreter C Stack:\n"); 932*7c478bd9Sstevel@tonic-gate sprintf(buf, "/usr/proc/bin/pstack %d", getpid()); 933*7c478bd9Sstevel@tonic-gate if ((fd = popen(buf, "r")) == NULL) 934*7c478bd9Sstevel@tonic-gate log_perror(MSG_ERROR, "Can't run: %s", buf); 935*7c478bd9Sstevel@tonic-gate else { 936*7c478bd9Sstevel@tonic-gate while (fgets(buf, sizeof (buf), fd)) 937*7c478bd9Sstevel@tonic-gate log_message(MSG_DEBUG, buf); 938*7c478bd9Sstevel@tonic-gate fclose(fd); 939*7c478bd9Sstevel@tonic-gate } 940*7c478bd9Sstevel@tonic-gate } 941*7c478bd9Sstevel@tonic-gate 942*7c478bd9Sstevel@tonic-gate /* 943*7c478bd9Sstevel@tonic-gate * Dump data, return stacks, try to unthread forth calling stack. 944*7c478bd9Sstevel@tonic-gate */ 945*7c478bd9Sstevel@tonic-gate void 946*7c478bd9Sstevel@tonic-gate ftrace(fcode_env_t *env) 947*7c478bd9Sstevel@tonic-gate { 948*7c478bd9Sstevel@tonic-gate log_message(MSG_DEBUG, "Forth Interpreter Stacks:\n"); 949*7c478bd9Sstevel@tonic-gate output_data_stack(env, MSG_DEBUG); 950*7c478bd9Sstevel@tonic-gate output_return_stack(env, 1, MSG_DEBUG); 951*7c478bd9Sstevel@tonic-gate log_message(MSG_DEBUG, "\n"); 952*7c478bd9Sstevel@tonic-gate } 953*7c478bd9Sstevel@tonic-gate 954*7c478bd9Sstevel@tonic-gate int in_forth_abort; 955*7c478bd9Sstevel@tonic-gate 956*7c478bd9Sstevel@tonic-gate /* 957*7c478bd9Sstevel@tonic-gate * Handle fatal error, if interactive mode, return to ok prompt. 958*7c478bd9Sstevel@tonic-gate */ 959*7c478bd9Sstevel@tonic-gate void 960*7c478bd9Sstevel@tonic-gate forth_abort(fcode_env_t *env, char *fmt, ...) 961*7c478bd9Sstevel@tonic-gate { 962*7c478bd9Sstevel@tonic-gate va_list ap; 963*7c478bd9Sstevel@tonic-gate char msg[256]; 964*7c478bd9Sstevel@tonic-gate 965*7c478bd9Sstevel@tonic-gate if (in_forth_abort) { 966*7c478bd9Sstevel@tonic-gate log_message(MSG_FATAL, "ABORT: abort within forth_abort\n"); 967*7c478bd9Sstevel@tonic-gate abort(); 968*7c478bd9Sstevel@tonic-gate } 969*7c478bd9Sstevel@tonic-gate in_forth_abort++; 970*7c478bd9Sstevel@tonic-gate 971*7c478bd9Sstevel@tonic-gate va_start(ap, fmt); 972*7c478bd9Sstevel@tonic-gate vsprintf(msg, fmt, ap); 973*7c478bd9Sstevel@tonic-gate log_message(MSG_ERROR, "ABORT: %s\n", msg); 974*7c478bd9Sstevel@tonic-gate 975*7c478bd9Sstevel@tonic-gate if (env) { 976*7c478bd9Sstevel@tonic-gate ctrace(env); 977*7c478bd9Sstevel@tonic-gate ftrace(env); 978*7c478bd9Sstevel@tonic-gate } 979*7c478bd9Sstevel@tonic-gate 980*7c478bd9Sstevel@tonic-gate return_to_interact(env); 981*7c478bd9Sstevel@tonic-gate /* 982*7c478bd9Sstevel@tonic-gate * If not in interactive mode, return_to_interact just returns. 983*7c478bd9Sstevel@tonic-gate */ 984*7c478bd9Sstevel@tonic-gate exit(1); 985*7c478bd9Sstevel@tonic-gate } 986*7c478bd9Sstevel@tonic-gate 987*7c478bd9Sstevel@tonic-gate /* 988*7c478bd9Sstevel@tonic-gate * Handle fatal system call error 989*7c478bd9Sstevel@tonic-gate */ 990*7c478bd9Sstevel@tonic-gate void 991*7c478bd9Sstevel@tonic-gate forth_perror(fcode_env_t *env, char *fmt, ...) 992*7c478bd9Sstevel@tonic-gate { 993*7c478bd9Sstevel@tonic-gate va_list ap; 994*7c478bd9Sstevel@tonic-gate char msg[256]; 995*7c478bd9Sstevel@tonic-gate int save_errno = errno; /* just in case... */ 996*7c478bd9Sstevel@tonic-gate 997*7c478bd9Sstevel@tonic-gate va_start(ap, fmt); 998*7c478bd9Sstevel@tonic-gate vsprintf(msg, fmt, ap); 999*7c478bd9Sstevel@tonic-gate 1000*7c478bd9Sstevel@tonic-gate forth_abort(env, "%s: %s", msg, strerror(save_errno)); 1001*7c478bd9Sstevel@tonic-gate } 1002*7c478bd9Sstevel@tonic-gate 1003*7c478bd9Sstevel@tonic-gate static void 1004*7c478bd9Sstevel@tonic-gate show_stack(fcode_env_t *env) 1005*7c478bd9Sstevel@tonic-gate { 1006*7c478bd9Sstevel@tonic-gate #ifdef DEBUG 1007*7c478bd9Sstevel@tonic-gate debug_level ^= DEBUG_SHOW_STACK; 1008*7c478bd9Sstevel@tonic-gate #else 1009*7c478bd9Sstevel@tonic-gate /*EMPTY*/ 1010*7c478bd9Sstevel@tonic-gate #endif 1011*7c478bd9Sstevel@tonic-gate } 1012*7c478bd9Sstevel@tonic-gate 1013*7c478bd9Sstevel@tonic-gate static void 1014*7c478bd9Sstevel@tonic-gate print_bytes_header(int width, int offset) 1015*7c478bd9Sstevel@tonic-gate { 1016*7c478bd9Sstevel@tonic-gate int i; 1017*7c478bd9Sstevel@tonic-gate 1018*7c478bd9Sstevel@tonic-gate for (i = 0; i < width; i++) 1019*7c478bd9Sstevel@tonic-gate log_message(MSG_INFO, " "); 1020*7c478bd9Sstevel@tonic-gate log_message(MSG_INFO, " "); 1021*7c478bd9Sstevel@tonic-gate for (i = 0; i < 16; i++) { 1022*7c478bd9Sstevel@tonic-gate if (i == 8) 1023*7c478bd9Sstevel@tonic-gate log_message(MSG_INFO, " "); 1024*7c478bd9Sstevel@tonic-gate if (i == offset) 1025*7c478bd9Sstevel@tonic-gate log_message(MSG_INFO, "\\/ "); 1026*7c478bd9Sstevel@tonic-gate else 1027*7c478bd9Sstevel@tonic-gate log_message(MSG_INFO, "%2x ", i); 1028*7c478bd9Sstevel@tonic-gate } 1029*7c478bd9Sstevel@tonic-gate log_message(MSG_INFO, " "); 1030*7c478bd9Sstevel@tonic-gate for (i = 0; i < 16; i++) { 1031*7c478bd9Sstevel@tonic-gate if (i == offset) 1032*7c478bd9Sstevel@tonic-gate log_message(MSG_INFO, "v"); 1033*7c478bd9Sstevel@tonic-gate else 1034*7c478bd9Sstevel@tonic-gate log_message(MSG_INFO, "%x", i); 1035*7c478bd9Sstevel@tonic-gate } 1036*7c478bd9Sstevel@tonic-gate log_message(MSG_INFO, "\n"); 1037*7c478bd9Sstevel@tonic-gate } 1038*7c478bd9Sstevel@tonic-gate 1039*7c478bd9Sstevel@tonic-gate static void 1040*7c478bd9Sstevel@tonic-gate dump(fcode_env_t *env) 1041*7c478bd9Sstevel@tonic-gate { 1042*7c478bd9Sstevel@tonic-gate uchar_t *data; 1043*7c478bd9Sstevel@tonic-gate int len, offset; 1044*7c478bd9Sstevel@tonic-gate char buf[20]; 1045*7c478bd9Sstevel@tonic-gate 1046*7c478bd9Sstevel@tonic-gate len = POP(DS); 1047*7c478bd9Sstevel@tonic-gate data = (uchar_t *)POP(DS); 1048*7c478bd9Sstevel@tonic-gate offset = ((long)data) & 0xf; 1049*7c478bd9Sstevel@tonic-gate len += offset; 1050*7c478bd9Sstevel@tonic-gate data = (uchar_t *)((long)data & ~0xf); 1051*7c478bd9Sstevel@tonic-gate sprintf(buf, "%p", (uint32_t)data); 1052*7c478bd9Sstevel@tonic-gate print_bytes_header(strlen(buf), offset); 1053*7c478bd9Sstevel@tonic-gate for (len += offset; len > 0; len -= 16, data += 16) 1054*7c478bd9Sstevel@tonic-gate dump_line(data); 1055*7c478bd9Sstevel@tonic-gate } 1056*7c478bd9Sstevel@tonic-gate 1057*7c478bd9Sstevel@tonic-gate static acf_t 1058*7c478bd9Sstevel@tonic-gate do_sifting(fcode_env_t *env, acf_t acf, void *pat) 1059*7c478bd9Sstevel@tonic-gate { 1060*7c478bd9Sstevel@tonic-gate char *name; 1061*7c478bd9Sstevel@tonic-gate 1062*7c478bd9Sstevel@tonic-gate if ((name = get_name(ACF_TO_LINK(acf))) != NULL && strstr(name, pat)) 1063*7c478bd9Sstevel@tonic-gate output_acf_name(acf); 1064*7c478bd9Sstevel@tonic-gate return (NULL); 1065*7c478bd9Sstevel@tonic-gate } 1066*7c478bd9Sstevel@tonic-gate 1067*7c478bd9Sstevel@tonic-gate static void 1068*7c478bd9Sstevel@tonic-gate sifting(fcode_env_t *env) 1069*7c478bd9Sstevel@tonic-gate { 1070*7c478bd9Sstevel@tonic-gate char *pat; 1071*7c478bd9Sstevel@tonic-gate 1072*7c478bd9Sstevel@tonic-gate if ((pat = parse_a_string(env, NULL)) != NULL) { 1073*7c478bd9Sstevel@tonic-gate (void) search_all_dictionaries(env, do_sifting, pat); 1074*7c478bd9Sstevel@tonic-gate output_acf_name(NULL); 1075*7c478bd9Sstevel@tonic-gate } 1076*7c478bd9Sstevel@tonic-gate } 1077*7c478bd9Sstevel@tonic-gate 1078*7c478bd9Sstevel@tonic-gate void 1079*7c478bd9Sstevel@tonic-gate print_level(int level, int *doprint) 1080*7c478bd9Sstevel@tonic-gate { 1081*7c478bd9Sstevel@tonic-gate int i; 1082*7c478bd9Sstevel@tonic-gate 1083*7c478bd9Sstevel@tonic-gate if (*doprint) { 1084*7c478bd9Sstevel@tonic-gate log_message(MSG_DEBUG, "\n "); 1085*7c478bd9Sstevel@tonic-gate for (i = 0; i < level; i++) 1086*7c478bd9Sstevel@tonic-gate log_message(MSG_DEBUG, " "); 1087*7c478bd9Sstevel@tonic-gate *doprint = 0; 1088*7c478bd9Sstevel@tonic-gate } 1089*7c478bd9Sstevel@tonic-gate } 1090*7c478bd9Sstevel@tonic-gate 1091*7c478bd9Sstevel@tonic-gate #define BI_QUOTE 1 1092*7c478bd9Sstevel@tonic-gate #define BI_BLIT 2 1093*7c478bd9Sstevel@tonic-gate #define BI_BDO 3 1094*7c478bd9Sstevel@tonic-gate #define BI_QDO 4 1095*7c478bd9Sstevel@tonic-gate #define BI_BR 5 1096*7c478bd9Sstevel@tonic-gate #define BI_QBR 6 1097*7c478bd9Sstevel@tonic-gate #define BI_BOF 7 1098*7c478bd9Sstevel@tonic-gate #define BI_LOOP 8 1099*7c478bd9Sstevel@tonic-gate #define BI_PLOOP 9 1100*7c478bd9Sstevel@tonic-gate #define BI_TO 10 1101*7c478bd9Sstevel@tonic-gate #define BI_SEMI 11 1102*7c478bd9Sstevel@tonic-gate #define BI_COLON 12 1103*7c478bd9Sstevel@tonic-gate #define BI_NOOP 13 1104*7c478bd9Sstevel@tonic-gate #define BI_NOTYET 14 /* unimplented in "see" */ 1105*7c478bd9Sstevel@tonic-gate 1106*7c478bd9Sstevel@tonic-gate struct bitab bitab[] = { 1107*7c478bd9Sstevel@tonic-gate (token_t)("e_ptr), "\"", BI_QUOTE, 1108*7c478bd9Sstevel@tonic-gate (token_t)(&blit_ptr), "blit", BI_BLIT, 1109*7c478bd9Sstevel@tonic-gate (token_t)(&do_bdo_ptr), "do", BI_BDO, 1110*7c478bd9Sstevel@tonic-gate (token_t)(&do_bqdo_ptr), "?do", BI_QDO, 1111*7c478bd9Sstevel@tonic-gate (token_t)(&bbranch_ptrs[0]), "br", BI_BR, 1112*7c478bd9Sstevel@tonic-gate (token_t)(&bbranch_ptrs[1]), "qbr", BI_QBR, 1113*7c478bd9Sstevel@tonic-gate (token_t)(&bbranch_ptrs[2]), "bof", BI_BOF, 1114*7c478bd9Sstevel@tonic-gate (token_t)(&do_loop_ptr), "loop", BI_LOOP, 1115*7c478bd9Sstevel@tonic-gate (token_t)(&do_ploop_ptr), "+loop", BI_PLOOP, 1116*7c478bd9Sstevel@tonic-gate (token_t)(&to_ptr), "to", BI_NOOP, 1117*7c478bd9Sstevel@tonic-gate (token_t)(&semi_ptr), ";", BI_SEMI, 1118*7c478bd9Sstevel@tonic-gate (token_t)(&do_colon), ":", BI_COLON, 1119*7c478bd9Sstevel@tonic-gate (token_t)(&tlit_ptr), "[']", BI_NOOP, 1120*7c478bd9Sstevel@tonic-gate (token_t)(&do_leave_ptr), "leave", BI_NOTYET, 1121*7c478bd9Sstevel@tonic-gate (token_t)(&create_ptr), "create", BI_NOTYET, 1122*7c478bd9Sstevel@tonic-gate (token_t)(&does_ptr), "does>", BI_NOTYET, 1123*7c478bd9Sstevel@tonic-gate (token_t)(&value_defines[0][0]), "a.@", BI_NOTYET, 1124*7c478bd9Sstevel@tonic-gate (token_t)(&value_defines[0][1]), "a.!", BI_NOTYET, 1125*7c478bd9Sstevel@tonic-gate (token_t)(&value_defines[0][2]), "a.nop", BI_NOTYET, 1126*7c478bd9Sstevel@tonic-gate (token_t)(&value_defines[1][0]), "a.i@", BI_NOTYET, 1127*7c478bd9Sstevel@tonic-gate (token_t)(&value_defines[1][1]), "a.i!", BI_NOTYET, 1128*7c478bd9Sstevel@tonic-gate (token_t)(&value_defines[1][2]), "a.iad", BI_NOTYET, 1129*7c478bd9Sstevel@tonic-gate (token_t)(&value_defines[2][0]), "a.defer", BI_NOTYET, 1130*7c478bd9Sstevel@tonic-gate (token_t)(&value_defines[2][1]), "a.@", BI_NOTYET, 1131*7c478bd9Sstevel@tonic-gate (token_t)(&value_defines[2][2]), "a.nop", BI_NOTYET, 1132*7c478bd9Sstevel@tonic-gate (token_t)(&value_defines[3][0]), "a.defexec", BI_NOTYET, 1133*7c478bd9Sstevel@tonic-gate (token_t)(&value_defines[3][1]), "a.iset", BI_NOTYET, 1134*7c478bd9Sstevel@tonic-gate (token_t)(&value_defines[3][2]), "a.iad", BI_NOTYET, 1135*7c478bd9Sstevel@tonic-gate (token_t)(&value_defines[4][0]), "a.binit", BI_NOTYET, 1136*7c478bd9Sstevel@tonic-gate (token_t)(&value_defines[4][1]), "a.2drop", BI_NOTYET, 1137*7c478bd9Sstevel@tonic-gate (token_t)(&value_defines[4][2]), "a.nop", BI_NOTYET, 1138*7c478bd9Sstevel@tonic-gate (token_t)(&value_defines[5][0]), "a.ibinit", BI_NOTYET, 1139*7c478bd9Sstevel@tonic-gate (token_t)(&value_defines[5][1]), "a.2drop", BI_NOTYET, 1140*7c478bd9Sstevel@tonic-gate (token_t)(&value_defines[5][2]), "a.iad", BI_NOTYET, 1141*7c478bd9Sstevel@tonic-gate 0 1142*7c478bd9Sstevel@tonic-gate }; 1143*7c478bd9Sstevel@tonic-gate 1144*7c478bd9Sstevel@tonic-gate struct bitab * 1145*7c478bd9Sstevel@tonic-gate lookup_builtin(token_t builtin) 1146*7c478bd9Sstevel@tonic-gate { 1147*7c478bd9Sstevel@tonic-gate int i; 1148*7c478bd9Sstevel@tonic-gate 1149*7c478bd9Sstevel@tonic-gate for (i = 0; bitab[i].bi_ptr; i++) 1150*7c478bd9Sstevel@tonic-gate if (bitab[i].bi_ptr == builtin) 1151*7c478bd9Sstevel@tonic-gate return (&bitab[i]); 1152*7c478bd9Sstevel@tonic-gate return (NULL); 1153*7c478bd9Sstevel@tonic-gate } 1154*7c478bd9Sstevel@tonic-gate 1155*7c478bd9Sstevel@tonic-gate static void 1156*7c478bd9Sstevel@tonic-gate paren_see(fcode_env_t *env) 1157*7c478bd9Sstevel@tonic-gate { 1158*7c478bd9Sstevel@tonic-gate acf_t save_acf = (acf_t)POP(DS); 1159*7c478bd9Sstevel@tonic-gate acf_t acf = save_acf; 1160*7c478bd9Sstevel@tonic-gate int i, n, pass; 1161*7c478bd9Sstevel@tonic-gate token_t brtab[30], thentab[30], brstk[30]; 1162*7c478bd9Sstevel@tonic-gate int nbrtab = 0, nthentab = 0, nbrstk = 0; 1163*7c478bd9Sstevel@tonic-gate uchar_t *p; 1164*7c478bd9Sstevel@tonic-gate int level = 0, doprintlevel = 1, nthen; 1165*7c478bd9Sstevel@tonic-gate struct bitab *bip; 1166*7c478bd9Sstevel@tonic-gate token_t last_lit = 0, case_lit = 0, endof_loc = 0, endcase_loc = 0; 1167*7c478bd9Sstevel@tonic-gate 1168*7c478bd9Sstevel@tonic-gate if ((bip = lookup_builtin(*acf)) == NULL || 1169*7c478bd9Sstevel@tonic-gate bip->bi_type != BI_COLON) { 1170*7c478bd9Sstevel@tonic-gate if (bip = lookup_builtin((token_t)acf)) 1171*7c478bd9Sstevel@tonic-gate log_message(MSG_INFO, "%s: builtin\n", bip->bi_name); 1172*7c478bd9Sstevel@tonic-gate else 1173*7c478bd9Sstevel@tonic-gate log_message(MSG_INFO, "%s: builtin\n", 1174*7c478bd9Sstevel@tonic-gate acf_to_name(env, acf)); 1175*7c478bd9Sstevel@tonic-gate return; 1176*7c478bd9Sstevel@tonic-gate } 1177*7c478bd9Sstevel@tonic-gate log_message(MSG_INFO, ": %s", acf_to_name(env, acf)); 1178*7c478bd9Sstevel@tonic-gate for (pass = 0; pass < 2; pass++) { 1179*7c478bd9Sstevel@tonic-gate acf = save_acf; 1180*7c478bd9Sstevel@tonic-gate for (acf++; ; acf++) { 1181*7c478bd9Sstevel@tonic-gate if (pass) { 1182*7c478bd9Sstevel@tonic-gate print_level(level, &doprintlevel); 1183*7c478bd9Sstevel@tonic-gate for (nthen = 0; nthentab > 0 && 1184*7c478bd9Sstevel@tonic-gate thentab[nthentab-1] == (token_t)acf; 1185*7c478bd9Sstevel@tonic-gate nthentab--) 1186*7c478bd9Sstevel@tonic-gate nthen++; 1187*7c478bd9Sstevel@tonic-gate if (nthen) { 1188*7c478bd9Sstevel@tonic-gate level -= nthen; 1189*7c478bd9Sstevel@tonic-gate doprintlevel = 1; 1190*7c478bd9Sstevel@tonic-gate print_level(level, &doprintlevel); 1191*7c478bd9Sstevel@tonic-gate for (i = 0; i < nthen; i++) 1192*7c478bd9Sstevel@tonic-gate log_message(MSG_INFO, "then "); 1193*7c478bd9Sstevel@tonic-gate } 1194*7c478bd9Sstevel@tonic-gate print_level(level, &doprintlevel); 1195*7c478bd9Sstevel@tonic-gate for (i = 0; i < nbrtab; i += 2) 1196*7c478bd9Sstevel@tonic-gate if ((token_t)acf == brtab[i]) { 1197*7c478bd9Sstevel@tonic-gate log_message(MSG_INFO, "begin "); 1198*7c478bd9Sstevel@tonic-gate brstk[nbrstk++] = brtab[i+1]; 1199*7c478bd9Sstevel@tonic-gate level++; 1200*7c478bd9Sstevel@tonic-gate doprintlevel = 1; 1201*7c478bd9Sstevel@tonic-gate } 1202*7c478bd9Sstevel@tonic-gate print_level(level, &doprintlevel); 1203*7c478bd9Sstevel@tonic-gate if (case_lit == (token_t)acf) { 1204*7c478bd9Sstevel@tonic-gate log_message(MSG_INFO, "case "); 1205*7c478bd9Sstevel@tonic-gate doprintlevel = 1; 1206*7c478bd9Sstevel@tonic-gate print_level(level, &doprintlevel); 1207*7c478bd9Sstevel@tonic-gate } 1208*7c478bd9Sstevel@tonic-gate if (endof_loc == (token_t)acf) { 1209*7c478bd9Sstevel@tonic-gate log_message(MSG_INFO, "endof "); 1210*7c478bd9Sstevel@tonic-gate doprintlevel = 1; 1211*7c478bd9Sstevel@tonic-gate print_level(level, &doprintlevel); 1212*7c478bd9Sstevel@tonic-gate } 1213*7c478bd9Sstevel@tonic-gate if (endcase_loc == (token_t)acf) { 1214*7c478bd9Sstevel@tonic-gate doprintlevel = 1; 1215*7c478bd9Sstevel@tonic-gate print_level(level, &doprintlevel); 1216*7c478bd9Sstevel@tonic-gate log_message(MSG_INFO, "endcase "); 1217*7c478bd9Sstevel@tonic-gate } 1218*7c478bd9Sstevel@tonic-gate } 1219*7c478bd9Sstevel@tonic-gate if ((bip = lookup_builtin((token_t)*acf)) == 0) { 1220*7c478bd9Sstevel@tonic-gate last_lit = (token_t)acf; 1221*7c478bd9Sstevel@tonic-gate if (pass) 1222*7c478bd9Sstevel@tonic-gate log_message(MSG_INFO, "%s ", 1223*7c478bd9Sstevel@tonic-gate acf_to_name(env, (acf_t)*acf)); 1224*7c478bd9Sstevel@tonic-gate continue; 1225*7c478bd9Sstevel@tonic-gate } 1226*7c478bd9Sstevel@tonic-gate if (bip->bi_type == BI_SEMI) { 1227*7c478bd9Sstevel@tonic-gate if (pass) { 1228*7c478bd9Sstevel@tonic-gate log_message(MSG_INFO, "\n"); 1229*7c478bd9Sstevel@tonic-gate log_message(MSG_INFO, "%s\n", 1230*7c478bd9Sstevel@tonic-gate bip->bi_name); 1231*7c478bd9Sstevel@tonic-gate } 1232*7c478bd9Sstevel@tonic-gate break; 1233*7c478bd9Sstevel@tonic-gate } 1234*7c478bd9Sstevel@tonic-gate switch (bip->bi_type) { 1235*7c478bd9Sstevel@tonic-gate 1236*7c478bd9Sstevel@tonic-gate case BI_NOOP: 1237*7c478bd9Sstevel@tonic-gate case BI_NOTYET: 1238*7c478bd9Sstevel@tonic-gate if (pass) 1239*7c478bd9Sstevel@tonic-gate log_message(MSG_INFO, "%s ", 1240*7c478bd9Sstevel@tonic-gate bip->bi_name); 1241*7c478bd9Sstevel@tonic-gate break; 1242*7c478bd9Sstevel@tonic-gate 1243*7c478bd9Sstevel@tonic-gate case BI_QUOTE: 1244*7c478bd9Sstevel@tonic-gate if (pass) 1245*7c478bd9Sstevel@tonic-gate log_message(MSG_INFO, "\" "); 1246*7c478bd9Sstevel@tonic-gate acf++; 1247*7c478bd9Sstevel@tonic-gate p = (uchar_t *)acf; 1248*7c478bd9Sstevel@tonic-gate n = *p++; 1249*7c478bd9Sstevel@tonic-gate if (pass) 1250*7c478bd9Sstevel@tonic-gate log_message(MSG_INFO, "%s\" ", p); 1251*7c478bd9Sstevel@tonic-gate p += n + 1; 1252*7c478bd9Sstevel@tonic-gate for (; ((token_t)(p)) & (sizeof (token_t) - 1); 1253*7c478bd9Sstevel@tonic-gate p++) 1254*7c478bd9Sstevel@tonic-gate ; 1255*7c478bd9Sstevel@tonic-gate acf = (acf_t)p; 1256*7c478bd9Sstevel@tonic-gate acf--; 1257*7c478bd9Sstevel@tonic-gate break; 1258*7c478bd9Sstevel@tonic-gate 1259*7c478bd9Sstevel@tonic-gate case BI_BLIT: 1260*7c478bd9Sstevel@tonic-gate acf++; 1261*7c478bd9Sstevel@tonic-gate if (pass) 1262*7c478bd9Sstevel@tonic-gate log_message(MSG_INFO, "%x ", *acf); 1263*7c478bd9Sstevel@tonic-gate break; 1264*7c478bd9Sstevel@tonic-gate 1265*7c478bd9Sstevel@tonic-gate case BI_BDO: 1266*7c478bd9Sstevel@tonic-gate case BI_QDO: 1267*7c478bd9Sstevel@tonic-gate if (pass) { 1268*7c478bd9Sstevel@tonic-gate log_message(MSG_INFO, "%s ", 1269*7c478bd9Sstevel@tonic-gate bip->bi_name); 1270*7c478bd9Sstevel@tonic-gate doprintlevel = 1; 1271*7c478bd9Sstevel@tonic-gate level++; 1272*7c478bd9Sstevel@tonic-gate } 1273*7c478bd9Sstevel@tonic-gate acf++; 1274*7c478bd9Sstevel@tonic-gate break; 1275*7c478bd9Sstevel@tonic-gate 1276*7c478bd9Sstevel@tonic-gate case BI_BR: 1277*7c478bd9Sstevel@tonic-gate acf++; 1278*7c478bd9Sstevel@tonic-gate if (pass) { 1279*7c478bd9Sstevel@tonic-gate if (*acf < (token_t)acf) { 1280*7c478bd9Sstevel@tonic-gate if (nbrstk) { 1281*7c478bd9Sstevel@tonic-gate doprintlevel = 1; 1282*7c478bd9Sstevel@tonic-gate level--; 1283*7c478bd9Sstevel@tonic-gate print_level(level, 1284*7c478bd9Sstevel@tonic-gate &doprintlevel); 1285*7c478bd9Sstevel@tonic-gate log_message(MSG_INFO, 1286*7c478bd9Sstevel@tonic-gate "repeat "); 1287*7c478bd9Sstevel@tonic-gate nbrstk--; 1288*7c478bd9Sstevel@tonic-gate } else 1289*7c478bd9Sstevel@tonic-gate log_message(MSG_INFO, 1290*7c478bd9Sstevel@tonic-gate "[br back?]"); 1291*7c478bd9Sstevel@tonic-gate } else if (nthentab) { 1292*7c478bd9Sstevel@tonic-gate doprintlevel = 1; 1293*7c478bd9Sstevel@tonic-gate print_level(level - 1, 1294*7c478bd9Sstevel@tonic-gate &doprintlevel); 1295*7c478bd9Sstevel@tonic-gate log_message(MSG_INFO, "else "); 1296*7c478bd9Sstevel@tonic-gate doprintlevel = 1; 1297*7c478bd9Sstevel@tonic-gate thentab[nthentab - 1] = *acf; 1298*7c478bd9Sstevel@tonic-gate } 1299*7c478bd9Sstevel@tonic-gate } else { 1300*7c478bd9Sstevel@tonic-gate if (*acf < (token_t)acf) { 1301*7c478bd9Sstevel@tonic-gate brtab[nbrtab++] = *acf; 1302*7c478bd9Sstevel@tonic-gate brtab[nbrtab++] = (token_t)acf; 1303*7c478bd9Sstevel@tonic-gate } 1304*7c478bd9Sstevel@tonic-gate if (endcase_loc == 0 && 1305*7c478bd9Sstevel@tonic-gate case_lit) { 1306*7c478bd9Sstevel@tonic-gate endcase_loc = *acf; 1307*7c478bd9Sstevel@tonic-gate } 1308*7c478bd9Sstevel@tonic-gate } 1309*7c478bd9Sstevel@tonic-gate break; 1310*7c478bd9Sstevel@tonic-gate 1311*7c478bd9Sstevel@tonic-gate case BI_QBR: 1312*7c478bd9Sstevel@tonic-gate acf++; 1313*7c478bd9Sstevel@tonic-gate if (pass) { 1314*7c478bd9Sstevel@tonic-gate if (*acf < (token_t)acf) { 1315*7c478bd9Sstevel@tonic-gate if (nbrstk) { 1316*7c478bd9Sstevel@tonic-gate doprintlevel = 1; 1317*7c478bd9Sstevel@tonic-gate level--; 1318*7c478bd9Sstevel@tonic-gate print_level(level, 1319*7c478bd9Sstevel@tonic-gate &doprintlevel); 1320*7c478bd9Sstevel@tonic-gate log_message(MSG_INFO, 1321*7c478bd9Sstevel@tonic-gate "until "); 1322*7c478bd9Sstevel@tonic-gate nbrstk--; 1323*7c478bd9Sstevel@tonic-gate } else 1324*7c478bd9Sstevel@tonic-gate log_message(MSG_INFO, 1325*7c478bd9Sstevel@tonic-gate "[br back?]"); 1326*7c478bd9Sstevel@tonic-gate } else if (nbrstk > 0 && 1327*7c478bd9Sstevel@tonic-gate *acf >= brstk[nbrstk - 1]) { 1328*7c478bd9Sstevel@tonic-gate doprintlevel = 1; 1329*7c478bd9Sstevel@tonic-gate print_level(level - 1, 1330*7c478bd9Sstevel@tonic-gate &doprintlevel); 1331*7c478bd9Sstevel@tonic-gate log_message(MSG_INFO, 1332*7c478bd9Sstevel@tonic-gate "while "); 1333*7c478bd9Sstevel@tonic-gate doprintlevel = 1; 1334*7c478bd9Sstevel@tonic-gate } else { 1335*7c478bd9Sstevel@tonic-gate log_message(MSG_INFO, "if "); 1336*7c478bd9Sstevel@tonic-gate doprintlevel = 1; 1337*7c478bd9Sstevel@tonic-gate level++; 1338*7c478bd9Sstevel@tonic-gate thentab[nthentab++] = *acf; 1339*7c478bd9Sstevel@tonic-gate } 1340*7c478bd9Sstevel@tonic-gate } else if (*acf < (token_t)acf) { 1341*7c478bd9Sstevel@tonic-gate brtab[nbrtab++] = *acf; 1342*7c478bd9Sstevel@tonic-gate brtab[nbrtab++] = (token_t)acf; 1343*7c478bd9Sstevel@tonic-gate } 1344*7c478bd9Sstevel@tonic-gate break; 1345*7c478bd9Sstevel@tonic-gate 1346*7c478bd9Sstevel@tonic-gate case BI_BOF: 1347*7c478bd9Sstevel@tonic-gate acf++; 1348*7c478bd9Sstevel@tonic-gate if (pass) { 1349*7c478bd9Sstevel@tonic-gate log_message(MSG_INFO, "of "); 1350*7c478bd9Sstevel@tonic-gate endof_loc = *acf; 1351*7c478bd9Sstevel@tonic-gate } else if (case_lit == 0) { 1352*7c478bd9Sstevel@tonic-gate case_lit = last_lit; 1353*7c478bd9Sstevel@tonic-gate } 1354*7c478bd9Sstevel@tonic-gate break; 1355*7c478bd9Sstevel@tonic-gate 1356*7c478bd9Sstevel@tonic-gate case BI_LOOP: 1357*7c478bd9Sstevel@tonic-gate case BI_PLOOP: 1358*7c478bd9Sstevel@tonic-gate if (pass) { 1359*7c478bd9Sstevel@tonic-gate level--; 1360*7c478bd9Sstevel@tonic-gate doprintlevel = 1; 1361*7c478bd9Sstevel@tonic-gate print_level(level, &doprintlevel); 1362*7c478bd9Sstevel@tonic-gate log_message(MSG_INFO, "%s ", 1363*7c478bd9Sstevel@tonic-gate bip->bi_name); 1364*7c478bd9Sstevel@tonic-gate } 1365*7c478bd9Sstevel@tonic-gate acf++; 1366*7c478bd9Sstevel@tonic-gate break; 1367*7c478bd9Sstevel@tonic-gate 1368*7c478bd9Sstevel@tonic-gate default: 1369*7c478bd9Sstevel@tonic-gate log_message(MSG_ERROR, "Invalid builtin %s\n", 1370*7c478bd9Sstevel@tonic-gate bip->bi_name); 1371*7c478bd9Sstevel@tonic-gate } 1372*7c478bd9Sstevel@tonic-gate } 1373*7c478bd9Sstevel@tonic-gate } 1374*7c478bd9Sstevel@tonic-gate } 1375*7c478bd9Sstevel@tonic-gate 1376*7c478bd9Sstevel@tonic-gate static void 1377*7c478bd9Sstevel@tonic-gate see(fcode_env_t *env) 1378*7c478bd9Sstevel@tonic-gate { 1379*7c478bd9Sstevel@tonic-gate fstack_t d; 1380*7c478bd9Sstevel@tonic-gate 1381*7c478bd9Sstevel@tonic-gate parse_word(env); 1382*7c478bd9Sstevel@tonic-gate dollar_find(env); 1383*7c478bd9Sstevel@tonic-gate d = POP(DS); 1384*7c478bd9Sstevel@tonic-gate if (d) 1385*7c478bd9Sstevel@tonic-gate paren_see(env); 1386*7c478bd9Sstevel@tonic-gate else { 1387*7c478bd9Sstevel@tonic-gate log_message(MSG_WARN, "?"); 1388*7c478bd9Sstevel@tonic-gate two_drop(env); 1389*7c478bd9Sstevel@tonic-gate } 1390*7c478bd9Sstevel@tonic-gate } 1391*7c478bd9Sstevel@tonic-gate 1392*7c478bd9Sstevel@tonic-gate static acf_t 1393*7c478bd9Sstevel@tonic-gate do_dot_calls(fcode_env_t *env, acf_t acf, void *cacf) 1394*7c478bd9Sstevel@tonic-gate { 1395*7c478bd9Sstevel@tonic-gate token_t *dptr = ACF_TO_LINK(acf); 1396*7c478bd9Sstevel@tonic-gate token_t *wptr = acf; 1397*7c478bd9Sstevel@tonic-gate 1398*7c478bd9Sstevel@tonic-gate if (*wptr == (token_t)(&do_colon)) { 1399*7c478bd9Sstevel@tonic-gate do { 1400*7c478bd9Sstevel@tonic-gate if ((acf_t)(*wptr) == (acf_t)cacf) 1401*7c478bd9Sstevel@tonic-gate output_acf_name(acf); 1402*7c478bd9Sstevel@tonic-gate } while (*wptr++ != (token_t)(&semi_ptr)); 1403*7c478bd9Sstevel@tonic-gate } else if ((acf_t)(*wptr) == cacf) 1404*7c478bd9Sstevel@tonic-gate output_acf_name(acf); 1405*7c478bd9Sstevel@tonic-gate else if (wptr == (token_t *)cacf) 1406*7c478bd9Sstevel@tonic-gate output_acf_name(acf); 1407*7c478bd9Sstevel@tonic-gate return (NULL); 1408*7c478bd9Sstevel@tonic-gate } 1409*7c478bd9Sstevel@tonic-gate 1410*7c478bd9Sstevel@tonic-gate static void 1411*7c478bd9Sstevel@tonic-gate dot_calls(fcode_env_t *env) 1412*7c478bd9Sstevel@tonic-gate { 1413*7c478bd9Sstevel@tonic-gate acf_t acf = (acf_t)POP(DS); 1414*7c478bd9Sstevel@tonic-gate 1415*7c478bd9Sstevel@tonic-gate search_all_dictionaries(env, do_dot_calls, acf); 1416*7c478bd9Sstevel@tonic-gate output_acf_name(NULL); 1417*7c478bd9Sstevel@tonic-gate } 1418*7c478bd9Sstevel@tonic-gate 1419*7c478bd9Sstevel@tonic-gate static void 1420*7c478bd9Sstevel@tonic-gate dot_pci_space(fcode_env_t *env) 1421*7c478bd9Sstevel@tonic-gate { 1422*7c478bd9Sstevel@tonic-gate fstack_t d = POP(DS); 1423*7c478bd9Sstevel@tonic-gate 1424*7c478bd9Sstevel@tonic-gate switch ((d >> 24) & 0x3) { 1425*7c478bd9Sstevel@tonic-gate case 0: log_message(MSG_INFO, "Config,"); break; 1426*7c478bd9Sstevel@tonic-gate case 1: log_message(MSG_INFO, "IO,"); break; 1427*7c478bd9Sstevel@tonic-gate case 2: log_message(MSG_INFO, "Memory32,"); break; 1428*7c478bd9Sstevel@tonic-gate case 3: log_message(MSG_INFO, "Memory64,"); break; 1429*7c478bd9Sstevel@tonic-gate } 1430*7c478bd9Sstevel@tonic-gate if (d & 0x80000000) 1431*7c478bd9Sstevel@tonic-gate log_message(MSG_INFO, "Not_reloc,"); 1432*7c478bd9Sstevel@tonic-gate if (d & 0x400000000) 1433*7c478bd9Sstevel@tonic-gate log_message(MSG_INFO, "Prefetch,"); 1434*7c478bd9Sstevel@tonic-gate if (d & 0x200000000) 1435*7c478bd9Sstevel@tonic-gate log_message(MSG_INFO, "Alias,"); 1436*7c478bd9Sstevel@tonic-gate log_message(MSG_INFO, "Bus%d,", (d >> 16) & 0xff); 1437*7c478bd9Sstevel@tonic-gate log_message(MSG_INFO, "Dev%d,", (d >> 11) & 0x1f); 1438*7c478bd9Sstevel@tonic-gate log_message(MSG_INFO, "Func%d,", (d >> 8) & 0x7); 1439*7c478bd9Sstevel@tonic-gate log_message(MSG_INFO, "Reg%x", d & 0xff); 1440*7c478bd9Sstevel@tonic-gate log_message(MSG_INFO, "\n"); 1441*7c478bd9Sstevel@tonic-gate } 1442*7c478bd9Sstevel@tonic-gate 1443*7c478bd9Sstevel@tonic-gate void 1444*7c478bd9Sstevel@tonic-gate fcode_debug(fcode_env_t *env) 1445*7c478bd9Sstevel@tonic-gate { 1446*7c478bd9Sstevel@tonic-gate PUSH(DS, (fstack_t)(&env->fcode_debug)); 1447*7c478bd9Sstevel@tonic-gate } 1448*7c478bd9Sstevel@tonic-gate 1449*7c478bd9Sstevel@tonic-gate static void 1450*7c478bd9Sstevel@tonic-gate base_addr(fcode_env_t *env) 1451*7c478bd9Sstevel@tonic-gate { 1452*7c478bd9Sstevel@tonic-gate PUSH(DS, (fstack_t)env->base); 1453*7c478bd9Sstevel@tonic-gate } 1454*7c478bd9Sstevel@tonic-gate 1455*7c478bd9Sstevel@tonic-gate static int mw_valid; 1456*7c478bd9Sstevel@tonic-gate static int mw_size; 1457*7c478bd9Sstevel@tonic-gate static void *mw_addr; 1458*7c478bd9Sstevel@tonic-gate static fstack_t mw_value; 1459*7c478bd9Sstevel@tonic-gate static fstack_t mw_lastvalue; 1460*7c478bd9Sstevel@tonic-gate 1461*7c478bd9Sstevel@tonic-gate static fstack_t 1462*7c478bd9Sstevel@tonic-gate mw_fetch(void) 1463*7c478bd9Sstevel@tonic-gate { 1464*7c478bd9Sstevel@tonic-gate switch (mw_size) { 1465*7c478bd9Sstevel@tonic-gate case 1: return (*((uint8_t *)mw_addr)); 1466*7c478bd9Sstevel@tonic-gate case 2: return (*((uint16_t *)mw_addr)); 1467*7c478bd9Sstevel@tonic-gate case 4: return (*((uint32_t *)mw_addr)); 1468*7c478bd9Sstevel@tonic-gate case 8: return (*((uint64_t *)mw_addr)); 1469*7c478bd9Sstevel@tonic-gate } 1470*7c478bd9Sstevel@tonic-gate return (0); 1471*7c478bd9Sstevel@tonic-gate } 1472*7c478bd9Sstevel@tonic-gate 1473*7c478bd9Sstevel@tonic-gate void 1474*7c478bd9Sstevel@tonic-gate do_memory_watch(fcode_env_t *env) 1475*7c478bd9Sstevel@tonic-gate { 1476*7c478bd9Sstevel@tonic-gate fstack_t value; 1477*7c478bd9Sstevel@tonic-gate 1478*7c478bd9Sstevel@tonic-gate if (!mw_valid) 1479*7c478bd9Sstevel@tonic-gate return; 1480*7c478bd9Sstevel@tonic-gate value = mw_fetch(); 1481*7c478bd9Sstevel@tonic-gate if (value != mw_lastvalue) { 1482*7c478bd9Sstevel@tonic-gate if (mw_valid == 1 || mw_value == value) { 1483*7c478bd9Sstevel@tonic-gate log_message(MSG_INFO, 1484*7c478bd9Sstevel@tonic-gate "memory-watch: %p/%d: %llx -> %llx\n", 1485*7c478bd9Sstevel@tonic-gate mw_addr, mw_size, (uint64_t)mw_lastvalue, 1486*7c478bd9Sstevel@tonic-gate (uint64_t)value); 1487*7c478bd9Sstevel@tonic-gate do_fclib_step(env); 1488*7c478bd9Sstevel@tonic-gate } 1489*7c478bd9Sstevel@tonic-gate mw_lastvalue = value; 1490*7c478bd9Sstevel@tonic-gate } 1491*7c478bd9Sstevel@tonic-gate } 1492*7c478bd9Sstevel@tonic-gate 1493*7c478bd9Sstevel@tonic-gate static void 1494*7c478bd9Sstevel@tonic-gate set_memory_watch(fcode_env_t *env, int type, int size, void *addr, 1495*7c478bd9Sstevel@tonic-gate fstack_t value) 1496*7c478bd9Sstevel@tonic-gate { 1497*7c478bd9Sstevel@tonic-gate switch (size) { 1498*7c478bd9Sstevel@tonic-gate case 1: case 2: case 4: case 8: 1499*7c478bd9Sstevel@tonic-gate break; 1500*7c478bd9Sstevel@tonic-gate default: 1501*7c478bd9Sstevel@tonic-gate log_message(MSG_ERROR, "set_memory_watch: invalid size: %d\n", 1502*7c478bd9Sstevel@tonic-gate size); 1503*7c478bd9Sstevel@tonic-gate return; 1504*7c478bd9Sstevel@tonic-gate } 1505*7c478bd9Sstevel@tonic-gate mw_valid = type; 1506*7c478bd9Sstevel@tonic-gate mw_size = size; 1507*7c478bd9Sstevel@tonic-gate mw_addr = addr; 1508*7c478bd9Sstevel@tonic-gate mw_value = value; 1509*7c478bd9Sstevel@tonic-gate mw_lastvalue = mw_fetch(); 1510*7c478bd9Sstevel@tonic-gate } 1511*7c478bd9Sstevel@tonic-gate 1512*7c478bd9Sstevel@tonic-gate static void 1513*7c478bd9Sstevel@tonic-gate memory_watch(fcode_env_t *env) 1514*7c478bd9Sstevel@tonic-gate { 1515*7c478bd9Sstevel@tonic-gate int size = POP(DS); 1516*7c478bd9Sstevel@tonic-gate void *addr = (void *)POP(DS); 1517*7c478bd9Sstevel@tonic-gate 1518*7c478bd9Sstevel@tonic-gate set_memory_watch(env, 1, size, addr, 0); 1519*7c478bd9Sstevel@tonic-gate } 1520*7c478bd9Sstevel@tonic-gate 1521*7c478bd9Sstevel@tonic-gate static void 1522*7c478bd9Sstevel@tonic-gate memory_watch_value(fcode_env_t *env) 1523*7c478bd9Sstevel@tonic-gate { 1524*7c478bd9Sstevel@tonic-gate int size = POP(DS); 1525*7c478bd9Sstevel@tonic-gate void *addr = (void *)POP(DS); 1526*7c478bd9Sstevel@tonic-gate fstack_t value = POP(DS); 1527*7c478bd9Sstevel@tonic-gate 1528*7c478bd9Sstevel@tonic-gate set_memory_watch(env, 2, size, addr, value); 1529*7c478bd9Sstevel@tonic-gate } 1530*7c478bd9Sstevel@tonic-gate 1531*7c478bd9Sstevel@tonic-gate static void 1532*7c478bd9Sstevel@tonic-gate memory_watch_clear(fcode_env_t *env) 1533*7c478bd9Sstevel@tonic-gate { 1534*7c478bd9Sstevel@tonic-gate mw_valid = 0; 1535*7c478bd9Sstevel@tonic-gate } 1536*7c478bd9Sstevel@tonic-gate 1537*7c478bd9Sstevel@tonic-gate static void 1538*7c478bd9Sstevel@tonic-gate vsearch(fcode_env_t *env) 1539*7c478bd9Sstevel@tonic-gate { 1540*7c478bd9Sstevel@tonic-gate fstack_t value; 1541*7c478bd9Sstevel@tonic-gate int size = POP(DS); 1542*7c478bd9Sstevel@tonic-gate fstack_t match_value = POP(DS); 1543*7c478bd9Sstevel@tonic-gate uchar_t *toaddr = (uchar_t *)POP(DS); 1544*7c478bd9Sstevel@tonic-gate uchar_t *fromaddr = (uchar_t *)POP(DS); 1545*7c478bd9Sstevel@tonic-gate 1546*7c478bd9Sstevel@tonic-gate log_message(MSG_INFO, "%p to %p by %d looking for %llx\n", fromaddr, 1547*7c478bd9Sstevel@tonic-gate toaddr, size, (uint64_t)match_value); 1548*7c478bd9Sstevel@tonic-gate for (; fromaddr < toaddr; fromaddr += size) { 1549*7c478bd9Sstevel@tonic-gate switch (size) { 1550*7c478bd9Sstevel@tonic-gate case 1: value = *((uint8_t *)fromaddr); break; 1551*7c478bd9Sstevel@tonic-gate case 2: value = *((uint16_t *)fromaddr); break; 1552*7c478bd9Sstevel@tonic-gate case 4: value = *((uint32_t *)fromaddr); break; 1553*7c478bd9Sstevel@tonic-gate case 8: value = *((uint64_t *)fromaddr); break; 1554*7c478bd9Sstevel@tonic-gate default: 1555*7c478bd9Sstevel@tonic-gate log_message(MSG_INFO, "Invalid size: %d\n", size); 1556*7c478bd9Sstevel@tonic-gate return; 1557*7c478bd9Sstevel@tonic-gate } 1558*7c478bd9Sstevel@tonic-gate if (value == match_value) 1559*7c478bd9Sstevel@tonic-gate log_message(MSG_INFO, "%p\n", fromaddr); 1560*7c478bd9Sstevel@tonic-gate } 1561*7c478bd9Sstevel@tonic-gate } 1562*7c478bd9Sstevel@tonic-gate 1563*7c478bd9Sstevel@tonic-gate #pragma init(_init) 1564*7c478bd9Sstevel@tonic-gate 1565*7c478bd9Sstevel@tonic-gate static void 1566*7c478bd9Sstevel@tonic-gate _init(void) 1567*7c478bd9Sstevel@tonic-gate { 1568*7c478bd9Sstevel@tonic-gate fcode_env_t *env = initial_env; 1569*7c478bd9Sstevel@tonic-gate 1570*7c478bd9Sstevel@tonic-gate ASSERT(env); 1571*7c478bd9Sstevel@tonic-gate NOTICE; 1572*7c478bd9Sstevel@tonic-gate 1573*7c478bd9Sstevel@tonic-gate FORTH(IMMEDIATE, "words", words); 1574*7c478bd9Sstevel@tonic-gate FORTH(IMMEDIATE, "dump-words", dump_words); 1575*7c478bd9Sstevel@tonic-gate FORTH(IMMEDIATE, "dump-dict", dump_dictionary); 1576*7c478bd9Sstevel@tonic-gate FORTH(IMMEDIATE, "dump-table", dump_table); 1577*7c478bd9Sstevel@tonic-gate FORTH(0, "debugf", debugf); 1578*7c478bd9Sstevel@tonic-gate FORTH(0, ".debugf", dot_debugf); 1579*7c478bd9Sstevel@tonic-gate FORTH(0, "set-debugf", set_debugf); 1580*7c478bd9Sstevel@tonic-gate FORTH(0, "debugf?", debugf_qmark); 1581*7c478bd9Sstevel@tonic-gate FORTH(0, "control", control); 1582*7c478bd9Sstevel@tonic-gate FORTH(0, "dump", dump); 1583*7c478bd9Sstevel@tonic-gate FORTH(IMMEDIATE, "showstack", show_stack); 1584*7c478bd9Sstevel@tonic-gate FORTH(IMMEDIATE, "sifting", sifting); 1585*7c478bd9Sstevel@tonic-gate FORTH(IMMEDIATE, "ctrace", ctrace); 1586*7c478bd9Sstevel@tonic-gate FORTH(IMMEDIATE, "ftrace", ftrace); 1587*7c478bd9Sstevel@tonic-gate FORTH(0, "see", see); 1588*7c478bd9Sstevel@tonic-gate FORTH(0, "(see)", paren_see); 1589*7c478bd9Sstevel@tonic-gate FORTH(0, "base-addr", base_addr); 1590*7c478bd9Sstevel@tonic-gate FORTH(0, "smatch", smatch); 1591*7c478bd9Sstevel@tonic-gate FORTH(0, ".calls", dot_calls); 1592*7c478bd9Sstevel@tonic-gate FORTH(0, ".pci-space", dot_pci_space); 1593*7c478bd9Sstevel@tonic-gate FORTH(0, "(debug)", paren_debug); 1594*7c478bd9Sstevel@tonic-gate FORTH(0, "debug", debug); 1595*7c478bd9Sstevel@tonic-gate FORTH(0, ".debug", dot_debug); 1596*7c478bd9Sstevel@tonic-gate FORTH(0, "undebug", undebug); 1597*7c478bd9Sstevel@tonic-gate FORTH(0, "memory-watch", memory_watch); 1598*7c478bd9Sstevel@tonic-gate FORTH(0, "memory-watch-value", memory_watch_value); 1599*7c478bd9Sstevel@tonic-gate FORTH(0, "memory-watch-clear", memory_watch_clear); 1600*7c478bd9Sstevel@tonic-gate FORTH(0, "vsearch", vsearch); 1601*7c478bd9Sstevel@tonic-gate } 1602