1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #pragma ident "%Z%%M% %I% %E% SMI" 27 28 #include <stdio.h> 29 #include <stdlib.h> 30 #include <string.h> 31 32 #include <fcode/private.h> 33 #include <fcode/log.h> 34 35 fcode_env_t *initial_env = 0; 36 int dict_size = 0x4000000; /* 64Mb, hopefully big enough... */ 37 int stack_size = 0x200; 38 39 void * 40 safe_malloc(size_t n, char *f, int l) 41 { 42 void *p; 43 44 p = malloc((size_t)n); 45 #if defined(__sparcv9) 46 /* 47 * For Ultrasparc, we must force addresses to be less than 4Gb, 48 * since Fcode assumes that addresses can be stored in 32 bits. 49 * To get around this would require turning all addresses into 50 * cookies, which is a lot of work. 51 */ 52 if (((uint64_t)p) >= 0x100000000) { 53 log_message(MSG_WARN, "Malloc returned address > 4Gb\n"); 54 } 55 #endif /* __sparcv9 */ 56 if (p) { 57 memset(p, 0, (size_t)n); 58 } else 59 log_message(MSG_ERROR, "%s:%d:Malloc(%llx) failed\n", f, l, 60 (uint64_t)n); 61 return (p); 62 } 63 64 void * 65 safe_realloc(void *p, size_t n, char *f, int l) 66 { 67 void *newp; 68 69 if ((newp = safe_malloc(n, f, l)) == NULL) { 70 log_message(MSG_ERROR, "%s:%d:realloc(%p, %x) failed\n", f, l, 71 p, n); 72 safe_free(p, f, l); 73 return (NULL); 74 } 75 if (p) { 76 memcpy(newp, p, n); 77 safe_free(p, f, l); 78 } 79 return (newp); 80 } 81 82 void 83 safe_free(void *p, char *f, int l) 84 { 85 if (p) { 86 free(p); 87 } 88 } 89 90 char * 91 safe_strdup(char *s, char *f, int l) 92 { 93 char *p = strdup(s); 94 95 return (p); 96 } 97 98 #pragma init(_init) 99 100 static void 101 _init(void) 102 { 103 int i; 104 acf_t f_error_addr; 105 fcode_env_t *env; 106 107 NOTICE; 108 109 fcode_impl_count = 0; 110 env = MALLOC(sizeof (fcode_env_t)); 111 env->table = MALLOC((MAX_FCODE + 1) * sizeof (fcode_token)); 112 env->base = MALLOC(dict_size); 113 env->here = env->base; 114 env->ds = env->ds0 = MALLOC(stack_size * sizeof (fstack_t)); 115 env->rs = env->rs0 = MALLOC(stack_size * sizeof (fstack_t)); 116 env->order = MALLOC(MAX_ORDER * sizeof (token_t)); 117 env->input = MALLOC(sizeof (input_typ)); 118 env->num_base = 0x10; 119 120 /* Setup the initial forth environment */ 121 do_forth(env); 122 do_definitions(env); 123 install_handlers(env); 124 125 initial_env = env; 126 127 /* 128 * Need to define this early because it is the default for 129 * all unimpl, FCODE functions 130 */ 131 P1275(0x0fc, IMMEDIATE, "ferror", f_error); 132 f_error_addr = LINK_TO_ACF(env->lastlink); 133 for (i = 0; i <= MAX_FCODE; i++) { 134 DEBUGF(ANY, env->table[i].usage = 0); 135 SET_TOKEN(i, IMMEDIATE, "ferror", f_error_addr); 136 } 137 fcode_impl_count = 0; 138 } 139