xref: /titanic_53/usr/src/cmd/geniconvtbl/geniconvtbl.c (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
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 1999, 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 <stdlib.h>
31*7c478bd9Sstevel@tonic-gate #include <strings.h>
32*7c478bd9Sstevel@tonic-gate #include <unistd.h>
33*7c478bd9Sstevel@tonic-gate #include <fcntl.h>
34*7c478bd9Sstevel@tonic-gate #include <errno.h>
35*7c478bd9Sstevel@tonic-gate #include <sys/types.h>
36*7c478bd9Sstevel@tonic-gate #include <sys/stat.h>
37*7c478bd9Sstevel@tonic-gate #include <sys/mman.h>
38*7c478bd9Sstevel@tonic-gate #include <synch.h>
39*7c478bd9Sstevel@tonic-gate 
40*7c478bd9Sstevel@tonic-gate #if defined(DEBUG)
41*7c478bd9Sstevel@tonic-gate #include <stdarg.h>
42*7c478bd9Sstevel@tonic-gate #endif /* !DEBUG */
43*7c478bd9Sstevel@tonic-gate 
44*7c478bd9Sstevel@tonic-gate #include "iconv_tm.h"
45*7c478bd9Sstevel@tonic-gate #include "hash.h"
46*7c478bd9Sstevel@tonic-gate 
47*7c478bd9Sstevel@tonic-gate 
48*7c478bd9Sstevel@tonic-gate /*
49*7c478bd9Sstevel@tonic-gate  * Debug
50*7c478bd9Sstevel@tonic-gate  */
51*7c478bd9Sstevel@tonic-gate #if defined(DEBUG)
52*7c478bd9Sstevel@tonic-gate 
53*7c478bd9Sstevel@tonic-gate static void	trace_init(void);
54*7c478bd9Sstevel@tonic-gate static void	trace_message(char *, ...);
55*7c478bd9Sstevel@tonic-gate 
56*7c478bd9Sstevel@tonic-gate static char	trace_option[128];
57*7c478bd9Sstevel@tonic-gate 
58*7c478bd9Sstevel@tonic-gate #define	TRACE(c)		(*(trace_option + (c & 0x007f)))
59*7c478bd9Sstevel@tonic-gate #define	TRACE_MESSAGE(c, args)	((TRACE(c))? trace_message args: (void)0)
60*7c478bd9Sstevel@tonic-gate 
61*7c478bd9Sstevel@tonic-gate #else /* !DEBUG */
62*7c478bd9Sstevel@tonic-gate 
63*7c478bd9Sstevel@tonic-gate #define	trace_init()
64*7c478bd9Sstevel@tonic-gate #define	TRACE()
65*7c478bd9Sstevel@tonic-gate #define	TRACE_MESSAGE(c, args)
66*7c478bd9Sstevel@tonic-gate 
67*7c478bd9Sstevel@tonic-gate #endif /* !DEBUG */
68*7c478bd9Sstevel@tonic-gate 
69*7c478bd9Sstevel@tonic-gate 
70*7c478bd9Sstevel@tonic-gate /*
71*7c478bd9Sstevel@tonic-gate  * ITM reference information
72*7c478bd9Sstevel@tonic-gate  */
73*7c478bd9Sstevel@tonic-gate typedef struct _itm_ref {
74*7c478bd9Sstevel@tonic-gate 	char		*name;		/* ITM file name */
75*7c478bd9Sstevel@tonic-gate 	itm_hdr_t	*hdr;		/* address of ITM */
76*7c478bd9Sstevel@tonic-gate 	size_t		len;		/* length of ITM */
77*7c478bd9Sstevel@tonic-gate } itm_ref_t;
78*7c478bd9Sstevel@tonic-gate 
79*7c478bd9Sstevel@tonic-gate 
80*7c478bd9Sstevel@tonic-gate /*
81*7c478bd9Sstevel@tonic-gate  * struct _icv_state; to keep status
82*7c478bd9Sstevel@tonic-gate  */
83*7c478bd9Sstevel@tonic-gate typedef struct _icv_state {
84*7c478bd9Sstevel@tonic-gate 	struct _itm_ref	*itm;		/* reference to ITM */
85*7c478bd9Sstevel@tonic-gate 	itm_hdr_t	*itm_hdr;	/* address of ITM */
86*7c478bd9Sstevel@tonic-gate 	itm_tbl_hdr_t	*direc;		/* current direction */
87*7c478bd9Sstevel@tonic-gate 	itm_place_t	default_action;	/* default action */
88*7c478bd9Sstevel@tonic-gate 	itm_num_t	*regs;		/* register */
89*7c478bd9Sstevel@tonic-gate 	itm_num_t	reg_num;	/* number of register */
90*7c478bd9Sstevel@tonic-gate #if defined(OP_DEPTH_MAX)
91*7c478bd9Sstevel@tonic-gate 	int		op_depth;	/* depth of operation */
92*7c478bd9Sstevel@tonic-gate #endif /* OP_DEPTH_MAX */
93*7c478bd9Sstevel@tonic-gate } icv_state_t;
94*7c478bd9Sstevel@tonic-gate 
95*7c478bd9Sstevel@tonic-gate 
96*7c478bd9Sstevel@tonic-gate /*
97*7c478bd9Sstevel@tonic-gate  * function prototype
98*7c478bd9Sstevel@tonic-gate  */
99*7c478bd9Sstevel@tonic-gate void *	_icv_open(const char *);
100*7c478bd9Sstevel@tonic-gate void	_icv_close(icv_state_t *);
101*7c478bd9Sstevel@tonic-gate size_t	_icv_iconv(icv_state_t *, const unsigned char **,
102*7c478bd9Sstevel@tonic-gate 		    size_t *, unsigned char **, size_t *);
103*7c478bd9Sstevel@tonic-gate 
104*7c478bd9Sstevel@tonic-gate static size_t	map_i_f(itm_tbl_hdr_t *,
105*7c478bd9Sstevel@tonic-gate 			const unsigned char **, size_t *,
106*7c478bd9Sstevel@tonic-gate 			unsigned char **, size_t *, long);
107*7c478bd9Sstevel@tonic-gate static size_t	map_l_f(itm_tbl_hdr_t *,
108*7c478bd9Sstevel@tonic-gate 			const unsigned char **, size_t *,
109*7c478bd9Sstevel@tonic-gate 			unsigned char **, size_t *, long);
110*7c478bd9Sstevel@tonic-gate static size_t	map_h_l(itm_tbl_hdr_t *,
111*7c478bd9Sstevel@tonic-gate 			const unsigned char **, size_t *,
112*7c478bd9Sstevel@tonic-gate 			unsigned char **, size_t *, long);
113*7c478bd9Sstevel@tonic-gate static size_t	map_d_e_l(itm_tbl_hdr_t *,
114*7c478bd9Sstevel@tonic-gate 			const unsigned char **, size_t *,
115*7c478bd9Sstevel@tonic-gate 			unsigned char **, size_t *, long);
116*7c478bd9Sstevel@tonic-gate static size_t	eval_cond_tbl(icv_state_t *, itm_place_t,
117*7c478bd9Sstevel@tonic-gate 			const unsigned char **, size_t *,
118*7c478bd9Sstevel@tonic-gate 			size_t, itm_direc_t *);
119*7c478bd9Sstevel@tonic-gate static size_t	eval_op_tbl(icv_state_t *, itm_place_t,
120*7c478bd9Sstevel@tonic-gate 			const unsigned char **, size_t *,
121*7c478bd9Sstevel@tonic-gate 			unsigned char **, size_t *);
122*7c478bd9Sstevel@tonic-gate static size_t	eval_op(icv_state_t *, itm_place2_t,
123*7c478bd9Sstevel@tonic-gate 			const unsigned char **, size_t *,
124*7c478bd9Sstevel@tonic-gate 			unsigned char **, size_t *);
125*7c478bd9Sstevel@tonic-gate 
126*7c478bd9Sstevel@tonic-gate static itm_num_t	eval_expr(icv_state_t *, itm_place_t,
127*7c478bd9Sstevel@tonic-gate 				size_t, const unsigned char *, size_t);
128*7c478bd9Sstevel@tonic-gate 
129*7c478bd9Sstevel@tonic-gate static void		itm_ref_free(int, void *, void *, void *, size_t);
130*7c478bd9Sstevel@tonic-gate static itm_ref_t	*itm_ref_inc(const char *);
131*7c478bd9Sstevel@tonic-gate static void		itm_ref_dec(itm_ref_t *);
132*7c478bd9Sstevel@tonic-gate 
133*7c478bd9Sstevel@tonic-gate static void		op_init_default(icv_state_t *);
134*7c478bd9Sstevel@tonic-gate static void		op_reset_default(icv_state_t *);
135*7c478bd9Sstevel@tonic-gate static void		regs_init(icv_state_t *);
136*7c478bd9Sstevel@tonic-gate 
137*7c478bd9Sstevel@tonic-gate 
138*7c478bd9Sstevel@tonic-gate /*
139*7c478bd9Sstevel@tonic-gate  * macro definition
140*7c478bd9Sstevel@tonic-gate  */
141*7c478bd9Sstevel@tonic-gate 
142*7c478bd9Sstevel@tonic-gate #define	ADDR(place)	((void *)(((char *)(ist->itm_hdr)) +\
143*7c478bd9Sstevel@tonic-gate 				((itm_place2_t)(place.itm_ptr))))
144*7c478bd9Sstevel@tonic-gate #define	ADDR2(place2)	((void *)(((char *)(ist->itm_hdr)) +\
145*7c478bd9Sstevel@tonic-gate 				((itm_place2_t)(place2))))
146*7c478bd9Sstevel@tonic-gate #define	DADDR(n)	(((n)->size <= (sizeof ((n)->place.itm_64d))) ?	\
147*7c478bd9Sstevel@tonic-gate 				((unsigned char *)(&((n)->place.itm_64d))) :\
148*7c478bd9Sstevel@tonic-gate 				((unsigned char *)(ADDR((n)->place))))
149*7c478bd9Sstevel@tonic-gate 
150*7c478bd9Sstevel@tonic-gate #define	REG(n)		(*(ist->regs + (n)))
151*7c478bd9Sstevel@tonic-gate #define	DISCARD(c)	(((*inbuf) = (void *)((*inbuf) + (c))),\
152*7c478bd9Sstevel@tonic-gate 			((*inbytesleft) -= (c)))
153*7c478bd9Sstevel@tonic-gate #define	GET(c)		((c) = **inbuf, (*inbuf)++, (*inbytesleft)--)
154*7c478bd9Sstevel@tonic-gate #define	PUT(c)		(**outbuf = (c), (*outbuf)++, (*outbytesleft)--)
155*7c478bd9Sstevel@tonic-gate 
156*7c478bd9Sstevel@tonic-gate #define	RETVALERR	((size_t)(-1))
157*7c478bd9Sstevel@tonic-gate #define	RETVALDIR	((size_t)(-2))
158*7c478bd9Sstevel@tonic-gate #define	RETVALBRK	((size_t)(-3))
159*7c478bd9Sstevel@tonic-gate #define	RETVALRET	((size_t)(-4))
160*7c478bd9Sstevel@tonic-gate 
161*7c478bd9Sstevel@tonic-gate #define	UPDATE_ARGS()	(*inbuf = ip, \
162*7c478bd9Sstevel@tonic-gate 			 *inbytesleft = ileft, \
163*7c478bd9Sstevel@tonic-gate 			 *outbuf = op, \
164*7c478bd9Sstevel@tonic-gate 			 *outbytesleft = oleft)
165*7c478bd9Sstevel@tonic-gate 
166*7c478bd9Sstevel@tonic-gate /*
167*7c478bd9Sstevel@tonic-gate  * Open; called from iconv_open()
168*7c478bd9Sstevel@tonic-gate  */
169*7c478bd9Sstevel@tonic-gate void *
170*7c478bd9Sstevel@tonic-gate _icv_open(const char	*itm)
171*7c478bd9Sstevel@tonic-gate {
172*7c478bd9Sstevel@tonic-gate 	icv_state_t	*ist;
173*7c478bd9Sstevel@tonic-gate 	itm_hdr_t	*hdr;
174*7c478bd9Sstevel@tonic-gate 	itm_ref_t	*itm_ref;
175*7c478bd9Sstevel@tonic-gate 	int		r;
176*7c478bd9Sstevel@tonic-gate 
177*7c478bd9Sstevel@tonic-gate 	/*
178*7c478bd9Sstevel@tonic-gate 	 * for debug
179*7c478bd9Sstevel@tonic-gate 	 */
180*7c478bd9Sstevel@tonic-gate 	trace_init();
181*7c478bd9Sstevel@tonic-gate 
182*7c478bd9Sstevel@tonic-gate 	/*
183*7c478bd9Sstevel@tonic-gate 	 * _icv_open() primaty task
184*7c478bd9Sstevel@tonic-gate 	 */
185*7c478bd9Sstevel@tonic-gate 	itm_ref = itm_ref_inc(itm);
186*7c478bd9Sstevel@tonic-gate 	if (NULL == itm_ref) {
187*7c478bd9Sstevel@tonic-gate 		return ((void *)(-1));
188*7c478bd9Sstevel@tonic-gate 	}
189*7c478bd9Sstevel@tonic-gate 
190*7c478bd9Sstevel@tonic-gate 	if (NULL == (ist = malloc(sizeof (icv_state_t)))) {
191*7c478bd9Sstevel@tonic-gate 		r = errno;
192*7c478bd9Sstevel@tonic-gate 		itm_ref_dec(itm_ref);
193*7c478bd9Sstevel@tonic-gate 		errno = r;
194*7c478bd9Sstevel@tonic-gate 		return	(NULL);
195*7c478bd9Sstevel@tonic-gate 	}
196*7c478bd9Sstevel@tonic-gate 
197*7c478bd9Sstevel@tonic-gate 	ist->itm = itm_ref;
198*7c478bd9Sstevel@tonic-gate 	ist->itm_hdr = ist->itm->hdr;
199*7c478bd9Sstevel@tonic-gate 	ist->reg_num = ist->itm->hdr->reg_num;
200*7c478bd9Sstevel@tonic-gate 
201*7c478bd9Sstevel@tonic-gate 	hdr =  ist->itm->hdr;
202*7c478bd9Sstevel@tonic-gate 	ist->direc = ADDR(hdr->direc_init_tbl);
203*7c478bd9Sstevel@tonic-gate 	ist->default_action.itm_64d = 0;
204*7c478bd9Sstevel@tonic-gate #if defined(OP_DEPTH_MAX)
205*7c478bd9Sstevel@tonic-gate 	ist->op_depth = 0;
206*7c478bd9Sstevel@tonic-gate #endif /* OP_DEPTH_MAX */
207*7c478bd9Sstevel@tonic-gate 
208*7c478bd9Sstevel@tonic-gate 
209*7c478bd9Sstevel@tonic-gate 	/*
210*7c478bd9Sstevel@tonic-gate 	 * brief sanity check
211*7c478bd9Sstevel@tonic-gate 	 */
212*7c478bd9Sstevel@tonic-gate 	if (hdr->itm_size.itm_ptr <= hdr->direc_init_tbl.itm_ptr) {
213*7c478bd9Sstevel@tonic-gate 		_icv_close(ist);
214*7c478bd9Sstevel@tonic-gate 		errno = ELIBBAD;
215*7c478bd9Sstevel@tonic-gate 		return ((void *)(-1));
216*7c478bd9Sstevel@tonic-gate 	}
217*7c478bd9Sstevel@tonic-gate 
218*7c478bd9Sstevel@tonic-gate 
219*7c478bd9Sstevel@tonic-gate 	/* allocate register region */
220*7c478bd9Sstevel@tonic-gate 	if (hdr->reg_num <= 0) {
221*7c478bd9Sstevel@tonic-gate 		ist->regs = NULL;
222*7c478bd9Sstevel@tonic-gate 	} else {
223*7c478bd9Sstevel@tonic-gate 		ist->regs = malloc((sizeof (itm_num_t)) * hdr->reg_num);
224*7c478bd9Sstevel@tonic-gate 		if (NULL == ist->regs) {
225*7c478bd9Sstevel@tonic-gate 			r = errno;
226*7c478bd9Sstevel@tonic-gate 			_icv_close(ist);
227*7c478bd9Sstevel@tonic-gate 			errno = r;
228*7c478bd9Sstevel@tonic-gate 			return ((void *)(-1));
229*7c478bd9Sstevel@tonic-gate 		}
230*7c478bd9Sstevel@tonic-gate 		(void) memset(ist->regs, 0,
231*7c478bd9Sstevel@tonic-gate 			(sizeof (itm_num_t)) * hdr->reg_num);
232*7c478bd9Sstevel@tonic-gate 	}
233*7c478bd9Sstevel@tonic-gate 
234*7c478bd9Sstevel@tonic-gate 
235*7c478bd9Sstevel@tonic-gate 	/* evaluate init operation */
236*7c478bd9Sstevel@tonic-gate 	if (0 != ist->itm_hdr->op_init_tbl.itm_ptr) {
237*7c478bd9Sstevel@tonic-gate 		const unsigned char	*ip = NULL;
238*7c478bd9Sstevel@tonic-gate 		size_t			ileft = 0;
239*7c478bd9Sstevel@tonic-gate 		unsigned char		*op = NULL;
240*7c478bd9Sstevel@tonic-gate 		size_t			oleft = 0;
241*7c478bd9Sstevel@tonic-gate 		(void) eval_op_tbl(ist,
242*7c478bd9Sstevel@tonic-gate 			    ist->itm_hdr->op_init_tbl,
243*7c478bd9Sstevel@tonic-gate 			    &ip,
244*7c478bd9Sstevel@tonic-gate 			    &ileft,
245*7c478bd9Sstevel@tonic-gate 			    &op, &oleft);
246*7c478bd9Sstevel@tonic-gate 	} else {
247*7c478bd9Sstevel@tonic-gate 		op_init_default(ist);
248*7c478bd9Sstevel@tonic-gate 	}
249*7c478bd9Sstevel@tonic-gate 
250*7c478bd9Sstevel@tonic-gate 	return	(ist);
251*7c478bd9Sstevel@tonic-gate }
252*7c478bd9Sstevel@tonic-gate 
253*7c478bd9Sstevel@tonic-gate 
254*7c478bd9Sstevel@tonic-gate /*
255*7c478bd9Sstevel@tonic-gate  * Close; called from iconv_close
256*7c478bd9Sstevel@tonic-gate  */
257*7c478bd9Sstevel@tonic-gate void
258*7c478bd9Sstevel@tonic-gate _icv_close(icv_state_t		*ist)
259*7c478bd9Sstevel@tonic-gate {
260*7c478bd9Sstevel@tonic-gate 	if (NULL == ist) {
261*7c478bd9Sstevel@tonic-gate 		errno = EBADF;
262*7c478bd9Sstevel@tonic-gate 		return;
263*7c478bd9Sstevel@tonic-gate 	}
264*7c478bd9Sstevel@tonic-gate 	itm_ref_dec(ist->itm);
265*7c478bd9Sstevel@tonic-gate 	free(ist->regs);
266*7c478bd9Sstevel@tonic-gate 	free(ist);
267*7c478bd9Sstevel@tonic-gate }
268*7c478bd9Sstevel@tonic-gate 
269*7c478bd9Sstevel@tonic-gate 
270*7c478bd9Sstevel@tonic-gate /*
271*7c478bd9Sstevel@tonic-gate  * Actual conversion; called from iconv()
272*7c478bd9Sstevel@tonic-gate  */
273*7c478bd9Sstevel@tonic-gate size_t
274*7c478bd9Sstevel@tonic-gate _icv_iconv(
275*7c478bd9Sstevel@tonic-gate 	icv_state_t		*ist,
276*7c478bd9Sstevel@tonic-gate 	const unsigned char	**inbuf,
277*7c478bd9Sstevel@tonic-gate 	size_t			*inbytesleft,
278*7c478bd9Sstevel@tonic-gate 	unsigned char		**outbuf,
279*7c478bd9Sstevel@tonic-gate 	size_t			*outbytesleft)
280*7c478bd9Sstevel@tonic-gate {
281*7c478bd9Sstevel@tonic-gate 	size_t			retval;
282*7c478bd9Sstevel@tonic-gate 	itm_hdr_t		*hdr;
283*7c478bd9Sstevel@tonic-gate 	itm_type_t		type;
284*7c478bd9Sstevel@tonic-gate 	const unsigned char	*ip;
285*7c478bd9Sstevel@tonic-gate 	size_t			ileft;
286*7c478bd9Sstevel@tonic-gate 	itm_place_t		action;
287*7c478bd9Sstevel@tonic-gate 
288*7c478bd9Sstevel@tonic-gate 	if (NULL == ist) {
289*7c478bd9Sstevel@tonic-gate 		errno = EBADF;
290*7c478bd9Sstevel@tonic-gate 		TRACE_MESSAGE('e', ("_icv_iconv: error=%d\n", errno));
291*7c478bd9Sstevel@tonic-gate 		return ((size_t)(-1));
292*7c478bd9Sstevel@tonic-gate 	}
293*7c478bd9Sstevel@tonic-gate 	if (NULL == inbuf) {
294*7c478bd9Sstevel@tonic-gate 		ip = NULL;
295*7c478bd9Sstevel@tonic-gate 		inbuf = &ip;
296*7c478bd9Sstevel@tonic-gate 	}
297*7c478bd9Sstevel@tonic-gate 	if (NULL == inbytesleft) {
298*7c478bd9Sstevel@tonic-gate 		ileft = 0;
299*7c478bd9Sstevel@tonic-gate 		inbytesleft = &ileft;
300*7c478bd9Sstevel@tonic-gate 	}
301*7c478bd9Sstevel@tonic-gate 
302*7c478bd9Sstevel@tonic-gate 	hdr = ist->itm_hdr;
303*7c478bd9Sstevel@tonic-gate 
304*7c478bd9Sstevel@tonic-gate 	retval = 0;
305*7c478bd9Sstevel@tonic-gate 
306*7c478bd9Sstevel@tonic-gate 	TRACE_MESSAGE('i', ("_icv_iconv(inbuf=%p inbytesleft=%ld "
307*7c478bd9Sstevel@tonic-gate 			    "outbuf=%p outbytesleft=%ld)\n",
308*7c478bd9Sstevel@tonic-gate 			    (NULL == inbuf) ? 0 : *inbuf,
309*7c478bd9Sstevel@tonic-gate 			    (NULL == inbytesleft) ? 0 : *inbytesleft,
310*7c478bd9Sstevel@tonic-gate 			    (NULL == outbuf) ? 0 : *outbuf,
311*7c478bd9Sstevel@tonic-gate 			    (NULL == outbytesleft) ? 0 : *outbytesleft));
312*7c478bd9Sstevel@tonic-gate 
313*7c478bd9Sstevel@tonic-gate 	/*
314*7c478bd9Sstevel@tonic-gate 	 * If (NULL == inbuf || NULL == *inbuf) then this conversion is
315*7c478bd9Sstevel@tonic-gate 	 * placed into initial state.
316*7c478bd9Sstevel@tonic-gate 	 */
317*7c478bd9Sstevel@tonic-gate 	if ((NULL == inbuf) || (NULL == *inbuf)) {
318*7c478bd9Sstevel@tonic-gate 		if (0 != hdr->op_reset_tbl.itm_ptr) {
319*7c478bd9Sstevel@tonic-gate 			ist->direc = ADDR(hdr->direc_init_tbl);
320*7c478bd9Sstevel@tonic-gate 			retval = eval_op_tbl(ist,
321*7c478bd9Sstevel@tonic-gate 						hdr->op_reset_tbl,
322*7c478bd9Sstevel@tonic-gate 						inbuf, inbytesleft,
323*7c478bd9Sstevel@tonic-gate 						outbuf, outbytesleft);
324*7c478bd9Sstevel@tonic-gate 			if ((size_t)(-1) == retval) {
325*7c478bd9Sstevel@tonic-gate 				return	(retval);
326*7c478bd9Sstevel@tonic-gate 			}
327*7c478bd9Sstevel@tonic-gate 		} else {
328*7c478bd9Sstevel@tonic-gate 			op_reset_default(ist);
329*7c478bd9Sstevel@tonic-gate 		}
330*7c478bd9Sstevel@tonic-gate 		return ((size_t)(0));
331*7c478bd9Sstevel@tonic-gate 	}
332*7c478bd9Sstevel@tonic-gate 
333*7c478bd9Sstevel@tonic-gate 	if (ITM_TBL_MAP_INDEX_FIXED_1_1 == ist->direc->type) {
334*7c478bd9Sstevel@tonic-gate 		itm_map_idx_fix_hdr_t	*map_hdr;
335*7c478bd9Sstevel@tonic-gate 		char			*map;
336*7c478bd9Sstevel@tonic-gate 		const unsigned char	*ip;
337*7c478bd9Sstevel@tonic-gate 		size_t			ileft;
338*7c478bd9Sstevel@tonic-gate 		unsigned char		*op;
339*7c478bd9Sstevel@tonic-gate 		size_t			oleft;
340*7c478bd9Sstevel@tonic-gate 
341*7c478bd9Sstevel@tonic-gate 		map_hdr = (itm_map_idx_fix_hdr_t *)(ist->direc + 1);
342*7c478bd9Sstevel@tonic-gate 		map = (char *)(map_hdr + 1);
343*7c478bd9Sstevel@tonic-gate 
344*7c478bd9Sstevel@tonic-gate 		if (1 == map_hdr->default_error) {
345*7c478bd9Sstevel@tonic-gate 			retval = map_i_f(ist->direc,
346*7c478bd9Sstevel@tonic-gate 					inbuf, inbytesleft,
347*7c478bd9Sstevel@tonic-gate 					outbuf, outbytesleft, 0);
348*7c478bd9Sstevel@tonic-gate 			return	(retval);
349*7c478bd9Sstevel@tonic-gate 		}
350*7c478bd9Sstevel@tonic-gate 
351*7c478bd9Sstevel@tonic-gate 		ip = *inbuf;
352*7c478bd9Sstevel@tonic-gate 		ileft = *inbytesleft;
353*7c478bd9Sstevel@tonic-gate 		op = *outbuf;
354*7c478bd9Sstevel@tonic-gate 		oleft = *outbytesleft;
355*7c478bd9Sstevel@tonic-gate 
356*7c478bd9Sstevel@tonic-gate 		while (1 <= ileft) {
357*7c478bd9Sstevel@tonic-gate 			if (oleft < 1) {
358*7c478bd9Sstevel@tonic-gate 				UPDATE_ARGS();
359*7c478bd9Sstevel@tonic-gate 				errno = E2BIG;
360*7c478bd9Sstevel@tonic-gate 				TRACE_MESSAGE('e', ("_icv_iconv: error=%d\n",
361*7c478bd9Sstevel@tonic-gate 						errno));
362*7c478bd9Sstevel@tonic-gate 				return ((size_t)-1);
363*7c478bd9Sstevel@tonic-gate 			}
364*7c478bd9Sstevel@tonic-gate 			*(op++) = *(map + *(ip++));
365*7c478bd9Sstevel@tonic-gate 			ileft--;
366*7c478bd9Sstevel@tonic-gate 			oleft--;
367*7c478bd9Sstevel@tonic-gate 
368*7c478bd9Sstevel@tonic-gate 		}
369*7c478bd9Sstevel@tonic-gate 		UPDATE_ARGS();
370*7c478bd9Sstevel@tonic-gate 		return (0);
371*7c478bd9Sstevel@tonic-gate 	} else if (ITM_TBL_MAP_INDEX_FIXED == ist->direc->type) {
372*7c478bd9Sstevel@tonic-gate 		retval = map_i_f(ist->direc,
373*7c478bd9Sstevel@tonic-gate 				inbuf, inbytesleft,
374*7c478bd9Sstevel@tonic-gate 				outbuf, outbytesleft, 0);
375*7c478bd9Sstevel@tonic-gate 		return	(retval);
376*7c478bd9Sstevel@tonic-gate 	} else if (ITM_TBL_MAP_HASH == ist->direc->type) {
377*7c478bd9Sstevel@tonic-gate 		retval = map_h_l(ist->direc,
378*7c478bd9Sstevel@tonic-gate 				inbuf, inbytesleft,
379*7c478bd9Sstevel@tonic-gate 				outbuf, outbytesleft, 0);
380*7c478bd9Sstevel@tonic-gate 		return	(retval);
381*7c478bd9Sstevel@tonic-gate 	} else if (ITM_TBL_MAP_DENSE_ENC == ist->direc->type) {
382*7c478bd9Sstevel@tonic-gate 		retval = map_d_e_l(ist->direc,
383*7c478bd9Sstevel@tonic-gate 				inbuf, inbytesleft,
384*7c478bd9Sstevel@tonic-gate 				outbuf, outbytesleft, 0);
385*7c478bd9Sstevel@tonic-gate 		return	(retval);
386*7c478bd9Sstevel@tonic-gate 	} else if (ITM_TBL_MAP_LOOKUP == ist->direc->type) {
387*7c478bd9Sstevel@tonic-gate 		retval = map_l_f(ist->direc,
388*7c478bd9Sstevel@tonic-gate 				inbuf, inbytesleft,
389*7c478bd9Sstevel@tonic-gate 				outbuf, outbytesleft, 0);
390*7c478bd9Sstevel@tonic-gate 		return	(retval);
391*7c478bd9Sstevel@tonic-gate 	}
392*7c478bd9Sstevel@tonic-gate 
393*7c478bd9Sstevel@tonic-gate #if defined(OP_DEPTH_MAX)
394*7c478bd9Sstevel@tonic-gate 	ist->op_depth = 0;
395*7c478bd9Sstevel@tonic-gate #endif /* OP_DEPTH_MAX */
396*7c478bd9Sstevel@tonic-gate 
397*7c478bd9Sstevel@tonic-gate 
398*7c478bd9Sstevel@tonic-gate 	/*
399*7c478bd9Sstevel@tonic-gate 	 * Main loop; basically 1 loop per 1 output character
400*7c478bd9Sstevel@tonic-gate 	 */
401*7c478bd9Sstevel@tonic-gate retry_cond_eval:
402*7c478bd9Sstevel@tonic-gate 	while (0 < *inbytesleft) {
403*7c478bd9Sstevel@tonic-gate 		itm_tbl_hdr_t	*direc_hdr;
404*7c478bd9Sstevel@tonic-gate 		itm_direc_t	*direc;
405*7c478bd9Sstevel@tonic-gate 		long		i;
406*7c478bd9Sstevel@tonic-gate 
407*7c478bd9Sstevel@tonic-gate 		direc_hdr = ist->direc;
408*7c478bd9Sstevel@tonic-gate 		direc = (itm_direc_t *)(ist->direc + 1);
409*7c478bd9Sstevel@tonic-gate 		for (i = 0; /* NULL */; i++, direc++) {
410*7c478bd9Sstevel@tonic-gate 			if (i >= direc_hdr->number) {
411*7c478bd9Sstevel@tonic-gate 				if (0 == ist->default_action.itm_ptr) {
412*7c478bd9Sstevel@tonic-gate 					errno = EILSEQ;
413*7c478bd9Sstevel@tonic-gate 					TRACE_MESSAGE('e',
414*7c478bd9Sstevel@tonic-gate 						("_icv_iconv:error=%d\n",
415*7c478bd9Sstevel@tonic-gate 						errno));
416*7c478bd9Sstevel@tonic-gate 					return ((size_t)(-1));
417*7c478bd9Sstevel@tonic-gate 				}
418*7c478bd9Sstevel@tonic-gate 
419*7c478bd9Sstevel@tonic-gate 
420*7c478bd9Sstevel@tonic-gate 
421*7c478bd9Sstevel@tonic-gate 				action = ist->default_action;
422*7c478bd9Sstevel@tonic-gate 				type = ((itm_tbl_hdr_t *)(ADDR(action)))->type;
423*7c478bd9Sstevel@tonic-gate 				TRACE_MESSAGE('E',
424*7c478bd9Sstevel@tonic-gate 				("escape seq (default action=%6p, type=%ld) "
425*7c478bd9Sstevel@tonic-gate 				"excuting\n", action.itm_ptr, type));
426*7c478bd9Sstevel@tonic-gate 			} else if (0 != direc->condition.itm_ptr) {
427*7c478bd9Sstevel@tonic-gate 				retval = eval_cond_tbl(ist, direc->condition,
428*7c478bd9Sstevel@tonic-gate 							inbuf, inbytesleft,
429*7c478bd9Sstevel@tonic-gate 							*outbytesleft,
430*7c478bd9Sstevel@tonic-gate 							direc);
431*7c478bd9Sstevel@tonic-gate 				if ((size_t)(0) == retval) {
432*7c478bd9Sstevel@tonic-gate 					continue;
433*7c478bd9Sstevel@tonic-gate 				} else if ((size_t)(-1) == retval) {
434*7c478bd9Sstevel@tonic-gate 					return	(retval);
435*7c478bd9Sstevel@tonic-gate 				} else if ((size_t)(2) == retval) {
436*7c478bd9Sstevel@tonic-gate 					goto retry_cond_eval;
437*7c478bd9Sstevel@tonic-gate 				}
438*7c478bd9Sstevel@tonic-gate 				action = direc->action;
439*7c478bd9Sstevel@tonic-gate 				type = ((itm_tbl_hdr_t *)(ADDR(action)))->type;
440*7c478bd9Sstevel@tonic-gate 			} else {
441*7c478bd9Sstevel@tonic-gate 				action = direc->action;
442*7c478bd9Sstevel@tonic-gate 				type = ((itm_tbl_hdr_t *)(ADDR(action)))->type;
443*7c478bd9Sstevel@tonic-gate 			}
444*7c478bd9Sstevel@tonic-gate 
445*7c478bd9Sstevel@tonic-gate 			TRACE_MESSAGE('a',
446*7c478bd9Sstevel@tonic-gate 				("inbytesleft=%ld; type=%ld:action=%p\n",
447*7c478bd9Sstevel@tonic-gate 				*inbytesleft, type, action.itm_ptr));
448*7c478bd9Sstevel@tonic-gate 			switch (ITM_TBL_MASK & type) {
449*7c478bd9Sstevel@tonic-gate 			case ITM_TBL_OP:
450*7c478bd9Sstevel@tonic-gate 				retval = eval_op_tbl(ist, action,
451*7c478bd9Sstevel@tonic-gate 						inbuf, inbytesleft,
452*7c478bd9Sstevel@tonic-gate 						outbuf, outbytesleft);
453*7c478bd9Sstevel@tonic-gate 				if ((size_t)(-1) == retval) {
454*7c478bd9Sstevel@tonic-gate 					return	(retval);
455*7c478bd9Sstevel@tonic-gate 				}
456*7c478bd9Sstevel@tonic-gate 				break;
457*7c478bd9Sstevel@tonic-gate 			case ITM_TBL_DIREC:
458*7c478bd9Sstevel@tonic-gate 				ist->direc = ADDR(action);
459*7c478bd9Sstevel@tonic-gate 				break;
460*7c478bd9Sstevel@tonic-gate 			case ITM_TBL_MAP:
461*7c478bd9Sstevel@tonic-gate 				switch (type) {
462*7c478bd9Sstevel@tonic-gate 				case ITM_TBL_MAP_INDEX_FIXED_1_1:
463*7c478bd9Sstevel@tonic-gate 				case ITM_TBL_MAP_INDEX_FIXED:
464*7c478bd9Sstevel@tonic-gate 					retval = map_i_f(
465*7c478bd9Sstevel@tonic-gate 						    ADDR(action),
466*7c478bd9Sstevel@tonic-gate 						    inbuf, inbytesleft,
467*7c478bd9Sstevel@tonic-gate 						    outbuf, outbytesleft,
468*7c478bd9Sstevel@tonic-gate 						    1);
469*7c478bd9Sstevel@tonic-gate 					break;
470*7c478bd9Sstevel@tonic-gate 				case ITM_TBL_MAP_HASH:
471*7c478bd9Sstevel@tonic-gate 					retval = map_h_l(ADDR(action),
472*7c478bd9Sstevel@tonic-gate 						    inbuf, inbytesleft,
473*7c478bd9Sstevel@tonic-gate 						    outbuf, outbytesleft, 1);
474*7c478bd9Sstevel@tonic-gate 					break;
475*7c478bd9Sstevel@tonic-gate 				case ITM_TBL_MAP_DENSE_ENC:
476*7c478bd9Sstevel@tonic-gate 					retval = map_d_e_l(ADDR(action),
477*7c478bd9Sstevel@tonic-gate 						    inbuf, inbytesleft,
478*7c478bd9Sstevel@tonic-gate 						    outbuf, outbytesleft, 1);
479*7c478bd9Sstevel@tonic-gate 					break;
480*7c478bd9Sstevel@tonic-gate 				case ITM_TBL_MAP_LOOKUP:
481*7c478bd9Sstevel@tonic-gate 					retval = map_l_f(
482*7c478bd9Sstevel@tonic-gate 						    ADDR(action),
483*7c478bd9Sstevel@tonic-gate 						    inbuf, inbytesleft,
484*7c478bd9Sstevel@tonic-gate 						    outbuf, outbytesleft,
485*7c478bd9Sstevel@tonic-gate 						    1);
486*7c478bd9Sstevel@tonic-gate 					break;
487*7c478bd9Sstevel@tonic-gate 				default:
488*7c478bd9Sstevel@tonic-gate 					errno = ELIBBAD;
489*7c478bd9Sstevel@tonic-gate 					TRACE_MESSAGE('e',
490*7c478bd9Sstevel@tonic-gate 					("_icv_iconv:error=%d\n", errno));
491*7c478bd9Sstevel@tonic-gate 					return ((size_t)(-1));
492*7c478bd9Sstevel@tonic-gate 
493*7c478bd9Sstevel@tonic-gate 				}
494*7c478bd9Sstevel@tonic-gate 				if ((size_t)(-1) == retval) {
495*7c478bd9Sstevel@tonic-gate 					return	(retval);
496*7c478bd9Sstevel@tonic-gate 				}
497*7c478bd9Sstevel@tonic-gate 				break;
498*7c478bd9Sstevel@tonic-gate 			default:	/* never */
499*7c478bd9Sstevel@tonic-gate 				errno = ELIBBAD;
500*7c478bd9Sstevel@tonic-gate 				TRACE_MESSAGE('e',
501*7c478bd9Sstevel@tonic-gate 				("_icv_iconv:error=%d\n", errno));
502*7c478bd9Sstevel@tonic-gate 				return ((size_t)(-1));
503*7c478bd9Sstevel@tonic-gate 			}
504*7c478bd9Sstevel@tonic-gate 			break;
505*7c478bd9Sstevel@tonic-gate 		}
506*7c478bd9Sstevel@tonic-gate 	}
507*7c478bd9Sstevel@tonic-gate 	return	(retval);
508*7c478bd9Sstevel@tonic-gate }
509*7c478bd9Sstevel@tonic-gate 
510*7c478bd9Sstevel@tonic-gate 
511*7c478bd9Sstevel@tonic-gate 
512*7c478bd9Sstevel@tonic-gate /*
513*7c478bd9Sstevel@tonic-gate  * map-indexed-fixed
514*7c478bd9Sstevel@tonic-gate  */
515*7c478bd9Sstevel@tonic-gate static size_t
516*7c478bd9Sstevel@tonic-gate map_i_f(
517*7c478bd9Sstevel@tonic-gate 	itm_tbl_hdr_t		*tbl_hdr,
518*7c478bd9Sstevel@tonic-gate 	const unsigned char	**inbuf,
519*7c478bd9Sstevel@tonic-gate 	size_t			*inbytesleft,
520*7c478bd9Sstevel@tonic-gate 	unsigned char		**outbuf,
521*7c478bd9Sstevel@tonic-gate 	size_t			*outbytesleft,
522*7c478bd9Sstevel@tonic-gate 	long			once)
523*7c478bd9Sstevel@tonic-gate {
524*7c478bd9Sstevel@tonic-gate 	itm_map_idx_fix_hdr_t	*map_hdr;
525*7c478bd9Sstevel@tonic-gate 	long			i;
526*7c478bd9Sstevel@tonic-gate 	unsigned char		c;
527*7c478bd9Sstevel@tonic-gate 	unsigned long		j;
528*7c478bd9Sstevel@tonic-gate 	const unsigned char	*p;
529*7c478bd9Sstevel@tonic-gate 
530*7c478bd9Sstevel@tonic-gate 	TRACE_MESSAGE('i', ("map_i_f\n"));
531*7c478bd9Sstevel@tonic-gate 
532*7c478bd9Sstevel@tonic-gate 	map_hdr = (itm_map_idx_fix_hdr_t *)(tbl_hdr + 1);
533*7c478bd9Sstevel@tonic-gate 
534*7c478bd9Sstevel@tonic-gate 	do {
535*7c478bd9Sstevel@tonic-gate 		if (*inbytesleft < map_hdr->source_len) {
536*7c478bd9Sstevel@tonic-gate 			errno = EINVAL;
537*7c478bd9Sstevel@tonic-gate 			TRACE_MESSAGE('e', ("map_i_f:error=%d\n", errno));
538*7c478bd9Sstevel@tonic-gate 			return ((size_t)(-1));
539*7c478bd9Sstevel@tonic-gate 		}
540*7c478bd9Sstevel@tonic-gate 
541*7c478bd9Sstevel@tonic-gate 		j = 0;
542*7c478bd9Sstevel@tonic-gate 		for (i = 0; i < map_hdr->source_len; i++) {
543*7c478bd9Sstevel@tonic-gate 			GET(c);
544*7c478bd9Sstevel@tonic-gate 			j = ((j << 8) | c);
545*7c478bd9Sstevel@tonic-gate 		}
546*7c478bd9Sstevel@tonic-gate 
547*7c478bd9Sstevel@tonic-gate 		if (((j < map_hdr->start.itm_ptr) ||
548*7c478bd9Sstevel@tonic-gate 			(map_hdr->end.itm_ptr < j)) &&
549*7c478bd9Sstevel@tonic-gate 		    (0 < map_hdr->default_error)) {
550*7c478bd9Sstevel@tonic-gate 			errno = EILSEQ;
551*7c478bd9Sstevel@tonic-gate 			(*inbuf) = (void*) ((*inbuf) - map_hdr->source_len);
552*7c478bd9Sstevel@tonic-gate 			(*inbytesleft) += map_hdr->source_len;
553*7c478bd9Sstevel@tonic-gate 			TRACE_MESSAGE('e', ("map_i_f:error=%d\n", errno));
554*7c478bd9Sstevel@tonic-gate 			return ((size_t)(-1));
555*7c478bd9Sstevel@tonic-gate 		}
556*7c478bd9Sstevel@tonic-gate 
557*7c478bd9Sstevel@tonic-gate 		if (*outbytesleft < map_hdr->result_len) {
558*7c478bd9Sstevel@tonic-gate 			errno = E2BIG;
559*7c478bd9Sstevel@tonic-gate 			(*inbuf) = (void *)((*inbuf) - map_hdr->source_len);
560*7c478bd9Sstevel@tonic-gate 			(*inbytesleft) += map_hdr->source_len;
561*7c478bd9Sstevel@tonic-gate 			TRACE_MESSAGE('e', ("map_i_f:error=%d\n", errno));
562*7c478bd9Sstevel@tonic-gate 			return ((size_t)(-1));
563*7c478bd9Sstevel@tonic-gate 		}
564*7c478bd9Sstevel@tonic-gate 
565*7c478bd9Sstevel@tonic-gate 		if ((j < map_hdr->start.itm_ptr) ||
566*7c478bd9Sstevel@tonic-gate 			(map_hdr->end.itm_ptr < j)) {
567*7c478bd9Sstevel@tonic-gate 			if (0 == map_hdr->default_error) {
568*7c478bd9Sstevel@tonic-gate 				p = (((unsigned char *)(map_hdr + 1)) +
569*7c478bd9Sstevel@tonic-gate 					(map_hdr->result_len *
570*7c478bd9Sstevel@tonic-gate 					(tbl_hdr->number)));
571*7c478bd9Sstevel@tonic-gate 				for (i = 0; i < map_hdr->result_len; i++) {
572*7c478bd9Sstevel@tonic-gate 					PUT(*(p + i));
573*7c478bd9Sstevel@tonic-gate 				}
574*7c478bd9Sstevel@tonic-gate 			} else {
575*7c478bd9Sstevel@tonic-gate 				p = ((*inbuf) - map_hdr->source_len);
576*7c478bd9Sstevel@tonic-gate 				for (i = 0; i < map_hdr->source_len; i++) {
577*7c478bd9Sstevel@tonic-gate 					PUT(*(p + i));
578*7c478bd9Sstevel@tonic-gate 				}
579*7c478bd9Sstevel@tonic-gate 			}
580*7c478bd9Sstevel@tonic-gate 		} else {
581*7c478bd9Sstevel@tonic-gate 			char	*map_error;
582*7c478bd9Sstevel@tonic-gate 			map_error = (((char *)(map_hdr + 1)) +
583*7c478bd9Sstevel@tonic-gate 				    (map_hdr->result_len *
584*7c478bd9Sstevel@tonic-gate 				    (tbl_hdr->number)) +
585*7c478bd9Sstevel@tonic-gate 				    (j - map_hdr->start.itm_ptr));
586*7c478bd9Sstevel@tonic-gate 			if (0 == map_hdr->default_error) {
587*7c478bd9Sstevel@tonic-gate 				map_error = (void *)
588*7c478bd9Sstevel@tonic-gate 					(map_error + map_hdr->result_len);
589*7c478bd9Sstevel@tonic-gate 			}
590*7c478bd9Sstevel@tonic-gate 			if (((1 == map_hdr->default_error) ||
591*7c478bd9Sstevel@tonic-gate 			    (0 < map_hdr->error_num)) &&
592*7c478bd9Sstevel@tonic-gate 			    (0 != *(map_error))) {
593*7c478bd9Sstevel@tonic-gate 				errno = EILSEQ;
594*7c478bd9Sstevel@tonic-gate 				(*inbuf) = (void *)
595*7c478bd9Sstevel@tonic-gate 					((*inbuf) - map_hdr->source_len);
596*7c478bd9Sstevel@tonic-gate 				(*inbytesleft) += map_hdr->source_len;
597*7c478bd9Sstevel@tonic-gate 				TRACE_MESSAGE('e',
598*7c478bd9Sstevel@tonic-gate 				("map_i_f:error=%d\n", errno));
599*7c478bd9Sstevel@tonic-gate 				return ((size_t)(-1));
600*7c478bd9Sstevel@tonic-gate 			}
601*7c478bd9Sstevel@tonic-gate 			p = (((unsigned char *)(map_hdr + 1)) +
602*7c478bd9Sstevel@tonic-gate 				(map_hdr->result_len *
603*7c478bd9Sstevel@tonic-gate 				(j - map_hdr->start.itm_ptr)));
604*7c478bd9Sstevel@tonic-gate 			for (i = 0; i < map_hdr->result_len; i++) {
605*7c478bd9Sstevel@tonic-gate 				PUT(*(p + i));
606*7c478bd9Sstevel@tonic-gate 			}
607*7c478bd9Sstevel@tonic-gate 		}
608*7c478bd9Sstevel@tonic-gate 	} while ((0 < *inbytesleft) && (0 == once));
609*7c478bd9Sstevel@tonic-gate 
610*7c478bd9Sstevel@tonic-gate 	return (size_t)(0);
611*7c478bd9Sstevel@tonic-gate }
612*7c478bd9Sstevel@tonic-gate 
613*7c478bd9Sstevel@tonic-gate 
614*7c478bd9Sstevel@tonic-gate /*
615*7c478bd9Sstevel@tonic-gate  * map-lookup-fixed
616*7c478bd9Sstevel@tonic-gate  */
617*7c478bd9Sstevel@tonic-gate static size_t
618*7c478bd9Sstevel@tonic-gate map_l_f(
619*7c478bd9Sstevel@tonic-gate 	itm_tbl_hdr_t	*tbl_hdr,
620*7c478bd9Sstevel@tonic-gate 	const unsigned char	**inbuf,
621*7c478bd9Sstevel@tonic-gate 	size_t		*inbytesleft,
622*7c478bd9Sstevel@tonic-gate 	unsigned char	**outbuf,
623*7c478bd9Sstevel@tonic-gate 	size_t		*outbytesleft,
624*7c478bd9Sstevel@tonic-gate 	long		once)
625*7c478bd9Sstevel@tonic-gate {
626*7c478bd9Sstevel@tonic-gate 	itm_map_lookup_hdr_t	*map_hdr;
627*7c478bd9Sstevel@tonic-gate 	long			i;
628*7c478bd9Sstevel@tonic-gate 	unsigned char		*map;
629*7c478bd9Sstevel@tonic-gate 	const unsigned char	*p;
630*7c478bd9Sstevel@tonic-gate 	long			high;
631*7c478bd9Sstevel@tonic-gate 	long			mid;
632*7c478bd9Sstevel@tonic-gate 	long			low;
633*7c478bd9Sstevel@tonic-gate 	long			result;
634*7c478bd9Sstevel@tonic-gate 	itm_size_t		pair_size;
635*7c478bd9Sstevel@tonic-gate 
636*7c478bd9Sstevel@tonic-gate 	TRACE_MESSAGE('i', ("map_l_f\n"));
637*7c478bd9Sstevel@tonic-gate 
638*7c478bd9Sstevel@tonic-gate 	map_hdr = (itm_map_lookup_hdr_t *)(tbl_hdr + 1);
639*7c478bd9Sstevel@tonic-gate 	map = (unsigned char *)(map_hdr + 1);
640*7c478bd9Sstevel@tonic-gate 	pair_size = map_hdr->source_len + 1 + map_hdr->result_len;
641*7c478bd9Sstevel@tonic-gate 
642*7c478bd9Sstevel@tonic-gate 	do {
643*7c478bd9Sstevel@tonic-gate 		if (*inbytesleft < map_hdr->source_len) {
644*7c478bd9Sstevel@tonic-gate 			errno = EINVAL;
645*7c478bd9Sstevel@tonic-gate 			TRACE_MESSAGE('e', ("map_l_f:error=%d\n", errno));
646*7c478bd9Sstevel@tonic-gate 			return ((size_t)(-1));
647*7c478bd9Sstevel@tonic-gate 		}
648*7c478bd9Sstevel@tonic-gate 
649*7c478bd9Sstevel@tonic-gate 		for (low = 0, high = tbl_hdr->number; low < high; ) {
650*7c478bd9Sstevel@tonic-gate 			mid = (low + high) / 2;
651*7c478bd9Sstevel@tonic-gate 			p = map + (pair_size * mid);
652*7c478bd9Sstevel@tonic-gate 			for (i = 0, result = 0; i < map_hdr->source_len;
653*7c478bd9Sstevel@tonic-gate 			    i++, p++) {
654*7c478bd9Sstevel@tonic-gate 				if (*(unsigned char *)(*inbuf + i) < *p) {
655*7c478bd9Sstevel@tonic-gate 					result = -1;
656*7c478bd9Sstevel@tonic-gate 					break;
657*7c478bd9Sstevel@tonic-gate 				}
658*7c478bd9Sstevel@tonic-gate 				if (*p < *(unsigned char *)(*inbuf + i)) {
659*7c478bd9Sstevel@tonic-gate 					result = 1;
660*7c478bd9Sstevel@tonic-gate 					break;
661*7c478bd9Sstevel@tonic-gate 				}
662*7c478bd9Sstevel@tonic-gate 			}
663*7c478bd9Sstevel@tonic-gate 			if (result < 0) {
664*7c478bd9Sstevel@tonic-gate 				high = mid;
665*7c478bd9Sstevel@tonic-gate 			} else if (0 < result) {
666*7c478bd9Sstevel@tonic-gate 				low = mid + 1;
667*7c478bd9Sstevel@tonic-gate 			} else { /* 0 == result */
668*7c478bd9Sstevel@tonic-gate 				break;
669*7c478bd9Sstevel@tonic-gate 			}
670*7c478bd9Sstevel@tonic-gate 		}
671*7c478bd9Sstevel@tonic-gate 
672*7c478bd9Sstevel@tonic-gate 		if (0 != result) {
673*7c478bd9Sstevel@tonic-gate 			if (map_hdr->default_error < 0) {
674*7c478bd9Sstevel@tonic-gate 				p = *inbuf;
675*7c478bd9Sstevel@tonic-gate 			} else if (0 == map_hdr->default_error) {
676*7c478bd9Sstevel@tonic-gate 				p = map + (pair_size * tbl_hdr->number) +
677*7c478bd9Sstevel@tonic-gate 					map_hdr->source_len + 1;
678*7c478bd9Sstevel@tonic-gate 			} else if (0 < map_hdr->default_error) {
679*7c478bd9Sstevel@tonic-gate 				errno = EILSEQ;
680*7c478bd9Sstevel@tonic-gate 				TRACE_MESSAGE('e', ("map_l_f:error=%d\n",
681*7c478bd9Sstevel@tonic-gate 				errno));
682*7c478bd9Sstevel@tonic-gate 				return ((size_t)(-1));
683*7c478bd9Sstevel@tonic-gate 			}
684*7c478bd9Sstevel@tonic-gate 		} else {
685*7c478bd9Sstevel@tonic-gate 			if (0 != (*p)) {
686*7c478bd9Sstevel@tonic-gate 				errno = EILSEQ;
687*7c478bd9Sstevel@tonic-gate 				TRACE_MESSAGE('e', ("map_l_f:error=%d\n",
688*7c478bd9Sstevel@tonic-gate 				errno));
689*7c478bd9Sstevel@tonic-gate 				return ((size_t)(-1));
690*7c478bd9Sstevel@tonic-gate 			}
691*7c478bd9Sstevel@tonic-gate 			p++;
692*7c478bd9Sstevel@tonic-gate 		}
693*7c478bd9Sstevel@tonic-gate 
694*7c478bd9Sstevel@tonic-gate 		if (*outbytesleft < map_hdr->result_len) {
695*7c478bd9Sstevel@tonic-gate 			errno = E2BIG;
696*7c478bd9Sstevel@tonic-gate 			TRACE_MESSAGE('e', ("map_l_f:error=%d\n", errno));
697*7c478bd9Sstevel@tonic-gate 			return ((size_t)(-1));
698*7c478bd9Sstevel@tonic-gate 		}
699*7c478bd9Sstevel@tonic-gate 		DISCARD(map_hdr->source_len);
700*7c478bd9Sstevel@tonic-gate 
701*7c478bd9Sstevel@tonic-gate 		for (i = 0; i < map_hdr->result_len; i++) {
702*7c478bd9Sstevel@tonic-gate 			PUT(*(p + i));
703*7c478bd9Sstevel@tonic-gate 		}
704*7c478bd9Sstevel@tonic-gate 	} while ((0 < *inbytesleft) && (0 == once));
705*7c478bd9Sstevel@tonic-gate 
706*7c478bd9Sstevel@tonic-gate 	return ((size_t)(0));
707*7c478bd9Sstevel@tonic-gate }
708*7c478bd9Sstevel@tonic-gate 
709*7c478bd9Sstevel@tonic-gate 
710*7c478bd9Sstevel@tonic-gate /*
711*7c478bd9Sstevel@tonic-gate  * map-hash-lookup
712*7c478bd9Sstevel@tonic-gate  */
713*7c478bd9Sstevel@tonic-gate static size_t
714*7c478bd9Sstevel@tonic-gate map_h_l(
715*7c478bd9Sstevel@tonic-gate 	itm_tbl_hdr_t	*tbl_hdr,
716*7c478bd9Sstevel@tonic-gate 	const unsigned char	**inbuf,
717*7c478bd9Sstevel@tonic-gate 	size_t		*inbytesleft,
718*7c478bd9Sstevel@tonic-gate 	unsigned char	**outbuf,
719*7c478bd9Sstevel@tonic-gate 	size_t		*outbytesleft,
720*7c478bd9Sstevel@tonic-gate 	long		once)
721*7c478bd9Sstevel@tonic-gate {
722*7c478bd9Sstevel@tonic-gate 	itm_map_hash_hdr_t	*map_hdr;
723*7c478bd9Sstevel@tonic-gate 	long			i;
724*7c478bd9Sstevel@tonic-gate 	unsigned char	*map_error;
725*7c478bd9Sstevel@tonic-gate 	unsigned char	*map_hash;
726*7c478bd9Sstevel@tonic-gate 	unsigned char	*map_of;
727*7c478bd9Sstevel@tonic-gate 	const unsigned char	*p;
728*7c478bd9Sstevel@tonic-gate 	const unsigned char	*q;
729*7c478bd9Sstevel@tonic-gate 	long			high;
730*7c478bd9Sstevel@tonic-gate 	long			mid;
731*7c478bd9Sstevel@tonic-gate 	long			low;
732*7c478bd9Sstevel@tonic-gate 	long			result;
733*7c478bd9Sstevel@tonic-gate 	itm_size_t		pair_size;
734*7c478bd9Sstevel@tonic-gate 	itm_size_t		hash_value;
735*7c478bd9Sstevel@tonic-gate 	itm_size_t		source_len;
736*7c478bd9Sstevel@tonic-gate 	itm_size_t		result_len;
737*7c478bd9Sstevel@tonic-gate 
738*7c478bd9Sstevel@tonic-gate 	TRACE_MESSAGE('i', ("map_hash\n"));
739*7c478bd9Sstevel@tonic-gate 
740*7c478bd9Sstevel@tonic-gate 	map_hdr = (itm_map_hash_hdr_t *)(tbl_hdr + 1);
741*7c478bd9Sstevel@tonic-gate 	map_error = (unsigned char *)(map_hdr + 1);
742*7c478bd9Sstevel@tonic-gate 	map_hash = (map_error + map_hdr->hash_tbl_num);
743*7c478bd9Sstevel@tonic-gate 	map_of = map_hash + map_hdr->hash_tbl_size;
744*7c478bd9Sstevel@tonic-gate 	pair_size = map_hdr->source_len + 1 + map_hdr->result_len;
745*7c478bd9Sstevel@tonic-gate 	source_len = map_hdr->source_len;
746*7c478bd9Sstevel@tonic-gate 	result_len = map_hdr->result_len;
747*7c478bd9Sstevel@tonic-gate 
748*7c478bd9Sstevel@tonic-gate 	do {
749*7c478bd9Sstevel@tonic-gate 		if (*inbytesleft < source_len) {
750*7c478bd9Sstevel@tonic-gate 			errno = EINVAL;
751*7c478bd9Sstevel@tonic-gate 			TRACE_MESSAGE('e', ("map_h_l:error=%d\n", errno));
752*7c478bd9Sstevel@tonic-gate 			return ((size_t)(-1));
753*7c478bd9Sstevel@tonic-gate 		}
754*7c478bd9Sstevel@tonic-gate 
755*7c478bd9Sstevel@tonic-gate 		result = 1;
756*7c478bd9Sstevel@tonic-gate 		q = *inbuf;
757*7c478bd9Sstevel@tonic-gate 		hash_value = hash((const char *)(q),
758*7c478bd9Sstevel@tonic-gate 				source_len, map_hdr->hash_tbl_num);
759*7c478bd9Sstevel@tonic-gate 		p = map_hash + (pair_size * hash_value);
760*7c478bd9Sstevel@tonic-gate 		if (1 == *(map_error + hash_value)) {
761*7c478bd9Sstevel@tonic-gate 			for (i = 0, result = 0; i < source_len; i++) {
762*7c478bd9Sstevel@tonic-gate 				if (*(q + i) != *(p++)) {
763*7c478bd9Sstevel@tonic-gate 					result = -2;
764*7c478bd9Sstevel@tonic-gate 					break;
765*7c478bd9Sstevel@tonic-gate 				}
766*7c478bd9Sstevel@tonic-gate 			}
767*7c478bd9Sstevel@tonic-gate 			TRACE_MESSAGE('G',
768*7c478bd9Sstevel@tonic-gate 			("(h=%d): find pair without conflict\n",
769*7c478bd9Sstevel@tonic-gate 			hash_value));
770*7c478bd9Sstevel@tonic-gate 		} else if (0 == *(map_error + hash_value)) {
771*7c478bd9Sstevel@tonic-gate 			TRACE_MESSAGE('G',
772*7c478bd9Sstevel@tonic-gate 			("(h=%d): No Pair\n",
773*7c478bd9Sstevel@tonic-gate 			hash_value));
774*7c478bd9Sstevel@tonic-gate 			result = -3;
775*7c478bd9Sstevel@tonic-gate 		} else /* if (0 < *(map_error + hash_value)) */ {
776*7c478bd9Sstevel@tonic-gate 			for (i = 0, result = 0; i < source_len; i++) {
777*7c478bd9Sstevel@tonic-gate 				if (*(q + i) != *(p++)) {
778*7c478bd9Sstevel@tonic-gate 					result = 1;
779*7c478bd9Sstevel@tonic-gate 					break;
780*7c478bd9Sstevel@tonic-gate 				}
781*7c478bd9Sstevel@tonic-gate 			}
782*7c478bd9Sstevel@tonic-gate 			if (0 < result) {
783*7c478bd9Sstevel@tonic-gate 				for (low = 0, high = map_hdr->hash_of_num;
784*7c478bd9Sstevel@tonic-gate 				    low < high; /* NOP */) {
785*7c478bd9Sstevel@tonic-gate 					mid = (low + high) / 2;
786*7c478bd9Sstevel@tonic-gate 					p = map_of + (pair_size * mid);
787*7c478bd9Sstevel@tonic-gate 					for (i = 0, result = 0;
788*7c478bd9Sstevel@tonic-gate 					    i < source_len;
789*7c478bd9Sstevel@tonic-gate 					    i++, p++) {
790*7c478bd9Sstevel@tonic-gate 						if (*(q + i) < *p) {
791*7c478bd9Sstevel@tonic-gate 							result = -1;
792*7c478bd9Sstevel@tonic-gate 							break;
793*7c478bd9Sstevel@tonic-gate 						}
794*7c478bd9Sstevel@tonic-gate 						if (*p < *(q + i)) {
795*7c478bd9Sstevel@tonic-gate 							result = 1;
796*7c478bd9Sstevel@tonic-gate 							break;
797*7c478bd9Sstevel@tonic-gate 						}
798*7c478bd9Sstevel@tonic-gate 					}
799*7c478bd9Sstevel@tonic-gate 					if (result < 0) {
800*7c478bd9Sstevel@tonic-gate 						high = mid;
801*7c478bd9Sstevel@tonic-gate 					} else if (0 < result) {
802*7c478bd9Sstevel@tonic-gate 						low = mid + 1;
803*7c478bd9Sstevel@tonic-gate 					} else { /* 0 == result */
804*7c478bd9Sstevel@tonic-gate 						TRACE_MESSAGE('G',
805*7c478bd9Sstevel@tonic-gate 						("(h=%d): "
806*7c478bd9Sstevel@tonic-gate 						"find data on out ot "
807*7c478bd9Sstevel@tonic-gate 						"hashtable with CONFLICT\n",
808*7c478bd9Sstevel@tonic-gate 						hash_value));
809*7c478bd9Sstevel@tonic-gate 						break;
810*7c478bd9Sstevel@tonic-gate 					}
811*7c478bd9Sstevel@tonic-gate 				}
812*7c478bd9Sstevel@tonic-gate 			}
813*7c478bd9Sstevel@tonic-gate 		}
814*7c478bd9Sstevel@tonic-gate 		if (0 != result) {
815*7c478bd9Sstevel@tonic-gate 			if (map_hdr->default_error < 0) {
816*7c478bd9Sstevel@tonic-gate 				p = q;
817*7c478bd9Sstevel@tonic-gate 			} else if (0 == map_hdr->default_error) {
818*7c478bd9Sstevel@tonic-gate 				p = map_of + map_hdr->hash_of_size;
819*7c478bd9Sstevel@tonic-gate 			} else if (0 < map_hdr->default_error) {
820*7c478bd9Sstevel@tonic-gate 				TRACE_MESSAGE('G',
821*7c478bd9Sstevel@tonic-gate 				("(h=%d): NO PAIR\n",
822*7c478bd9Sstevel@tonic-gate 				hash_value));
823*7c478bd9Sstevel@tonic-gate 				errno = EILSEQ;
824*7c478bd9Sstevel@tonic-gate 				TRACE_MESSAGE('e',
825*7c478bd9Sstevel@tonic-gate 				("map_h_l:error=%d\n", errno));
826*7c478bd9Sstevel@tonic-gate 				return ((size_t)(-1));
827*7c478bd9Sstevel@tonic-gate 			}
828*7c478bd9Sstevel@tonic-gate 		} else {
829*7c478bd9Sstevel@tonic-gate 			if (0 != (*p)) {
830*7c478bd9Sstevel@tonic-gate 				errno = EILSEQ;
831*7c478bd9Sstevel@tonic-gate 				TRACE_MESSAGE('G',
832*7c478bd9Sstevel@tonic-gate 				("	      : error pair\n"));
833*7c478bd9Sstevel@tonic-gate 				TRACE_MESSAGE('e', ("map_l_f:error\n",
834*7c478bd9Sstevel@tonic-gate 				errno));
835*7c478bd9Sstevel@tonic-gate 				return ((size_t)(-1));
836*7c478bd9Sstevel@tonic-gate 			}
837*7c478bd9Sstevel@tonic-gate 			p++;
838*7c478bd9Sstevel@tonic-gate 		}
839*7c478bd9Sstevel@tonic-gate 
840*7c478bd9Sstevel@tonic-gate 		if (*outbytesleft < result_len) {
841*7c478bd9Sstevel@tonic-gate 			errno = E2BIG;
842*7c478bd9Sstevel@tonic-gate 			TRACE_MESSAGE('e', ("map_h_l:error=%d\n", errno));
843*7c478bd9Sstevel@tonic-gate 			return ((size_t)(-1));
844*7c478bd9Sstevel@tonic-gate 		}
845*7c478bd9Sstevel@tonic-gate 		DISCARD(source_len);
846*7c478bd9Sstevel@tonic-gate 
847*7c478bd9Sstevel@tonic-gate 		for (i = 0; i < result_len; i++) {
848*7c478bd9Sstevel@tonic-gate 			PUT(*(p + i));
849*7c478bd9Sstevel@tonic-gate 		}
850*7c478bd9Sstevel@tonic-gate 	} while ((0 < *inbytesleft) && (0 == once));
851*7c478bd9Sstevel@tonic-gate 
852*7c478bd9Sstevel@tonic-gate 	return ((size_t)(0));
853*7c478bd9Sstevel@tonic-gate }
854*7c478bd9Sstevel@tonic-gate 
855*7c478bd9Sstevel@tonic-gate 
856*7c478bd9Sstevel@tonic-gate /*
857*7c478bd9Sstevel@tonic-gate  * map-dense_encoding-lookup
858*7c478bd9Sstevel@tonic-gate  */
859*7c478bd9Sstevel@tonic-gate static size_t
860*7c478bd9Sstevel@tonic-gate map_d_e_l(
861*7c478bd9Sstevel@tonic-gate 	itm_tbl_hdr_t		*tbl_hdr,
862*7c478bd9Sstevel@tonic-gate 	const unsigned char	**inbuf,
863*7c478bd9Sstevel@tonic-gate 	size_t			*inbytesleft,
864*7c478bd9Sstevel@tonic-gate 	unsigned char		**outbuf,
865*7c478bd9Sstevel@tonic-gate 	size_t			*outbytesleft,
866*7c478bd9Sstevel@tonic-gate 	long			once)
867*7c478bd9Sstevel@tonic-gate {
868*7c478bd9Sstevel@tonic-gate 	itm_map_dense_enc_hdr_t	*map_hdr;
869*7c478bd9Sstevel@tonic-gate 	long			i;
870*7c478bd9Sstevel@tonic-gate 	itm_num_t		j;
871*7c478bd9Sstevel@tonic-gate 	const unsigned char	*p;
872*7c478bd9Sstevel@tonic-gate 	unsigned char		*map_ptr;
873*7c478bd9Sstevel@tonic-gate 	unsigned char		*map_error;
874*7c478bd9Sstevel@tonic-gate 	unsigned char		*byte_seq_min;
875*7c478bd9Sstevel@tonic-gate 	unsigned char		*byte_seq_max;
876*7c478bd9Sstevel@tonic-gate 
877*7c478bd9Sstevel@tonic-gate 	TRACE_MESSAGE('i', ("map_d_e_l\n"));
878*7c478bd9Sstevel@tonic-gate 
879*7c478bd9Sstevel@tonic-gate 	map_hdr = (itm_map_dense_enc_hdr_t *)(tbl_hdr + 1);
880*7c478bd9Sstevel@tonic-gate 	map_ptr = ((unsigned char *)(map_hdr + 1) +
881*7c478bd9Sstevel@tonic-gate 			map_hdr->source_len + map_hdr->source_len);
882*7c478bd9Sstevel@tonic-gate 	map_error = (map_ptr + (tbl_hdr->number * map_hdr->result_len));
883*7c478bd9Sstevel@tonic-gate 	if (0 == map_hdr->default_error) {
884*7c478bd9Sstevel@tonic-gate 		map_error = (void *)(map_error + map_hdr->result_len);
885*7c478bd9Sstevel@tonic-gate 	}
886*7c478bd9Sstevel@tonic-gate 	byte_seq_min = (unsigned char *)(map_hdr + 1);
887*7c478bd9Sstevel@tonic-gate 	byte_seq_max = byte_seq_min + map_hdr->source_len;
888*7c478bd9Sstevel@tonic-gate 
889*7c478bd9Sstevel@tonic-gate 	do {
890*7c478bd9Sstevel@tonic-gate 		if (*inbytesleft < map_hdr->source_len) {
891*7c478bd9Sstevel@tonic-gate 			errno = EINVAL;
892*7c478bd9Sstevel@tonic-gate 			TRACE_MESSAGE('e', ("map_d_e_l:error=%d\n", errno));
893*7c478bd9Sstevel@tonic-gate 			return ((size_t)(-1));
894*7c478bd9Sstevel@tonic-gate 		}
895*7c478bd9Sstevel@tonic-gate 
896*7c478bd9Sstevel@tonic-gate 		j = hash_dense_encoding(*inbuf, map_hdr->source_len,
897*7c478bd9Sstevel@tonic-gate 					byte_seq_min, byte_seq_max);
898*7c478bd9Sstevel@tonic-gate 
899*7c478bd9Sstevel@tonic-gate 		if (((j < 0) || (tbl_hdr->number < j)) &&
900*7c478bd9Sstevel@tonic-gate 		    (0 < map_hdr->default_error)) {
901*7c478bd9Sstevel@tonic-gate 			errno = EILSEQ;
902*7c478bd9Sstevel@tonic-gate 			TRACE_MESSAGE('e', ("map_d_e_l:error=%d\n", errno));
903*7c478bd9Sstevel@tonic-gate 			return ((size_t)(-1));
904*7c478bd9Sstevel@tonic-gate 		}
905*7c478bd9Sstevel@tonic-gate 
906*7c478bd9Sstevel@tonic-gate 		if (*outbytesleft < map_hdr->result_len) {
907*7c478bd9Sstevel@tonic-gate 			errno = E2BIG;
908*7c478bd9Sstevel@tonic-gate 			TRACE_MESSAGE('e', ("map_d_e_l:error=%d\n", errno));
909*7c478bd9Sstevel@tonic-gate 			return ((size_t)(-1));
910*7c478bd9Sstevel@tonic-gate 		}
911*7c478bd9Sstevel@tonic-gate 
912*7c478bd9Sstevel@tonic-gate 		if ((j < 0) || (tbl_hdr->number < j)) {
913*7c478bd9Sstevel@tonic-gate 			if (0 == map_hdr->default_error) {
914*7c478bd9Sstevel@tonic-gate 				p = (map_ptr +
915*7c478bd9Sstevel@tonic-gate 				(tbl_hdr->number * map_hdr->result_len));
916*7c478bd9Sstevel@tonic-gate 				for (i = 0; i < map_hdr->result_len; i++) {
917*7c478bd9Sstevel@tonic-gate 					PUT(*(p + i));
918*7c478bd9Sstevel@tonic-gate 				}
919*7c478bd9Sstevel@tonic-gate 			} else {
920*7c478bd9Sstevel@tonic-gate 				p = *inbuf;
921*7c478bd9Sstevel@tonic-gate 				for (i = 0; i < map_hdr->source_len; i++) {
922*7c478bd9Sstevel@tonic-gate 					PUT(*(p + i));
923*7c478bd9Sstevel@tonic-gate 				}
924*7c478bd9Sstevel@tonic-gate 			}
925*7c478bd9Sstevel@tonic-gate 		} else {
926*7c478bd9Sstevel@tonic-gate 			if ((1 == map_hdr->default_error) ||
927*7c478bd9Sstevel@tonic-gate 			    (0 < map_hdr->error_num)) {
928*7c478bd9Sstevel@tonic-gate 				if (0 != *(map_error + j)) {
929*7c478bd9Sstevel@tonic-gate 					errno = EILSEQ;
930*7c478bd9Sstevel@tonic-gate 					TRACE_MESSAGE('e',
931*7c478bd9Sstevel@tonic-gate 					("map_d_e_l:error=%d\n", errno));
932*7c478bd9Sstevel@tonic-gate 					return ((size_t)(-1));
933*7c478bd9Sstevel@tonic-gate 				}
934*7c478bd9Sstevel@tonic-gate 			}
935*7c478bd9Sstevel@tonic-gate 			p = (map_ptr + (map_hdr->result_len * j));
936*7c478bd9Sstevel@tonic-gate 			for (i = 0; i < map_hdr->result_len; i++) {
937*7c478bd9Sstevel@tonic-gate 				PUT(*(p + i));
938*7c478bd9Sstevel@tonic-gate 			}
939*7c478bd9Sstevel@tonic-gate 		}
940*7c478bd9Sstevel@tonic-gate 		DISCARD(map_hdr->source_len);
941*7c478bd9Sstevel@tonic-gate 	} while ((0 < *inbytesleft) && (0 == once));
942*7c478bd9Sstevel@tonic-gate 
943*7c478bd9Sstevel@tonic-gate 	return ((size_t)(0));
944*7c478bd9Sstevel@tonic-gate }
945*7c478bd9Sstevel@tonic-gate 
946*7c478bd9Sstevel@tonic-gate 
947*7c478bd9Sstevel@tonic-gate 
948*7c478bd9Sstevel@tonic-gate /*
949*7c478bd9Sstevel@tonic-gate  * Evaluate condition table
950*7c478bd9Sstevel@tonic-gate  *
951*7c478bd9Sstevel@tonic-gate  */
952*7c478bd9Sstevel@tonic-gate static size_t
953*7c478bd9Sstevel@tonic-gate eval_cond_tbl(
954*7c478bd9Sstevel@tonic-gate 	icv_state_t		*ist,
955*7c478bd9Sstevel@tonic-gate 	itm_place_t		cond_place,
956*7c478bd9Sstevel@tonic-gate 	const unsigned char	**inbuf,
957*7c478bd9Sstevel@tonic-gate 	size_t			*inbytesleft,
958*7c478bd9Sstevel@tonic-gate 	size_t			outbytesleft,
959*7c478bd9Sstevel@tonic-gate 	itm_direc_t		*direc
960*7c478bd9Sstevel@tonic-gate )
961*7c478bd9Sstevel@tonic-gate {
962*7c478bd9Sstevel@tonic-gate 	itm_tbl_hdr_t		*cond_hdr;
963*7c478bd9Sstevel@tonic-gate 	itm_cond_t		*cond;
964*7c478bd9Sstevel@tonic-gate 	long			i;
965*7c478bd9Sstevel@tonic-gate 	long			j;
966*7c478bd9Sstevel@tonic-gate 	long			k;
967*7c478bd9Sstevel@tonic-gate 	size_t			retval;
968*7c478bd9Sstevel@tonic-gate 	itm_tbl_hdr_t		*rth;
969*7c478bd9Sstevel@tonic-gate 	itm_range_hdr_t		*rtsh;
970*7c478bd9Sstevel@tonic-gate 	unsigned char		*p;
971*7c478bd9Sstevel@tonic-gate 	itm_tbl_hdr_t		*eth;
972*7c478bd9Sstevel@tonic-gate 	itm_escapeseq_hdr_t	*eh;
973*7c478bd9Sstevel@tonic-gate 	itm_data_t		*d;
974*7c478bd9Sstevel@tonic-gate 	const unsigned char	*ip;
975*7c478bd9Sstevel@tonic-gate 	size_t			ileft;
976*7c478bd9Sstevel@tonic-gate 
977*7c478bd9Sstevel@tonic-gate 	retval = 0;
978*7c478bd9Sstevel@tonic-gate 	ip =	*inbuf;
979*7c478bd9Sstevel@tonic-gate 	ileft = *inbytesleft;
980*7c478bd9Sstevel@tonic-gate 	cond_hdr = ADDR(cond_place);
981*7c478bd9Sstevel@tonic-gate 	cond = (itm_cond_t *)(cond_hdr + 1);
982*7c478bd9Sstevel@tonic-gate 	for (i = 0; i < cond_hdr->number; i++, cond++) {
983*7c478bd9Sstevel@tonic-gate 		switch (cond->type) {
984*7c478bd9Sstevel@tonic-gate 		case ITM_COND_BETWEEN:
985*7c478bd9Sstevel@tonic-gate 			rth = ADDR(cond->operand.place);
986*7c478bd9Sstevel@tonic-gate 			rtsh = (itm_range_hdr_t *)(rth + 1);
987*7c478bd9Sstevel@tonic-gate 			if (ileft < rtsh->len) {
988*7c478bd9Sstevel@tonic-gate 				errno = EINVAL;
989*7c478bd9Sstevel@tonic-gate 				TRACE_MESSAGE('e',
990*7c478bd9Sstevel@tonic-gate 				("eval_cond_tbl:error=%d\n", errno));
991*7c478bd9Sstevel@tonic-gate 				retval = ((size_t)(-1));
992*7c478bd9Sstevel@tonic-gate 				goto eval_cond_return;
993*7c478bd9Sstevel@tonic-gate 			}
994*7c478bd9Sstevel@tonic-gate 			p = (unsigned char *)(rtsh + 1);
995*7c478bd9Sstevel@tonic-gate 			retval = 0;
996*7c478bd9Sstevel@tonic-gate 			for (j = 0; j < rth->number;
997*7c478bd9Sstevel@tonic-gate 			    j++,  p = (void *)(p + (2 * rtsh->len))) {
998*7c478bd9Sstevel@tonic-gate 				retval = 1;
999*7c478bd9Sstevel@tonic-gate 				for (k = 0; k < rtsh->len; k++) {
1000*7c478bd9Sstevel@tonic-gate 					if ((*(ip + k) < *(p + k)) ||
1001*7c478bd9Sstevel@tonic-gate 					    (*(p + rtsh->len + k) <
1002*7c478bd9Sstevel@tonic-gate 					    *(ip + k))) {
1003*7c478bd9Sstevel@tonic-gate 						retval = 0;
1004*7c478bd9Sstevel@tonic-gate 						break;
1005*7c478bd9Sstevel@tonic-gate 					}
1006*7c478bd9Sstevel@tonic-gate 				}
1007*7c478bd9Sstevel@tonic-gate 				if (1 == retval) {
1008*7c478bd9Sstevel@tonic-gate 					break;
1009*7c478bd9Sstevel@tonic-gate 				}
1010*7c478bd9Sstevel@tonic-gate 			}
1011*7c478bd9Sstevel@tonic-gate 			if (0 == retval) {
1012*7c478bd9Sstevel@tonic-gate 				TRACE_MESSAGE('b',
1013*7c478bd9Sstevel@tonic-gate 				("out of between (%p) len= rtsh=%ld\n",
1014*7c478bd9Sstevel@tonic-gate 				*ip, rtsh->len));
1015*7c478bd9Sstevel@tonic-gate 				goto eval_cond_return;
1016*7c478bd9Sstevel@tonic-gate 			}
1017*7c478bd9Sstevel@tonic-gate 			break; /* continue */
1018*7c478bd9Sstevel@tonic-gate 		case ITM_COND_ESCAPESEQ:
1019*7c478bd9Sstevel@tonic-gate 			/*
1020*7c478bd9Sstevel@tonic-gate 			 * if escape sequence occur,
1021*7c478bd9Sstevel@tonic-gate 			 * change ist->default_action and return 2.
1022*7c478bd9Sstevel@tonic-gate 			 * never return 1.
1023*7c478bd9Sstevel@tonic-gate 			 */
1024*7c478bd9Sstevel@tonic-gate 			retval = 0;
1025*7c478bd9Sstevel@tonic-gate 			eth = ADDR(cond->operand.place);
1026*7c478bd9Sstevel@tonic-gate 			eh = (itm_escapeseq_hdr_t *)(eth + 1);
1027*7c478bd9Sstevel@tonic-gate 			if (NULL == ist->default_action.itm_ptr) {
1028*7c478bd9Sstevel@tonic-gate 				ist->default_action = direc->action;
1029*7c478bd9Sstevel@tonic-gate 				TRACE_MESSAGE('E',
1030*7c478bd9Sstevel@tonic-gate 				("escape seq (default action=%6p, "
1031*7c478bd9Sstevel@tonic-gate 				"type=%ld) set\n",
1032*7c478bd9Sstevel@tonic-gate 				direc->action.itm_ptr,
1033*7c478bd9Sstevel@tonic-gate 				((itm_tbl_hdr_t *)(ADDR(direc->action)))
1034*7c478bd9Sstevel@tonic-gate 				->type));
1035*7c478bd9Sstevel@tonic-gate 			}
1036*7c478bd9Sstevel@tonic-gate 			retval = 0;
1037*7c478bd9Sstevel@tonic-gate 			if (*inbytesleft < eh->len_min) {
1038*7c478bd9Sstevel@tonic-gate 				break;
1039*7c478bd9Sstevel@tonic-gate 			}
1040*7c478bd9Sstevel@tonic-gate 			for (j = 0, d = (itm_data_t *)(eh + 1);
1041*7c478bd9Sstevel@tonic-gate 			    j < eth->number;
1042*7c478bd9Sstevel@tonic-gate 			    j++, d++) {
1043*7c478bd9Sstevel@tonic-gate 				if (*inbytesleft < d->size) {
1044*7c478bd9Sstevel@tonic-gate 					continue;
1045*7c478bd9Sstevel@tonic-gate 				}
1046*7c478bd9Sstevel@tonic-gate 				if (0 == memcmp(*inbuf, DADDR(d), d->size)) {
1047*7c478bd9Sstevel@tonic-gate 					TRACE_MESSAGE('E',
1048*7c478bd9Sstevel@tonic-gate 					("escape seq: discard=%ld chars\n",
1049*7c478bd9Sstevel@tonic-gate 					d->size));
1050*7c478bd9Sstevel@tonic-gate 					TRACE_MESSAGE('E', (
1051*7c478bd9Sstevel@tonic-gate 					"escape seq (default action=%6p, "
1052*7c478bd9Sstevel@tonic-gate 					"type=%ld) set\n",
1053*7c478bd9Sstevel@tonic-gate 					direc->action.itm_ptr,
1054*7c478bd9Sstevel@tonic-gate 					((itm_tbl_hdr_t *)
1055*7c478bd9Sstevel@tonic-gate 					(ADDR(direc->action)))->type));
1056*7c478bd9Sstevel@tonic-gate 					ist->default_action = direc->action;
1057*7c478bd9Sstevel@tonic-gate 					DISCARD(d->size);
1058*7c478bd9Sstevel@tonic-gate 					retval = 2;
1059*7c478bd9Sstevel@tonic-gate 					goto eval_cond_return;
1060*7c478bd9Sstevel@tonic-gate 				}
1061*7c478bd9Sstevel@tonic-gate 			}
1062*7c478bd9Sstevel@tonic-gate 			if (0 == retval) {
1063*7c478bd9Sstevel@tonic-gate 				goto eval_cond_return;
1064*7c478bd9Sstevel@tonic-gate 			}
1065*7c478bd9Sstevel@tonic-gate 			break; /* continue */
1066*7c478bd9Sstevel@tonic-gate 		case ITM_COND_EXPR:
1067*7c478bd9Sstevel@tonic-gate 			retval = eval_expr(ist, cond->operand.place,
1068*7c478bd9Sstevel@tonic-gate 					*inbytesleft, ip, outbytesleft);
1069*7c478bd9Sstevel@tonic-gate 			if (0 == retval) {
1070*7c478bd9Sstevel@tonic-gate 				goto eval_cond_return;
1071*7c478bd9Sstevel@tonic-gate 			} else {
1072*7c478bd9Sstevel@tonic-gate 				retval = 1;
1073*7c478bd9Sstevel@tonic-gate 			}
1074*7c478bd9Sstevel@tonic-gate 			break; /* continue */
1075*7c478bd9Sstevel@tonic-gate 		default:
1076*7c478bd9Sstevel@tonic-gate 			TRACE_MESSAGE('e', ("eval_cond_tbl:illegal cond=%d\n",
1077*7c478bd9Sstevel@tonic-gate 			cond->type));
1078*7c478bd9Sstevel@tonic-gate 			retval = (size_t)-1;
1079*7c478bd9Sstevel@tonic-gate 			goto eval_cond_return;
1080*7c478bd9Sstevel@tonic-gate 		}
1081*7c478bd9Sstevel@tonic-gate 	}
1082*7c478bd9Sstevel@tonic-gate 
1083*7c478bd9Sstevel@tonic-gate eval_cond_return:
1084*7c478bd9Sstevel@tonic-gate 	return (retval);
1085*7c478bd9Sstevel@tonic-gate }
1086*7c478bd9Sstevel@tonic-gate 
1087*7c478bd9Sstevel@tonic-gate /*
1088*7c478bd9Sstevel@tonic-gate  * Evaluate operation table
1089*7c478bd9Sstevel@tonic-gate  *
1090*7c478bd9Sstevel@tonic-gate  */
1091*7c478bd9Sstevel@tonic-gate static size_t
1092*7c478bd9Sstevel@tonic-gate eval_op_tbl(
1093*7c478bd9Sstevel@tonic-gate 	icv_state_t	*ist,
1094*7c478bd9Sstevel@tonic-gate 	itm_place_t	op_tbl_place,
1095*7c478bd9Sstevel@tonic-gate 	const unsigned char	**inbuf,
1096*7c478bd9Sstevel@tonic-gate 	size_t		*inbytesleft,
1097*7c478bd9Sstevel@tonic-gate 	unsigned char	**outbuf,
1098*7c478bd9Sstevel@tonic-gate 	size_t		*outbytesleft)
1099*7c478bd9Sstevel@tonic-gate {
1100*7c478bd9Sstevel@tonic-gate 	itm_tbl_hdr_t	*op_hdr;
1101*7c478bd9Sstevel@tonic-gate 	itm_op_t	*operation;
1102*7c478bd9Sstevel@tonic-gate 	itm_place2_t	op_place;
1103*7c478bd9Sstevel@tonic-gate 	size_t		retval;
1104*7c478bd9Sstevel@tonic-gate 	long		i;
1105*7c478bd9Sstevel@tonic-gate 
1106*7c478bd9Sstevel@tonic-gate 	retval = 0;
1107*7c478bd9Sstevel@tonic-gate 
1108*7c478bd9Sstevel@tonic-gate #if defined(OP_DEPTH_MAX)
1109*7c478bd9Sstevel@tonic-gate 	if (OP_DEPTH_MAX <= ist->op_depth) {
1110*7c478bd9Sstevel@tonic-gate 		errno = ELIBBAD;
1111*7c478bd9Sstevel@tonic-gate 		TRACE_MESSAGE('e', ("eval_op_tbl:error=%d\n", errno));
1112*7c478bd9Sstevel@tonic-gate 		return	(RETVALERR);
1113*7c478bd9Sstevel@tonic-gate 	}
1114*7c478bd9Sstevel@tonic-gate 	ist->op_depth += 1;
1115*7c478bd9Sstevel@tonic-gate #endif /* OP_DEPTH_MAX */
1116*7c478bd9Sstevel@tonic-gate 
1117*7c478bd9Sstevel@tonic-gate 	op_hdr = ADDR(op_tbl_place);
1118*7c478bd9Sstevel@tonic-gate 	operation = (itm_op_t *)(op_hdr + 1);
1119*7c478bd9Sstevel@tonic-gate 
1120*7c478bd9Sstevel@tonic-gate 	op_place = op_tbl_place.itm_ptr + (sizeof (itm_tbl_hdr_t));
1121*7c478bd9Sstevel@tonic-gate 	for (i = 0; i < op_hdr->number; i++, operation++,
1122*7c478bd9Sstevel@tonic-gate 	    op_place += (sizeof (itm_op_t))) {
1123*7c478bd9Sstevel@tonic-gate 		TRACE_MESSAGE('O', ("eval_op_tbl: %ld %p\n", i, op_place));
1124*7c478bd9Sstevel@tonic-gate 		retval = eval_op(ist, op_place,
1125*7c478bd9Sstevel@tonic-gate 				inbuf, inbytesleft,
1126*7c478bd9Sstevel@tonic-gate 				outbuf, outbytesleft);
1127*7c478bd9Sstevel@tonic-gate 		if (((long)(retval)) < 0) {
1128*7c478bd9Sstevel@tonic-gate #if defined(OP_DEPTH_MAX)
1129*7c478bd9Sstevel@tonic-gate 			ist->op_depth -= 1;
1130*7c478bd9Sstevel@tonic-gate #endif /* OP_DEPTH_MAX */
1131*7c478bd9Sstevel@tonic-gate 			switch (retval) {
1132*7c478bd9Sstevel@tonic-gate 			case RETVALERR:
1133*7c478bd9Sstevel@tonic-gate 				return	(retval);
1134*7c478bd9Sstevel@tonic-gate 			case RETVALRET:
1135*7c478bd9Sstevel@tonic-gate 				if (0 == op_hdr->name.itm_ptr) {
1136*7c478bd9Sstevel@tonic-gate 					return	(RETVALRET);
1137*7c478bd9Sstevel@tonic-gate 				} else {
1138*7c478bd9Sstevel@tonic-gate 					return (0);
1139*7c478bd9Sstevel@tonic-gate 				}
1140*7c478bd9Sstevel@tonic-gate 			}
1141*7c478bd9Sstevel@tonic-gate 		}
1142*7c478bd9Sstevel@tonic-gate 	}
1143*7c478bd9Sstevel@tonic-gate #if defined(OP_DEPTH_MAX)
1144*7c478bd9Sstevel@tonic-gate 	ist->op_depth -= 1;
1145*7c478bd9Sstevel@tonic-gate #endif /* OP_DEPTH_MAX */
1146*7c478bd9Sstevel@tonic-gate 	return	(retval);
1147*7c478bd9Sstevel@tonic-gate }
1148*7c478bd9Sstevel@tonic-gate 
1149*7c478bd9Sstevel@tonic-gate 
1150*7c478bd9Sstevel@tonic-gate /*
1151*7c478bd9Sstevel@tonic-gate  * Evaluate single operation
1152*7c478bd9Sstevel@tonic-gate  *
1153*7c478bd9Sstevel@tonic-gate  */
1154*7c478bd9Sstevel@tonic-gate static size_t
1155*7c478bd9Sstevel@tonic-gate eval_op(
1156*7c478bd9Sstevel@tonic-gate 	icv_state_t		*ist,
1157*7c478bd9Sstevel@tonic-gate 	itm_place2_t		op_place,
1158*7c478bd9Sstevel@tonic-gate 	const unsigned char	**inbuf,
1159*7c478bd9Sstevel@tonic-gate 	size_t			*inbytesleft,
1160*7c478bd9Sstevel@tonic-gate 	unsigned char		**outbuf,
1161*7c478bd9Sstevel@tonic-gate 	size_t			*outbytesleft)
1162*7c478bd9Sstevel@tonic-gate {
1163*7c478bd9Sstevel@tonic-gate 	size_t			retval;
1164*7c478bd9Sstevel@tonic-gate 	itm_num_t		num;
1165*7c478bd9Sstevel@tonic-gate 	itm_op_t		*operation;
1166*7c478bd9Sstevel@tonic-gate 	itm_expr_t		*expr;
1167*7c478bd9Sstevel@tonic-gate 	itm_num_t		c;
1168*7c478bd9Sstevel@tonic-gate 	itm_num_t		i;
1169*7c478bd9Sstevel@tonic-gate 	itm_size_t		z;
1170*7c478bd9Sstevel@tonic-gate 	unsigned char		*p;
1171*7c478bd9Sstevel@tonic-gate 	itm_expr_t		*expr0;
1172*7c478bd9Sstevel@tonic-gate 
1173*7c478bd9Sstevel@tonic-gate #define	EVAL_EXPR(n)							\
1174*7c478bd9Sstevel@tonic-gate 	(expr0 = ADDR(operation->data.operand[(n)]),			\
1175*7c478bd9Sstevel@tonic-gate 	(itm_num_t)((expr0->type == ITM_EXPR_INT) ?		       	\
1176*7c478bd9Sstevel@tonic-gate 		expr0->data.itm_exnum :					\
1177*7c478bd9Sstevel@tonic-gate 		((expr0->type == ITM_EXPR_REG) ?			\
1178*7c478bd9Sstevel@tonic-gate 		REG(expr0->data.itm_exnum) :				\
1179*7c478bd9Sstevel@tonic-gate 		((expr0->type == ITM_EXPR_IN_VECTOR_D) ?		\
1180*7c478bd9Sstevel@tonic-gate 		((expr0->data.itm_exnum < 0) ?				\
1181*7c478bd9Sstevel@tonic-gate 		(((-1) == expr0->data.itm_exnum) ? *inbytesleft : 0) :	\
1182*7c478bd9Sstevel@tonic-gate 		((expr0->data.itm_exnum < *inbytesleft) ?		\
1183*7c478bd9Sstevel@tonic-gate 		(*(uchar_t *)(*inbuf + expr0->data.itm_exnum)) : 0)):	\
1184*7c478bd9Sstevel@tonic-gate 		eval_expr(ist, operation->data.operand[(n)],		\
1185*7c478bd9Sstevel@tonic-gate 		*inbytesleft, *inbuf, *outbytesleft)))))
1186*7c478bd9Sstevel@tonic-gate 
1187*7c478bd9Sstevel@tonic-gate 	retval = 0;
1188*7c478bd9Sstevel@tonic-gate 
1189*7c478bd9Sstevel@tonic-gate 	operation = (itm_op_t *)ADDR2(op_place);
1190*7c478bd9Sstevel@tonic-gate 
1191*7c478bd9Sstevel@tonic-gate 	switch (operation->type) {
1192*7c478bd9Sstevel@tonic-gate 	case ITM_OP_EXPR:
1193*7c478bd9Sstevel@tonic-gate 		num = eval_expr(ist, operation->data.operand[0],
1194*7c478bd9Sstevel@tonic-gate 				*inbytesleft, *inbuf, *outbytesleft);
1195*7c478bd9Sstevel@tonic-gate 		TRACE_MESSAGE('o', ("ITM_OP_EXPR: %ld\n", retval));
1196*7c478bd9Sstevel@tonic-gate 		break;
1197*7c478bd9Sstevel@tonic-gate 	case ITM_OP_ERROR:
1198*7c478bd9Sstevel@tonic-gate 		num = eval_expr(ist, operation->data.operand[0],
1199*7c478bd9Sstevel@tonic-gate 				*inbytesleft, *inbuf, *outbytesleft);
1200*7c478bd9Sstevel@tonic-gate 		errno = (int)num;
1201*7c478bd9Sstevel@tonic-gate 		TRACE_MESSAGE('o', ("ITM_OP_ERROR: %ld\n", num));
1202*7c478bd9Sstevel@tonic-gate 		retval = (size_t)(-1);
1203*7c478bd9Sstevel@tonic-gate 		break;
1204*7c478bd9Sstevel@tonic-gate 	case ITM_OP_ERROR_D:
1205*7c478bd9Sstevel@tonic-gate 		errno = (int)operation->data.itm_opnum;
1206*7c478bd9Sstevel@tonic-gate 		TRACE_MESSAGE('o', ("ITM_OP_ERROR_D: %d\n", errno));
1207*7c478bd9Sstevel@tonic-gate 		retval = (size_t)(-1);
1208*7c478bd9Sstevel@tonic-gate 		break;
1209*7c478bd9Sstevel@tonic-gate 	case ITM_OP_OUT:
1210*7c478bd9Sstevel@tonic-gate 		expr = ADDR(operation->data.operand[0]);
1211*7c478bd9Sstevel@tonic-gate 		if ((*outbytesleft) == 0) {
1212*7c478bd9Sstevel@tonic-gate 			errno = E2BIG;
1213*7c478bd9Sstevel@tonic-gate 			TRACE_MESSAGE('e', ("eval_op:error=%d\n", errno));
1214*7c478bd9Sstevel@tonic-gate 			return ((size_t)(-1));
1215*7c478bd9Sstevel@tonic-gate 		}
1216*7c478bd9Sstevel@tonic-gate 		c = eval_expr(ist, operation->data.operand[0],
1217*7c478bd9Sstevel@tonic-gate 				*inbytesleft, *inbuf, *outbytesleft);
1218*7c478bd9Sstevel@tonic-gate 		PUT((uchar_t)c);
1219*7c478bd9Sstevel@tonic-gate 		retval = *inbytesleft;
1220*7c478bd9Sstevel@tonic-gate 		TRACE_MESSAGE('o', ("ITM_OP_OUT: %ld %ld\n", c, *inbytesleft));
1221*7c478bd9Sstevel@tonic-gate 		break;
1222*7c478bd9Sstevel@tonic-gate 	case ITM_OP_OUT_D:
1223*7c478bd9Sstevel@tonic-gate 		expr = ADDR(operation->data.operand[0]);
1224*7c478bd9Sstevel@tonic-gate 		if ((*outbytesleft) == 0) {
1225*7c478bd9Sstevel@tonic-gate 			errno = E2BIG;
1226*7c478bd9Sstevel@tonic-gate 			TRACE_MESSAGE('e', ("eval_op:error=%d\n", errno));
1227*7c478bd9Sstevel@tonic-gate 			return ((size_t)(-1));
1228*7c478bd9Sstevel@tonic-gate 		}
1229*7c478bd9Sstevel@tonic-gate 		PUT(0xff & (expr->data.itm_exnum));
1230*7c478bd9Sstevel@tonic-gate 		break;
1231*7c478bd9Sstevel@tonic-gate 	case ITM_OP_OUT_S:
1232*7c478bd9Sstevel@tonic-gate 		expr = ADDR(operation->data.operand[0]);
1233*7c478bd9Sstevel@tonic-gate 		if ((*outbytesleft) == 0) {
1234*7c478bd9Sstevel@tonic-gate 			errno = E2BIG;
1235*7c478bd9Sstevel@tonic-gate 			TRACE_MESSAGE('e', ("eval_op:error=%d\n", errno));
1236*7c478bd9Sstevel@tonic-gate 			return ((size_t)(-1));
1237*7c478bd9Sstevel@tonic-gate 		}
1238*7c478bd9Sstevel@tonic-gate 		z = expr->data.value.size;
1239*7c478bd9Sstevel@tonic-gate 		if (*outbytesleft < z) {
1240*7c478bd9Sstevel@tonic-gate 			errno = E2BIG;
1241*7c478bd9Sstevel@tonic-gate 			TRACE_MESSAGE('e', ("eval_op:error=%d\n", errno));
1242*7c478bd9Sstevel@tonic-gate 			return ((size_t)(-1));
1243*7c478bd9Sstevel@tonic-gate 		}
1244*7c478bd9Sstevel@tonic-gate 		p = DADDR(&(expr->data.value));
1245*7c478bd9Sstevel@tonic-gate 		for (; 0 < z; --z, p++) {
1246*7c478bd9Sstevel@tonic-gate 			PUT(*p);
1247*7c478bd9Sstevel@tonic-gate 		}
1248*7c478bd9Sstevel@tonic-gate 		break;
1249*7c478bd9Sstevel@tonic-gate 	case ITM_OP_OUT_R:
1250*7c478bd9Sstevel@tonic-gate 		expr = ADDR(operation->data.operand[0]);
1251*7c478bd9Sstevel@tonic-gate 		if ((*outbytesleft) == 0) {
1252*7c478bd9Sstevel@tonic-gate 			errno = E2BIG;
1253*7c478bd9Sstevel@tonic-gate 			TRACE_MESSAGE('e', ("eval_op:error=%d\n", errno));
1254*7c478bd9Sstevel@tonic-gate 			return ((size_t)(-1));
1255*7c478bd9Sstevel@tonic-gate 		}
1256*7c478bd9Sstevel@tonic-gate 		c = REG(expr->data.itm_exnum);
1257*7c478bd9Sstevel@tonic-gate 		PUT((uchar_t)c);
1258*7c478bd9Sstevel@tonic-gate 		break;
1259*7c478bd9Sstevel@tonic-gate 	case ITM_OP_OUT_INVD:
1260*7c478bd9Sstevel@tonic-gate 		expr = ADDR(operation->data.operand[0]);
1261*7c478bd9Sstevel@tonic-gate 		if ((*outbytesleft) == 0) {
1262*7c478bd9Sstevel@tonic-gate 			errno = E2BIG;
1263*7c478bd9Sstevel@tonic-gate 			TRACE_MESSAGE('e', ("eval_op:error=%d\n", errno));
1264*7c478bd9Sstevel@tonic-gate 			return ((size_t)(-1));
1265*7c478bd9Sstevel@tonic-gate 		}
1266*7c478bd9Sstevel@tonic-gate 		z = (((0 <= expr->data.itm_exnum) &&
1267*7c478bd9Sstevel@tonic-gate 			(expr->data.itm_exnum < *inbytesleft)) ?
1268*7c478bd9Sstevel@tonic-gate 			(*((unsigned char *)(*inbuf + expr->data.itm_exnum))) :
1269*7c478bd9Sstevel@tonic-gate 			(((-1) == expr->data.itm_exnum) ? *inbytesleft : 0));
1270*7c478bd9Sstevel@tonic-gate 		PUT((uchar_t)z);
1271*7c478bd9Sstevel@tonic-gate 		break;
1272*7c478bd9Sstevel@tonic-gate 	case ITM_OP_DISCARD:
1273*7c478bd9Sstevel@tonic-gate #if defined(EVAL_EXPR)
1274*7c478bd9Sstevel@tonic-gate 		num = EVAL_EXPR(0);
1275*7c478bd9Sstevel@tonic-gate #else /* !defined(EVAL_EXPR) */
1276*7c478bd9Sstevel@tonic-gate 		num = eval_expr(ist, operation->data.operand[0],
1277*7c478bd9Sstevel@tonic-gate 				*inbytesleft, *inbuf, *outbytesleft);
1278*7c478bd9Sstevel@tonic-gate #endif /* defined(EVAL_EXPR) */
1279*7c478bd9Sstevel@tonic-gate 		TRACE_MESSAGE('o', ("ITM_OP_DISCARD: %ld\n", num));
1280*7c478bd9Sstevel@tonic-gate #if defined(DISCARD)
1281*7c478bd9Sstevel@tonic-gate 		DISCARD((num <= *inbytesleft) ? ((ulong_t)num) :
1282*7c478bd9Sstevel@tonic-gate 						*inbytesleft);
1283*7c478bd9Sstevel@tonic-gate #else /* defined(DISCARD) */
1284*7c478bd9Sstevel@tonic-gate 		for (num = ((num <= *inbytesleft) ? num : *inbytesleft);
1285*7c478bd9Sstevel@tonic-gate 		    0 < num; --num) {
1286*7c478bd9Sstevel@tonic-gate 			GET(c);
1287*7c478bd9Sstevel@tonic-gate 		}
1288*7c478bd9Sstevel@tonic-gate #endif /* defined(DISCARD) */
1289*7c478bd9Sstevel@tonic-gate 		break;
1290*7c478bd9Sstevel@tonic-gate 	case ITM_OP_DISCARD_D:
1291*7c478bd9Sstevel@tonic-gate 		num = operation->data.itm_opnum;
1292*7c478bd9Sstevel@tonic-gate 		TRACE_MESSAGE('o', ("ITM_OP_DISCARD_D: %ld\n", num));
1293*7c478bd9Sstevel@tonic-gate #if defined(DISCARD)
1294*7c478bd9Sstevel@tonic-gate 		DISCARD((num <= *inbytesleft) ? num : *inbytesleft);
1295*7c478bd9Sstevel@tonic-gate #else /* defined(DISCARD) */
1296*7c478bd9Sstevel@tonic-gate 		for (num = ((num <= *inbytesleft) ? num : *inbytesleft);
1297*7c478bd9Sstevel@tonic-gate 		    0 < num; --num) {
1298*7c478bd9Sstevel@tonic-gate 			GET(c);
1299*7c478bd9Sstevel@tonic-gate 		}
1300*7c478bd9Sstevel@tonic-gate #endif /* defined(DISCARD) */
1301*7c478bd9Sstevel@tonic-gate 		break;
1302*7c478bd9Sstevel@tonic-gate 	case ITM_OP_IF:
1303*7c478bd9Sstevel@tonic-gate 		c = eval_expr(ist, operation->data.operand[0],
1304*7c478bd9Sstevel@tonic-gate 				*inbytesleft, *inbuf, *outbytesleft);
1305*7c478bd9Sstevel@tonic-gate 		TRACE_MESSAGE('o', ("ITM_OP_IF: %ld\n", c));
1306*7c478bd9Sstevel@tonic-gate 		if (c) {
1307*7c478bd9Sstevel@tonic-gate 			retval = eval_op_tbl(ist,
1308*7c478bd9Sstevel@tonic-gate 					    operation->data.operand[1],
1309*7c478bd9Sstevel@tonic-gate 					    inbuf, inbytesleft,
1310*7c478bd9Sstevel@tonic-gate 					    outbuf, outbytesleft);
1311*7c478bd9Sstevel@tonic-gate 		}
1312*7c478bd9Sstevel@tonic-gate 		break;
1313*7c478bd9Sstevel@tonic-gate 	case ITM_OP_IF_ELSE:
1314*7c478bd9Sstevel@tonic-gate 		c = eval_expr(ist, operation->data.operand[0],
1315*7c478bd9Sstevel@tonic-gate 				*inbytesleft, *inbuf, *outbytesleft);
1316*7c478bd9Sstevel@tonic-gate 		TRACE_MESSAGE('o', ("ITM_OP_IF_ELSE: %ld\n", c));
1317*7c478bd9Sstevel@tonic-gate 		if (c) {
1318*7c478bd9Sstevel@tonic-gate 			retval = eval_op_tbl(ist,
1319*7c478bd9Sstevel@tonic-gate 						operation->data.operand[1],
1320*7c478bd9Sstevel@tonic-gate 						inbuf, inbytesleft,
1321*7c478bd9Sstevel@tonic-gate 						outbuf, outbytesleft);
1322*7c478bd9Sstevel@tonic-gate 		} else {
1323*7c478bd9Sstevel@tonic-gate 			retval = eval_op_tbl(ist,
1324*7c478bd9Sstevel@tonic-gate 						operation->data.operand[2],
1325*7c478bd9Sstevel@tonic-gate 						inbuf, inbytesleft,
1326*7c478bd9Sstevel@tonic-gate 						outbuf, outbytesleft);
1327*7c478bd9Sstevel@tonic-gate 		}
1328*7c478bd9Sstevel@tonic-gate 		break;
1329*7c478bd9Sstevel@tonic-gate 	case ITM_OP_DIRECTION:
1330*7c478bd9Sstevel@tonic-gate 		TRACE_MESSAGE('o', ("ITM_OP_DIRECTION: %p\n",
1331*7c478bd9Sstevel@tonic-gate 			operation->data.operand[0].itm_ptr));
1332*7c478bd9Sstevel@tonic-gate 		ist->direc = ADDR(operation->data.operand[0]);
1333*7c478bd9Sstevel@tonic-gate 		return ((size_t)(-2));
1334*7c478bd9Sstevel@tonic-gate 	case ITM_OP_MAP:
1335*7c478bd9Sstevel@tonic-gate 		TRACE_MESSAGE('o', ("ITM_OP_MAP: %p\n",
1336*7c478bd9Sstevel@tonic-gate 				operation->data.operand[0].itm_ptr));
1337*7c478bd9Sstevel@tonic-gate 		i = 0;
1338*7c478bd9Sstevel@tonic-gate 		if (0 != operation->data.operand[1].itm_ptr) {
1339*7c478bd9Sstevel@tonic-gate #if defined(EVAL_EXPR)
1340*7c478bd9Sstevel@tonic-gate 			i = EVAL_EXPR(1);
1341*7c478bd9Sstevel@tonic-gate #else /* !defined(EVAL_EXPR) */
1342*7c478bd9Sstevel@tonic-gate 			i = eval_expr(ist, operation->data.operand[1],
1343*7c478bd9Sstevel@tonic-gate 				*inbytesleft, *inbuf, *outbytesleft);
1344*7c478bd9Sstevel@tonic-gate #endif /* defined(EVAL_EXPR) */
1345*7c478bd9Sstevel@tonic-gate 			(*inbytesleft) -= i;
1346*7c478bd9Sstevel@tonic-gate 			(*inbuf) += i;
1347*7c478bd9Sstevel@tonic-gate 		}
1348*7c478bd9Sstevel@tonic-gate 
1349*7c478bd9Sstevel@tonic-gate 		retval = map_i_f(ADDR(operation->data.operand[0]),
1350*7c478bd9Sstevel@tonic-gate 				inbuf, inbytesleft,
1351*7c478bd9Sstevel@tonic-gate 				outbuf, outbytesleft, 1);
1352*7c478bd9Sstevel@tonic-gate 		if ((size_t)(-1) == retval) {
1353*7c478bd9Sstevel@tonic-gate 			(*outbytesleft) += i;
1354*7c478bd9Sstevel@tonic-gate 			(*outbuf) -= i;
1355*7c478bd9Sstevel@tonic-gate 		}
1356*7c478bd9Sstevel@tonic-gate 		break;
1357*7c478bd9Sstevel@tonic-gate 	case ITM_OP_OPERATION:
1358*7c478bd9Sstevel@tonic-gate 		TRACE_MESSAGE('o', ("ITM_OP_OPERATION: %p\n",
1359*7c478bd9Sstevel@tonic-gate 				operation->data.operand[0].itm_ptr));
1360*7c478bd9Sstevel@tonic-gate 		retval = eval_op_tbl(ist,
1361*7c478bd9Sstevel@tonic-gate 				operation->data.operand[0],
1362*7c478bd9Sstevel@tonic-gate 				inbuf, inbytesleft,
1363*7c478bd9Sstevel@tonic-gate 				outbuf, outbytesleft);
1364*7c478bd9Sstevel@tonic-gate 
1365*7c478bd9Sstevel@tonic-gate 		break;
1366*7c478bd9Sstevel@tonic-gate 	case ITM_OP_INIT:
1367*7c478bd9Sstevel@tonic-gate 		TRACE_MESSAGE('o', ("ITM_OP_INIT: %p\n",
1368*7c478bd9Sstevel@tonic-gate 				ist->itm_hdr->op_init_tbl));
1369*7c478bd9Sstevel@tonic-gate 		if (0 != ist->itm_hdr->op_init_tbl.itm_ptr) {
1370*7c478bd9Sstevel@tonic-gate 			retval = eval_op_tbl(ist,
1371*7c478bd9Sstevel@tonic-gate 						ist->itm_hdr->op_init_tbl,
1372*7c478bd9Sstevel@tonic-gate 						inbuf, inbytesleft,
1373*7c478bd9Sstevel@tonic-gate 						outbuf, outbytesleft);
1374*7c478bd9Sstevel@tonic-gate 		} else {
1375*7c478bd9Sstevel@tonic-gate 			op_init_default(ist);
1376*7c478bd9Sstevel@tonic-gate 			retval = (size_t)-2;
1377*7c478bd9Sstevel@tonic-gate 		}
1378*7c478bd9Sstevel@tonic-gate 		break;
1379*7c478bd9Sstevel@tonic-gate 	case ITM_OP_RESET:
1380*7c478bd9Sstevel@tonic-gate 		TRACE_MESSAGE('o', ("ITM_OP_RESET: %p\n",
1381*7c478bd9Sstevel@tonic-gate 				ist->itm_hdr->op_reset_tbl));
1382*7c478bd9Sstevel@tonic-gate 		if (0 != ist->itm_hdr->op_reset_tbl.itm_ptr) {
1383*7c478bd9Sstevel@tonic-gate 			retval = eval_op_tbl(ist,
1384*7c478bd9Sstevel@tonic-gate 						ist->itm_hdr->op_reset_tbl,
1385*7c478bd9Sstevel@tonic-gate 						inbuf, inbytesleft,
1386*7c478bd9Sstevel@tonic-gate 						outbuf, outbytesleft);
1387*7c478bd9Sstevel@tonic-gate 		} else {
1388*7c478bd9Sstevel@tonic-gate 			op_reset_default(ist);
1389*7c478bd9Sstevel@tonic-gate 			retval = (size_t)-2;
1390*7c478bd9Sstevel@tonic-gate 		}
1391*7c478bd9Sstevel@tonic-gate 		break;
1392*7c478bd9Sstevel@tonic-gate 	case ITM_OP_BREAK:
1393*7c478bd9Sstevel@tonic-gate 		TRACE_MESSAGE('o', ("ITM_OP_BREAK\n"));
1394*7c478bd9Sstevel@tonic-gate 		return	(RETVALBRK);
1395*7c478bd9Sstevel@tonic-gate 	case ITM_OP_RETURN:
1396*7c478bd9Sstevel@tonic-gate 		TRACE_MESSAGE('o', ("ITM_OP_RETURN\n"));
1397*7c478bd9Sstevel@tonic-gate 		return	(RETVALRET);
1398*7c478bd9Sstevel@tonic-gate 	case ITM_OP_PRINTCHR:
1399*7c478bd9Sstevel@tonic-gate 		c = eval_expr(ist, operation->data.operand[0],
1400*7c478bd9Sstevel@tonic-gate 				*inbytesleft, *inbuf, *outbytesleft);
1401*7c478bd9Sstevel@tonic-gate 		(void) fputc((uchar_t)c, stderr);
1402*7c478bd9Sstevel@tonic-gate 		TRACE_MESSAGE('o',
1403*7c478bd9Sstevel@tonic-gate 		("ITM_OP_PRINTCHR: %ld %ld\n", c, *inbytesleft));
1404*7c478bd9Sstevel@tonic-gate 		break;
1405*7c478bd9Sstevel@tonic-gate 	case ITM_OP_PRINTHD:
1406*7c478bd9Sstevel@tonic-gate 		c = eval_expr(ist, operation->data.operand[0],
1407*7c478bd9Sstevel@tonic-gate 				 *inbytesleft, *inbuf, *outbytesleft);
1408*7c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr, "%lx", c);
1409*7c478bd9Sstevel@tonic-gate 		TRACE_MESSAGE('o',
1410*7c478bd9Sstevel@tonic-gate 		("ITM_OP_PRINTHD: %ld %ld\n", c, *inbytesleft));
1411*7c478bd9Sstevel@tonic-gate 		break;
1412*7c478bd9Sstevel@tonic-gate 	case ITM_OP_PRINTINT:
1413*7c478bd9Sstevel@tonic-gate 		c = eval_expr(ist, operation->data.operand[0],
1414*7c478bd9Sstevel@tonic-gate 				*inbytesleft, *inbuf, *outbytesleft);
1415*7c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr, "%ld", c);
1416*7c478bd9Sstevel@tonic-gate 		TRACE_MESSAGE('o',
1417*7c478bd9Sstevel@tonic-gate 		("ITM_OP_PRINTINT: %ld %ld\n", c, *inbytesleft));
1418*7c478bd9Sstevel@tonic-gate 		break;
1419*7c478bd9Sstevel@tonic-gate 	default: /* never */
1420*7c478bd9Sstevel@tonic-gate 		errno = ELIBBAD;
1421*7c478bd9Sstevel@tonic-gate 		TRACE_MESSAGE('e', ("eval_op:error=%d\n", errno));
1422*7c478bd9Sstevel@tonic-gate 		return (size_t)(-1);
1423*7c478bd9Sstevel@tonic-gate 	}
1424*7c478bd9Sstevel@tonic-gate 	return	(retval);
1425*7c478bd9Sstevel@tonic-gate 
1426*7c478bd9Sstevel@tonic-gate #undef EVAL_EXPR
1427*7c478bd9Sstevel@tonic-gate }
1428*7c478bd9Sstevel@tonic-gate 
1429*7c478bd9Sstevel@tonic-gate 
1430*7c478bd9Sstevel@tonic-gate /*
1431*7c478bd9Sstevel@tonic-gate  * Evaluate expression
1432*7c478bd9Sstevel@tonic-gate  */
1433*7c478bd9Sstevel@tonic-gate static itm_num_t
1434*7c478bd9Sstevel@tonic-gate eval_expr(
1435*7c478bd9Sstevel@tonic-gate 	icv_state_t		*ist,
1436*7c478bd9Sstevel@tonic-gate 	itm_place_t		expr_place,
1437*7c478bd9Sstevel@tonic-gate 	size_t			inbytesleft,
1438*7c478bd9Sstevel@tonic-gate 	const unsigned char	*inbuf,
1439*7c478bd9Sstevel@tonic-gate 	size_t			outbytesleft)
1440*7c478bd9Sstevel@tonic-gate {
1441*7c478bd9Sstevel@tonic-gate 	itm_expr_t		*expr;
1442*7c478bd9Sstevel@tonic-gate 	itm_expr_t		*expr_op;
1443*7c478bd9Sstevel@tonic-gate 	itm_num_t		num;
1444*7c478bd9Sstevel@tonic-gate 	unsigned char		*p;
1445*7c478bd9Sstevel@tonic-gate 	long			i;
1446*7c478bd9Sstevel@tonic-gate 	itm_expr_t		*expr0;
1447*7c478bd9Sstevel@tonic-gate 	itm_num_t		num00;
1448*7c478bd9Sstevel@tonic-gate 	itm_num_t		num01;
1449*7c478bd9Sstevel@tonic-gate 
1450*7c478bd9Sstevel@tonic-gate #define	EVAL_EXPR_E(n) (eval_expr(ist, expr->data.operand[(n)],		\
1451*7c478bd9Sstevel@tonic-gate 					inbytesleft, inbuf, outbytesleft))
1452*7c478bd9Sstevel@tonic-gate #define	EVAL_EXPR_D(n)	((itm_num_t)(expr->data.operand[(n)].itm_ptr))
1453*7c478bd9Sstevel@tonic-gate #define	EVAL_EXPR_R(n)	(REG((itm_num_t)(expr->data.operand[(n)].itm_ptr)))
1454*7c478bd9Sstevel@tonic-gate #define	EVAL_EXPR_INVD(n)						\
1455*7c478bd9Sstevel@tonic-gate 	((num0 ## n) = ((itm_num_t)(expr->data.operand[(n)].itm_ptr)),	\
1456*7c478bd9Sstevel@tonic-gate 	((num0 ## n) < 0) ?						\
1457*7c478bd9Sstevel@tonic-gate 	(((-1) == (num0 ## n)) ? inbytesleft : 0) :			\
1458*7c478bd9Sstevel@tonic-gate 	(((num0 ## n) < inbytesleft) ?					\
1459*7c478bd9Sstevel@tonic-gate 	(*(unsigned char *)(inbuf + (num0 ## n))) : 0))
1460*7c478bd9Sstevel@tonic-gate #define	EVAL_EXPR(n)							\
1461*7c478bd9Sstevel@tonic-gate 	(expr0 = ADDR(expr->data.operand[(n)]),				\
1462*7c478bd9Sstevel@tonic-gate 	(itm_num_t)((expr0->type == ITM_EXPR_INT) ?		       	\
1463*7c478bd9Sstevel@tonic-gate 	expr0->data.itm_exnum :						\
1464*7c478bd9Sstevel@tonic-gate 	((expr0->type == ITM_EXPR_REG) ?				\
1465*7c478bd9Sstevel@tonic-gate 	REG(expr0->data.itm_exnum) :					\
1466*7c478bd9Sstevel@tonic-gate 	((expr0->type == ITM_EXPR_IN_VECTOR_D) ?			\
1467*7c478bd9Sstevel@tonic-gate 	((expr0->data.itm_exnum < 0) ?					\
1468*7c478bd9Sstevel@tonic-gate 	(((-1) == expr0->data.itm_exnum) ? inbytesleft : 0) :		\
1469*7c478bd9Sstevel@tonic-gate 	((expr0->data.itm_exnum < inbytesleft) ?			\
1470*7c478bd9Sstevel@tonic-gate 	(*(uchar_t *)(inbuf + expr0->data.itm_exnum)) : 0)) :		\
1471*7c478bd9Sstevel@tonic-gate 	eval_expr(ist, expr->data.operand[(n)],				\
1472*7c478bd9Sstevel@tonic-gate 	inbytesleft, inbuf, outbytesleft)))))
1473*7c478bd9Sstevel@tonic-gate 
1474*7c478bd9Sstevel@tonic-gate #define	EVAL_OP_BIN_PROTO(op, name, name0, name1)			\
1475*7c478bd9Sstevel@tonic-gate 	case ITM_EXPR_##name##_##name0##_##name1:			\
1476*7c478bd9Sstevel@tonic-gate 		return (EVAL_EXPR_##name0(0) op EVAL_EXPR_##name1(1));
1477*7c478bd9Sstevel@tonic-gate 
1478*7c478bd9Sstevel@tonic-gate #define	EVAL_OP_BIN1(op, name)					\
1479*7c478bd9Sstevel@tonic-gate 		EVAL_OP_BIN_PROTO(op, name, E, E)		\
1480*7c478bd9Sstevel@tonic-gate 		EVAL_OP_BIN_PROTO(op, name, E, D)		\
1481*7c478bd9Sstevel@tonic-gate 		EVAL_OP_BIN_PROTO(op, name, E, R)		\
1482*7c478bd9Sstevel@tonic-gate 		EVAL_OP_BIN_PROTO(op, name, E, INVD)
1483*7c478bd9Sstevel@tonic-gate 
1484*7c478bd9Sstevel@tonic-gate #define	EVAL_OP_BIN2(op, name)					\
1485*7c478bd9Sstevel@tonic-gate 		EVAL_OP_BIN_PROTO(op, name, D, E)		\
1486*7c478bd9Sstevel@tonic-gate 		EVAL_OP_BIN_PROTO(op, name, D, D)		\
1487*7c478bd9Sstevel@tonic-gate 		EVAL_OP_BIN_PROTO(op, name, D, R)		\
1488*7c478bd9Sstevel@tonic-gate 		EVAL_OP_BIN_PROTO(op, name, D, INVD)
1489*7c478bd9Sstevel@tonic-gate 
1490*7c478bd9Sstevel@tonic-gate #define	EVAL_OP_BIN3(op, name)					\
1491*7c478bd9Sstevel@tonic-gate 		EVAL_OP_BIN_PROTO(op, name, R, E)		\
1492*7c478bd9Sstevel@tonic-gate 		EVAL_OP_BIN_PROTO(op, name, R, D)		\
1493*7c478bd9Sstevel@tonic-gate 		EVAL_OP_BIN_PROTO(op, name, R, R)		\
1494*7c478bd9Sstevel@tonic-gate 		EVAL_OP_BIN_PROTO(op, name, R, INVD)
1495*7c478bd9Sstevel@tonic-gate 
1496*7c478bd9Sstevel@tonic-gate #define	EVAL_OP_BIN4(op, name)					\
1497*7c478bd9Sstevel@tonic-gate 		EVAL_OP_BIN_PROTO(op, name, INVD, E)		\
1498*7c478bd9Sstevel@tonic-gate 		EVAL_OP_BIN_PROTO(op, name, INVD, D)		\
1499*7c478bd9Sstevel@tonic-gate 		EVAL_OP_BIN_PROTO(op, name, INVD, R)		\
1500*7c478bd9Sstevel@tonic-gate 		EVAL_OP_BIN_PROTO(op, name, INVD, INVD)
1501*7c478bd9Sstevel@tonic-gate 
1502*7c478bd9Sstevel@tonic-gate #define	EVAL_OP_BIN_PROTECT_PROTO(op, name, name0, name1)	\
1503*7c478bd9Sstevel@tonic-gate 	case ITM_EXPR_##name##_##name0##_##name1:		\
1504*7c478bd9Sstevel@tonic-gate 		num = EVAL_EXPR_##name1(1);			\
1505*7c478bd9Sstevel@tonic-gate 		if (0 != num) {					\
1506*7c478bd9Sstevel@tonic-gate 			return (EVAL_EXPR_##name0(0) op num);	\
1507*7c478bd9Sstevel@tonic-gate 		} else {					\
1508*7c478bd9Sstevel@tonic-gate 			return (0);				\
1509*7c478bd9Sstevel@tonic-gate 		}
1510*7c478bd9Sstevel@tonic-gate 
1511*7c478bd9Sstevel@tonic-gate #define	EVAL_OP_BIN_PROTECT1(op, name)				\
1512*7c478bd9Sstevel@tonic-gate 		EVAL_OP_BIN_PROTECT_PROTO(op, name, E, E)	\
1513*7c478bd9Sstevel@tonic-gate 		EVAL_OP_BIN_PROTECT_PROTO(op, name, E, D)	\
1514*7c478bd9Sstevel@tonic-gate 		EVAL_OP_BIN_PROTECT_PROTO(op, name, E, R)	\
1515*7c478bd9Sstevel@tonic-gate 		EVAL_OP_BIN_PROTECT_PROTO(op, name, E, INVD)
1516*7c478bd9Sstevel@tonic-gate 
1517*7c478bd9Sstevel@tonic-gate #define	EVAL_OP_BIN_PROTECT2(op, name)				\
1518*7c478bd9Sstevel@tonic-gate 		EVAL_OP_BIN_PROTECT_PROTO(op, name, D, E)	\
1519*7c478bd9Sstevel@tonic-gate 		EVAL_OP_BIN_PROTECT_PROTO(op, name, D, D)	\
1520*7c478bd9Sstevel@tonic-gate 		EVAL_OP_BIN_PROTECT_PROTO(op, name, D, R)	\
1521*7c478bd9Sstevel@tonic-gate 		EVAL_OP_BIN_PROTECT_PROTO(op, name, D, INVD)
1522*7c478bd9Sstevel@tonic-gate 
1523*7c478bd9Sstevel@tonic-gate #define	EVAL_OP_BIN_PROTECT3(op, name)				\
1524*7c478bd9Sstevel@tonic-gate 		EVAL_OP_BIN_PROTECT_PROTO(op, name, R, E)	\
1525*7c478bd9Sstevel@tonic-gate 		EVAL_OP_BIN_PROTECT_PROTO(op, name, R, D)	\
1526*7c478bd9Sstevel@tonic-gate 		EVAL_OP_BIN_PROTECT_PROTO(op, name, R, R)	\
1527*7c478bd9Sstevel@tonic-gate 		EVAL_OP_BIN_PROTECT_PROTO(op, name, R, INVD)
1528*7c478bd9Sstevel@tonic-gate 
1529*7c478bd9Sstevel@tonic-gate #define	EVAL_OP_BIN_PROTECT4(op, name)				\
1530*7c478bd9Sstevel@tonic-gate 		EVAL_OP_BIN_PROTECT_PROTO(op, name, INVD, E)	\
1531*7c478bd9Sstevel@tonic-gate 		EVAL_OP_BIN_PROTECT_PROTO(op, name, INVD, D)	\
1532*7c478bd9Sstevel@tonic-gate 		EVAL_OP_BIN_PROTECT_PROTO(op, name, INVD, R)	\
1533*7c478bd9Sstevel@tonic-gate 		EVAL_OP_BIN_PROTECT_PROTO(op, name, INVD, INVD)
1534*7c478bd9Sstevel@tonic-gate 
1535*7c478bd9Sstevel@tonic-gate 	expr = ADDR(expr_place);
1536*7c478bd9Sstevel@tonic-gate 
1537*7c478bd9Sstevel@tonic-gate 	switch (expr->type) {
1538*7c478bd9Sstevel@tonic-gate 	case ITM_EXPR_NONE:		/* not used */
1539*7c478bd9Sstevel@tonic-gate 		return (0);
1540*7c478bd9Sstevel@tonic-gate 	case ITM_EXPR_NOP:		/* not used */
1541*7c478bd9Sstevel@tonic-gate 		return (0);
1542*7c478bd9Sstevel@tonic-gate 	case ITM_EXPR_NAME:		/* not used */
1543*7c478bd9Sstevel@tonic-gate 		return (0);
1544*7c478bd9Sstevel@tonic-gate 	case ITM_EXPR_INT:		/* integer */
1545*7c478bd9Sstevel@tonic-gate 		return (expr->data.itm_exnum);
1546*7c478bd9Sstevel@tonic-gate 	case ITM_EXPR_SEQ:		/* byte sequence */
1547*7c478bd9Sstevel@tonic-gate 		if ((sizeof (itm_place_t)) < expr->data.value.size) {
1548*7c478bd9Sstevel@tonic-gate 			p = (unsigned char *)ADDR(expr->data.value.place);
1549*7c478bd9Sstevel@tonic-gate 		} else {
1550*7c478bd9Sstevel@tonic-gate 			p = (unsigned char *)&(expr->data.value.place);
1551*7c478bd9Sstevel@tonic-gate 		}
1552*7c478bd9Sstevel@tonic-gate 		for (i = 0, num = 0; i < expr->data.value.size; i++, p++) {
1553*7c478bd9Sstevel@tonic-gate 			num = ((num << 8) | *p);
1554*7c478bd9Sstevel@tonic-gate 		}
1555*7c478bd9Sstevel@tonic-gate 		return	(num);
1556*7c478bd9Sstevel@tonic-gate 	case ITM_EXPR_REG:		/* register */
1557*7c478bd9Sstevel@tonic-gate 		return (REG(expr->data.itm_exnum));
1558*7c478bd9Sstevel@tonic-gate 	case ITM_EXPR_IN_VECTOR:	/* in[expr] */
1559*7c478bd9Sstevel@tonic-gate 		num = EVAL_EXPR(0);
1560*7c478bd9Sstevel@tonic-gate 		if ((0 <= num) && (num < inbytesleft)) {
1561*7c478bd9Sstevel@tonic-gate 			return (*((unsigned char *)(inbuf + num)));
1562*7c478bd9Sstevel@tonic-gate 		} else if ((-1) == num) {
1563*7c478bd9Sstevel@tonic-gate 			return	(inbytesleft);
1564*7c478bd9Sstevel@tonic-gate 		} else {
1565*7c478bd9Sstevel@tonic-gate 			return (0);
1566*7c478bd9Sstevel@tonic-gate 		}
1567*7c478bd9Sstevel@tonic-gate 	case ITM_EXPR_IN_VECTOR_D:	/* in[DECIMAL] */
1568*7c478bd9Sstevel@tonic-gate 		num = expr->data.itm_exnum;
1569*7c478bd9Sstevel@tonic-gate 		if ((0 <= num) && (num < inbytesleft)) {
1570*7c478bd9Sstevel@tonic-gate 			return (*((unsigned char *)(inbuf + num)));
1571*7c478bd9Sstevel@tonic-gate 		} else if ((-1) == num) {
1572*7c478bd9Sstevel@tonic-gate 			return	(inbytesleft);
1573*7c478bd9Sstevel@tonic-gate 		} else {
1574*7c478bd9Sstevel@tonic-gate 			return (0);
1575*7c478bd9Sstevel@tonic-gate 		}
1576*7c478bd9Sstevel@tonic-gate 	case ITM_EXPR_OUT:		/* out */
1577*7c478bd9Sstevel@tonic-gate 		return	(outbytesleft);
1578*7c478bd9Sstevel@tonic-gate 	case ITM_EXPR_TRUE:		/* true */
1579*7c478bd9Sstevel@tonic-gate 		return (1);
1580*7c478bd9Sstevel@tonic-gate 	case ITM_EXPR_FALSE:		/* false */
1581*7c478bd9Sstevel@tonic-gate 		return (0);
1582*7c478bd9Sstevel@tonic-gate 	case ITM_EXPR_UMINUS:		/* unary minus */
1583*7c478bd9Sstevel@tonic-gate 		return ((-1) * EVAL_EXPR(0));
1584*7c478bd9Sstevel@tonic-gate #define	PLUS_FOR_CSTYLE_CLEAN +
1585*7c478bd9Sstevel@tonic-gate #define	MINUS_FOR_CSTYLE_CLEAN -
1586*7c478bd9Sstevel@tonic-gate #define	MUL_FOR_CSTYLE_CLEAN *
1587*7c478bd9Sstevel@tonic-gate #define	DIV_FOR_CSTYLE_CLEAN /
1588*7c478bd9Sstevel@tonic-gate #define	MOD_FOR_CSTYLE_CLEAN %
1589*7c478bd9Sstevel@tonic-gate #define	SHIFT_L_FOR_CSTYLE_CLEAN <<
1590*7c478bd9Sstevel@tonic-gate #define	SHIFT_R_FOR_CSTYLE_CLEAN >>
1591*7c478bd9Sstevel@tonic-gate #define	OR_FOR_CSTYLE_CLEAN |
1592*7c478bd9Sstevel@tonic-gate #define	XOR_FOR_CSTYLE_CLEAN ^
1593*7c478bd9Sstevel@tonic-gate #define	AND_FOR_CSTYLE_CLEAN &
1594*7c478bd9Sstevel@tonic-gate #define	EQ_FOR_CSTYLE_CLEAN ==
1595*7c478bd9Sstevel@tonic-gate #define	NE_FOR_CSTYLE_CLEAN !=
1596*7c478bd9Sstevel@tonic-gate #define	GT_FOR_CSTYLE_CLEAN >
1597*7c478bd9Sstevel@tonic-gate #define	GE_FOR_CSTYLE_CLEAN >=
1598*7c478bd9Sstevel@tonic-gate #define	LT_FOR_CSTYLE_CLEAN <
1599*7c478bd9Sstevel@tonic-gate #define	LE_FOR_CSTYLE_CLEAN <=
1600*7c478bd9Sstevel@tonic-gate 	EVAL_OP_BIN1(PLUS_FOR_CSTYLE_CLEAN, PLUS)	/* A + B */
1601*7c478bd9Sstevel@tonic-gate 	EVAL_OP_BIN2(PLUS_FOR_CSTYLE_CLEAN, PLUS)	/* A + B */
1602*7c478bd9Sstevel@tonic-gate 	EVAL_OP_BIN3(PLUS_FOR_CSTYLE_CLEAN, PLUS)	/* A + B */
1603*7c478bd9Sstevel@tonic-gate 	EVAL_OP_BIN4(PLUS_FOR_CSTYLE_CLEAN, PLUS)	/* A + B */
1604*7c478bd9Sstevel@tonic-gate 
1605*7c478bd9Sstevel@tonic-gate 	EVAL_OP_BIN1(MINUS_FOR_CSTYLE_CLEAN, MINUS)	/* A - B */
1606*7c478bd9Sstevel@tonic-gate 	EVAL_OP_BIN2(MINUS_FOR_CSTYLE_CLEAN, MINUS)	/* A - B */
1607*7c478bd9Sstevel@tonic-gate 	EVAL_OP_BIN3(MINUS_FOR_CSTYLE_CLEAN, MINUS)	/* A - B */
1608*7c478bd9Sstevel@tonic-gate 	EVAL_OP_BIN4(MINUS_FOR_CSTYLE_CLEAN, MINUS)	/* A - B */
1609*7c478bd9Sstevel@tonic-gate 
1610*7c478bd9Sstevel@tonic-gate 	EVAL_OP_BIN1(MUL_FOR_CSTYLE_CLEAN, MUL)		/* A * B */
1611*7c478bd9Sstevel@tonic-gate 	EVAL_OP_BIN2(MUL_FOR_CSTYLE_CLEAN, MUL)		/* A * B */
1612*7c478bd9Sstevel@tonic-gate 	EVAL_OP_BIN3(MUL_FOR_CSTYLE_CLEAN, MUL)		/* A * B */
1613*7c478bd9Sstevel@tonic-gate 	EVAL_OP_BIN4(MUL_FOR_CSTYLE_CLEAN, MUL)		/* A * B */
1614*7c478bd9Sstevel@tonic-gate 
1615*7c478bd9Sstevel@tonic-gate 	EVAL_OP_BIN_PROTECT1(DIV_FOR_CSTYLE_CLEAN, DIV)	/* A / B */
1616*7c478bd9Sstevel@tonic-gate 	EVAL_OP_BIN_PROTECT2(DIV_FOR_CSTYLE_CLEAN, DIV)	/* A / B */
1617*7c478bd9Sstevel@tonic-gate 	EVAL_OP_BIN_PROTECT3(DIV_FOR_CSTYLE_CLEAN, DIV)	/* A / B */
1618*7c478bd9Sstevel@tonic-gate 	EVAL_OP_BIN_PROTECT4(DIV_FOR_CSTYLE_CLEAN, DIV)	/* A / B */
1619*7c478bd9Sstevel@tonic-gate 
1620*7c478bd9Sstevel@tonic-gate 	EVAL_OP_BIN_PROTECT1(MOD_FOR_CSTYLE_CLEAN, MOD)	/* A % B */
1621*7c478bd9Sstevel@tonic-gate 	EVAL_OP_BIN_PROTECT2(MOD_FOR_CSTYLE_CLEAN, MOD)	/* A % B */
1622*7c478bd9Sstevel@tonic-gate 	EVAL_OP_BIN_PROTECT3(MOD_FOR_CSTYLE_CLEAN, MOD)	/* A % B */
1623*7c478bd9Sstevel@tonic-gate 	EVAL_OP_BIN_PROTECT4(MOD_FOR_CSTYLE_CLEAN, MOD)	/* A % B */
1624*7c478bd9Sstevel@tonic-gate 
1625*7c478bd9Sstevel@tonic-gate 	EVAL_OP_BIN1(SHIFT_L_FOR_CSTYLE_CLEAN, SHIFT_L)	/* A << B */
1626*7c478bd9Sstevel@tonic-gate 	EVAL_OP_BIN2(SHIFT_L_FOR_CSTYLE_CLEAN, SHIFT_L)	/* A << B */
1627*7c478bd9Sstevel@tonic-gate 	EVAL_OP_BIN3(SHIFT_L_FOR_CSTYLE_CLEAN, SHIFT_L)	/* A << B */
1628*7c478bd9Sstevel@tonic-gate 	EVAL_OP_BIN4(SHIFT_L_FOR_CSTYLE_CLEAN, SHIFT_L)	/* A << B */
1629*7c478bd9Sstevel@tonic-gate 
1630*7c478bd9Sstevel@tonic-gate 	EVAL_OP_BIN1(SHIFT_R_FOR_CSTYLE_CLEAN, SHIFT_R)	/* A >> B */
1631*7c478bd9Sstevel@tonic-gate 	EVAL_OP_BIN2(SHIFT_R_FOR_CSTYLE_CLEAN, SHIFT_R)	/* A >> B */
1632*7c478bd9Sstevel@tonic-gate 	EVAL_OP_BIN3(SHIFT_R_FOR_CSTYLE_CLEAN, SHIFT_R)	/* A >> B */
1633*7c478bd9Sstevel@tonic-gate 	EVAL_OP_BIN4(SHIFT_R_FOR_CSTYLE_CLEAN, SHIFT_R)	/* A >> B */
1634*7c478bd9Sstevel@tonic-gate 
1635*7c478bd9Sstevel@tonic-gate 	EVAL_OP_BIN1(OR_FOR_CSTYLE_CLEAN, OR)		/* A |	B */
1636*7c478bd9Sstevel@tonic-gate 	EVAL_OP_BIN2(OR_FOR_CSTYLE_CLEAN, OR)		/* A |	B */
1637*7c478bd9Sstevel@tonic-gate 	EVAL_OP_BIN3(OR_FOR_CSTYLE_CLEAN, OR)		/* A |	B */
1638*7c478bd9Sstevel@tonic-gate 	EVAL_OP_BIN4(OR_FOR_CSTYLE_CLEAN, OR)		/* A |	B */
1639*7c478bd9Sstevel@tonic-gate 
1640*7c478bd9Sstevel@tonic-gate 	EVAL_OP_BIN1(XOR_FOR_CSTYLE_CLEAN, XOR)		/* A ^	B */
1641*7c478bd9Sstevel@tonic-gate 	EVAL_OP_BIN2(XOR_FOR_CSTYLE_CLEAN, XOR)		/* A ^	B */
1642*7c478bd9Sstevel@tonic-gate 	EVAL_OP_BIN3(XOR_FOR_CSTYLE_CLEAN, XOR)		/* A ^	B */
1643*7c478bd9Sstevel@tonic-gate 	EVAL_OP_BIN4(XOR_FOR_CSTYLE_CLEAN, XOR)		/* A ^	B */
1644*7c478bd9Sstevel@tonic-gate 
1645*7c478bd9Sstevel@tonic-gate 	EVAL_OP_BIN1(AND_FOR_CSTYLE_CLEAN, AND)		/* A &	B */
1646*7c478bd9Sstevel@tonic-gate 	EVAL_OP_BIN2(AND_FOR_CSTYLE_CLEAN, AND)		/* A &	B */
1647*7c478bd9Sstevel@tonic-gate 	EVAL_OP_BIN3(AND_FOR_CSTYLE_CLEAN, AND)		/* A &	B */
1648*7c478bd9Sstevel@tonic-gate 	EVAL_OP_BIN4(AND_FOR_CSTYLE_CLEAN, AND)		/* A &	B */
1649*7c478bd9Sstevel@tonic-gate 
1650*7c478bd9Sstevel@tonic-gate 	EVAL_OP_BIN1(EQ_FOR_CSTYLE_CLEAN, EQ)		/* A == B */
1651*7c478bd9Sstevel@tonic-gate 	EVAL_OP_BIN2(EQ_FOR_CSTYLE_CLEAN, EQ)		/* A == B */
1652*7c478bd9Sstevel@tonic-gate 	EVAL_OP_BIN3(EQ_FOR_CSTYLE_CLEAN, EQ)		/* A == B */
1653*7c478bd9Sstevel@tonic-gate 	EVAL_OP_BIN4(EQ_FOR_CSTYLE_CLEAN, EQ)		/* A == B */
1654*7c478bd9Sstevel@tonic-gate 
1655*7c478bd9Sstevel@tonic-gate 	EVAL_OP_BIN1(NE_FOR_CSTYLE_CLEAN, NE)		/* A != B */
1656*7c478bd9Sstevel@tonic-gate 	EVAL_OP_BIN2(NE_FOR_CSTYLE_CLEAN, NE)		/* A != B */
1657*7c478bd9Sstevel@tonic-gate 	EVAL_OP_BIN3(NE_FOR_CSTYLE_CLEAN, NE)		/* A != B */
1658*7c478bd9Sstevel@tonic-gate 	EVAL_OP_BIN4(NE_FOR_CSTYLE_CLEAN, NE)		/* A != B */
1659*7c478bd9Sstevel@tonic-gate 
1660*7c478bd9Sstevel@tonic-gate 	EVAL_OP_BIN1(GT_FOR_CSTYLE_CLEAN, GT)		/* A >	B */
1661*7c478bd9Sstevel@tonic-gate 	EVAL_OP_BIN2(GT_FOR_CSTYLE_CLEAN, GT)		/* A >	B */
1662*7c478bd9Sstevel@tonic-gate 	EVAL_OP_BIN3(GT_FOR_CSTYLE_CLEAN, GT)		/* A >	B */
1663*7c478bd9Sstevel@tonic-gate 	EVAL_OP_BIN4(GT_FOR_CSTYLE_CLEAN, GT)		/* A >	B */
1664*7c478bd9Sstevel@tonic-gate 
1665*7c478bd9Sstevel@tonic-gate 	EVAL_OP_BIN1(GE_FOR_CSTYLE_CLEAN, GE)		/* A >= B */
1666*7c478bd9Sstevel@tonic-gate 	EVAL_OP_BIN2(GE_FOR_CSTYLE_CLEAN, GE)		/* A >= B */
1667*7c478bd9Sstevel@tonic-gate 	EVAL_OP_BIN3(GE_FOR_CSTYLE_CLEAN, GE)		/* A >= B */
1668*7c478bd9Sstevel@tonic-gate 	EVAL_OP_BIN4(GE_FOR_CSTYLE_CLEAN, GE)		/* A >= B */
1669*7c478bd9Sstevel@tonic-gate 
1670*7c478bd9Sstevel@tonic-gate 	EVAL_OP_BIN1(LT_FOR_CSTYLE_CLEAN, LT)		/* A <	B */
1671*7c478bd9Sstevel@tonic-gate 	EVAL_OP_BIN2(LT_FOR_CSTYLE_CLEAN, LT)		/* A <	B */
1672*7c478bd9Sstevel@tonic-gate 	EVAL_OP_BIN3(LT_FOR_CSTYLE_CLEAN, LT)		/* A <	B */
1673*7c478bd9Sstevel@tonic-gate 	EVAL_OP_BIN4(LT_FOR_CSTYLE_CLEAN, LT)		/* A <	B */
1674*7c478bd9Sstevel@tonic-gate 
1675*7c478bd9Sstevel@tonic-gate 	EVAL_OP_BIN1(LE_FOR_CSTYLE_CLEAN, LE)		/* A <= B */
1676*7c478bd9Sstevel@tonic-gate 	EVAL_OP_BIN2(LE_FOR_CSTYLE_CLEAN, LE)		/* A <= B */
1677*7c478bd9Sstevel@tonic-gate 	EVAL_OP_BIN3(LE_FOR_CSTYLE_CLEAN, LE)		/* A <= B */
1678*7c478bd9Sstevel@tonic-gate 	EVAL_OP_BIN4(LE_FOR_CSTYLE_CLEAN, LE)		/* A <= B */
1679*7c478bd9Sstevel@tonic-gate 
1680*7c478bd9Sstevel@tonic-gate 	case ITM_EXPR_NOT:		/*   !A	  */
1681*7c478bd9Sstevel@tonic-gate 		return (!(EVAL_EXPR(0)));
1682*7c478bd9Sstevel@tonic-gate 	case ITM_EXPR_NEG:		/*   ~A	  */
1683*7c478bd9Sstevel@tonic-gate 		return (~(EVAL_EXPR(0)));
1684*7c478bd9Sstevel@tonic-gate 	case ITM_EXPR_LOR:		/* A || B */
1685*7c478bd9Sstevel@tonic-gate 		if (0 != (num = EVAL_EXPR(0)))
1686*7c478bd9Sstevel@tonic-gate 			return	(num);
1687*7c478bd9Sstevel@tonic-gate 		if (0 != (num = EVAL_EXPR(1)))
1688*7c478bd9Sstevel@tonic-gate 			return	(num);
1689*7c478bd9Sstevel@tonic-gate 		return (0);
1690*7c478bd9Sstevel@tonic-gate 	case ITM_EXPR_LAND:		/* A && B */
1691*7c478bd9Sstevel@tonic-gate 		if (0 == EVAL_EXPR(0))
1692*7c478bd9Sstevel@tonic-gate 			return (0);
1693*7c478bd9Sstevel@tonic-gate 		if (0 == (num = EVAL_EXPR(1)))
1694*7c478bd9Sstevel@tonic-gate 			return (0);
1695*7c478bd9Sstevel@tonic-gate 		return	(num);
1696*7c478bd9Sstevel@tonic-gate 	case ITM_EXPR_ASSIGN:		/* A  = B */
1697*7c478bd9Sstevel@tonic-gate 		num = EVAL_EXPR(1);
1698*7c478bd9Sstevel@tonic-gate 		if (expr->data.operand[0].itm_ptr < ist->itm_hdr->reg_num) {
1699*7c478bd9Sstevel@tonic-gate 			return (*(ist->regs + expr->data.operand[0].itm_ptr)
1700*7c478bd9Sstevel@tonic-gate 				= num);
1701*7c478bd9Sstevel@tonic-gate 		} else {
1702*7c478bd9Sstevel@tonic-gate 			return (0);
1703*7c478bd9Sstevel@tonic-gate 		}
1704*7c478bd9Sstevel@tonic-gate 	case ITM_EXPR_IN_EQ:		/* in == A */
1705*7c478bd9Sstevel@tonic-gate 		expr_op = ADDR(expr->data.operand[0]);
1706*7c478bd9Sstevel@tonic-gate 		switch (expr_op->type) {
1707*7c478bd9Sstevel@tonic-gate 		case ITM_EXPR_SEQ:
1708*7c478bd9Sstevel@tonic-gate 			if (inbytesleft < expr_op->data.value.size) {
1709*7c478bd9Sstevel@tonic-gate 				return (0);
1710*7c478bd9Sstevel@tonic-gate 			}
1711*7c478bd9Sstevel@tonic-gate 			p = DADDR(&(expr_op->data.value));
1712*7c478bd9Sstevel@tonic-gate 			for (i = 0; i < expr_op->data.value.size; i++, p++) {
1713*7c478bd9Sstevel@tonic-gate 				if (*p != *(inbuf + i)) {
1714*7c478bd9Sstevel@tonic-gate 					return (0);
1715*7c478bd9Sstevel@tonic-gate 				}
1716*7c478bd9Sstevel@tonic-gate 			}
1717*7c478bd9Sstevel@tonic-gate 			return (1);
1718*7c478bd9Sstevel@tonic-gate 		default:
1719*7c478bd9Sstevel@tonic-gate 			num = EVAL_EXPR(0);
1720*7c478bd9Sstevel@tonic-gate 			return (num == *((unsigned char *)inbuf));
1721*7c478bd9Sstevel@tonic-gate 		}
1722*7c478bd9Sstevel@tonic-gate 	default:
1723*7c478bd9Sstevel@tonic-gate 		break;
1724*7c478bd9Sstevel@tonic-gate 	}
1725*7c478bd9Sstevel@tonic-gate 
1726*7c478bd9Sstevel@tonic-gate 	return (0);
1727*7c478bd9Sstevel@tonic-gate 
1728*7c478bd9Sstevel@tonic-gate #undef EVAL_EXPR_E
1729*7c478bd9Sstevel@tonic-gate #undef EVAL_EXPR_D
1730*7c478bd9Sstevel@tonic-gate #undef EVAL_EXPR_R
1731*7c478bd9Sstevel@tonic-gate #undef EVAL_EXPR_INVD
1732*7c478bd9Sstevel@tonic-gate #undef EVAL_EXPR
1733*7c478bd9Sstevel@tonic-gate }
1734*7c478bd9Sstevel@tonic-gate 
1735*7c478bd9Sstevel@tonic-gate 
1736*7c478bd9Sstevel@tonic-gate /*
1737*7c478bd9Sstevel@tonic-gate  * maintain ITM reference information
1738*7c478bd9Sstevel@tonic-gate  */
1739*7c478bd9Sstevel@tonic-gate static void
1740*7c478bd9Sstevel@tonic-gate itm_ref_free(int fd, void *ptr0, void *ptr1, void *ptr2, size_t len)
1741*7c478bd9Sstevel@tonic-gate {
1742*7c478bd9Sstevel@tonic-gate 	int	r;
1743*7c478bd9Sstevel@tonic-gate 	r = errno;
1744*7c478bd9Sstevel@tonic-gate 	if (0 <= fd) {
1745*7c478bd9Sstevel@tonic-gate 		(void) close(fd);
1746*7c478bd9Sstevel@tonic-gate 	}
1747*7c478bd9Sstevel@tonic-gate 	free(ptr0);
1748*7c478bd9Sstevel@tonic-gate 	free(ptr1);
1749*7c478bd9Sstevel@tonic-gate 	if (0 < len) {
1750*7c478bd9Sstevel@tonic-gate 		(void) munmap(ptr2, len);
1751*7c478bd9Sstevel@tonic-gate 	}
1752*7c478bd9Sstevel@tonic-gate 	errno = r;
1753*7c478bd9Sstevel@tonic-gate }
1754*7c478bd9Sstevel@tonic-gate 
1755*7c478bd9Sstevel@tonic-gate static itm_ref_t *
1756*7c478bd9Sstevel@tonic-gate itm_ref_inc(const char		*itm)
1757*7c478bd9Sstevel@tonic-gate {
1758*7c478bd9Sstevel@tonic-gate 	itm_ref_t	*ref;
1759*7c478bd9Sstevel@tonic-gate 	itm_hdr_t	*hdr;
1760*7c478bd9Sstevel@tonic-gate 	struct stat	st;
1761*7c478bd9Sstevel@tonic-gate 	int		fd;
1762*7c478bd9Sstevel@tonic-gate 
1763*7c478bd9Sstevel@tonic-gate 	fd = open(itm, O_RDONLY, 0);
1764*7c478bd9Sstevel@tonic-gate 	if (fd == -1) {
1765*7c478bd9Sstevel@tonic-gate 		itm_ref_free(-1, NULL, NULL, NULL, 0);
1766*7c478bd9Sstevel@tonic-gate 		return	(NULL);
1767*7c478bd9Sstevel@tonic-gate 	}
1768*7c478bd9Sstevel@tonic-gate 
1769*7c478bd9Sstevel@tonic-gate 	if (fstat(fd, &st) == -1) {
1770*7c478bd9Sstevel@tonic-gate 		itm_ref_free(fd, NULL, NULL, NULL, 0);
1771*7c478bd9Sstevel@tonic-gate 		return	(NULL);
1772*7c478bd9Sstevel@tonic-gate 	}
1773*7c478bd9Sstevel@tonic-gate 	hdr = (void *) mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
1774*7c478bd9Sstevel@tonic-gate 	if (MAP_FAILED == hdr) {
1775*7c478bd9Sstevel@tonic-gate 		itm_ref_free(fd, NULL, NULL, NULL, 0);
1776*7c478bd9Sstevel@tonic-gate 		return	(NULL);
1777*7c478bd9Sstevel@tonic-gate 	}
1778*7c478bd9Sstevel@tonic-gate 
1779*7c478bd9Sstevel@tonic-gate 	(void) close(fd);
1780*7c478bd9Sstevel@tonic-gate 
1781*7c478bd9Sstevel@tonic-gate 	ref = malloc(sizeof (itm_ref_t));
1782*7c478bd9Sstevel@tonic-gate 	if (NULL == ref) {
1783*7c478bd9Sstevel@tonic-gate 		itm_ref_free(-1, NULL, NULL, hdr, st.st_size);
1784*7c478bd9Sstevel@tonic-gate 		return	(NULL);
1785*7c478bd9Sstevel@tonic-gate 	}
1786*7c478bd9Sstevel@tonic-gate 	ref->name = malloc(strlen(itm) + 1);
1787*7c478bd9Sstevel@tonic-gate 	if (NULL == ref->name) {
1788*7c478bd9Sstevel@tonic-gate 		itm_ref_free(-1, ref, NULL, hdr, st.st_size);
1789*7c478bd9Sstevel@tonic-gate 		return	(NULL);
1790*7c478bd9Sstevel@tonic-gate 	}
1791*7c478bd9Sstevel@tonic-gate 	(void) strcpy(ref->name, itm);
1792*7c478bd9Sstevel@tonic-gate 	ref->hdr = hdr;
1793*7c478bd9Sstevel@tonic-gate 	ref->len = st.st_size;
1794*7c478bd9Sstevel@tonic-gate 
1795*7c478bd9Sstevel@tonic-gate 	if ((hdr->ident[0] != ITM_IDENT_0) ||
1796*7c478bd9Sstevel@tonic-gate 	    (hdr->ident[1] != ITM_IDENT_1) ||
1797*7c478bd9Sstevel@tonic-gate 	    (hdr->ident[2] != ITM_IDENT_2) ||
1798*7c478bd9Sstevel@tonic-gate 	    (hdr->ident[3] != ITM_IDENT_3) ||
1799*7c478bd9Sstevel@tonic-gate 	    (hdr->spec[0] != ITM_SPEC_0) ||
1800*7c478bd9Sstevel@tonic-gate 	    (hdr->spec[1] != ITM_SPEC_1) ||
1801*7c478bd9Sstevel@tonic-gate 	    (hdr->spec[2] != ITM_SPEC_2) ||
1802*7c478bd9Sstevel@tonic-gate #if defined(_LITTLE_ENDIAN)
1803*7c478bd9Sstevel@tonic-gate #if defined(_LP64)
1804*7c478bd9Sstevel@tonic-gate 	    ((hdr->spec[3] != ITM_SPEC_3_32_LITTLE_ENDIAN) &&
1805*7c478bd9Sstevel@tonic-gate 	    (hdr->spec[3] != ITM_SPEC_3_64_LITTLE_ENDIAN)) ||
1806*7c478bd9Sstevel@tonic-gate #else
1807*7c478bd9Sstevel@tonic-gate 	    (hdr->spec[3] != ITM_SPEC_3_32_LITTLE_ENDIAN) ||
1808*7c478bd9Sstevel@tonic-gate #endif
1809*7c478bd9Sstevel@tonic-gate #else
1810*7c478bd9Sstevel@tonic-gate #if defined(_LP64)
1811*7c478bd9Sstevel@tonic-gate 	    ((hdr->spec[3] != ITM_SPEC_3_32_BIG_ENDIAN) &&
1812*7c478bd9Sstevel@tonic-gate 	    (hdr->spec[3] != ITM_SPEC_3_64_BIG_ENDIAN)) ||
1813*7c478bd9Sstevel@tonic-gate #else
1814*7c478bd9Sstevel@tonic-gate 	    (hdr->spec[3] != ITM_SPEC_3_32_BIG_ENDIAN) ||
1815*7c478bd9Sstevel@tonic-gate #endif
1816*7c478bd9Sstevel@tonic-gate #endif
1817*7c478bd9Sstevel@tonic-gate 	    (hdr->version[0] != ITM_VER_0) ||
1818*7c478bd9Sstevel@tonic-gate 	    (hdr->version[1] != ITM_VER_1) ||
1819*7c478bd9Sstevel@tonic-gate 	    (hdr->version[2] != ITM_VER_2) ||
1820*7c478bd9Sstevel@tonic-gate 	    (hdr->version[3] != ITM_VER_3) ||
1821*7c478bd9Sstevel@tonic-gate 	    (((size_t)(hdr->itm_size.itm_ptr)) != st.st_size)) {
1822*7c478bd9Sstevel@tonic-gate 		itm_ref_free(-1, ref, ref->name,
1823*7c478bd9Sstevel@tonic-gate 				ref->hdr, ref->len);
1824*7c478bd9Sstevel@tonic-gate 		errno = ELIBBAD;
1825*7c478bd9Sstevel@tonic-gate 		TRACE_MESSAGE('e', ("itm_ref_inc:error=%d\n", errno));
1826*7c478bd9Sstevel@tonic-gate 		return	(NULL);
1827*7c478bd9Sstevel@tonic-gate 	}
1828*7c478bd9Sstevel@tonic-gate 
1829*7c478bd9Sstevel@tonic-gate 	return	(ref);
1830*7c478bd9Sstevel@tonic-gate }
1831*7c478bd9Sstevel@tonic-gate 
1832*7c478bd9Sstevel@tonic-gate 
1833*7c478bd9Sstevel@tonic-gate static void
1834*7c478bd9Sstevel@tonic-gate itm_ref_dec(itm_ref_t	*ref)
1835*7c478bd9Sstevel@tonic-gate {
1836*7c478bd9Sstevel@tonic-gate 	(void) munmap((char *)(ref->hdr), ref->len);
1837*7c478bd9Sstevel@tonic-gate 	free(ref->name);
1838*7c478bd9Sstevel@tonic-gate 	free(ref);
1839*7c478bd9Sstevel@tonic-gate }
1840*7c478bd9Sstevel@tonic-gate 
1841*7c478bd9Sstevel@tonic-gate 
1842*7c478bd9Sstevel@tonic-gate static void
1843*7c478bd9Sstevel@tonic-gate op_init_default(icv_state_t	*ist)
1844*7c478bd9Sstevel@tonic-gate {
1845*7c478bd9Sstevel@tonic-gate 	ist->direc = ADDR(ist->itm_hdr->direc_init_tbl);
1846*7c478bd9Sstevel@tonic-gate 	regs_init(ist);
1847*7c478bd9Sstevel@tonic-gate }
1848*7c478bd9Sstevel@tonic-gate 
1849*7c478bd9Sstevel@tonic-gate 
1850*7c478bd9Sstevel@tonic-gate static void
1851*7c478bd9Sstevel@tonic-gate op_reset_default(icv_state_t	*ist)
1852*7c478bd9Sstevel@tonic-gate {
1853*7c478bd9Sstevel@tonic-gate 	ist->direc = ADDR(ist->itm_hdr->direc_init_tbl);
1854*7c478bd9Sstevel@tonic-gate 	regs_init(ist);
1855*7c478bd9Sstevel@tonic-gate }
1856*7c478bd9Sstevel@tonic-gate 
1857*7c478bd9Sstevel@tonic-gate 
1858*7c478bd9Sstevel@tonic-gate static void
1859*7c478bd9Sstevel@tonic-gate regs_init(icv_state_t	*ist)
1860*7c478bd9Sstevel@tonic-gate {
1861*7c478bd9Sstevel@tonic-gate 	if (0 < ist->itm_hdr->reg_num) {
1862*7c478bd9Sstevel@tonic-gate 		(void) memset(ist->regs, 0,
1863*7c478bd9Sstevel@tonic-gate 			(sizeof (itm_num_t)) * ist->itm_hdr->reg_num);
1864*7c478bd9Sstevel@tonic-gate 	}
1865*7c478bd9Sstevel@tonic-gate }
1866*7c478bd9Sstevel@tonic-gate 
1867*7c478bd9Sstevel@tonic-gate 
1868*7c478bd9Sstevel@tonic-gate #if defined(DEBUG)
1869*7c478bd9Sstevel@tonic-gate static void
1870*7c478bd9Sstevel@tonic-gate trace_init()
1871*7c478bd9Sstevel@tonic-gate {
1872*7c478bd9Sstevel@tonic-gate 	char	*env_val;
1873*7c478bd9Sstevel@tonic-gate 	char	*p;
1874*7c478bd9Sstevel@tonic-gate 
1875*7c478bd9Sstevel@tonic-gate 	env_val = getenv("ITM_INT_TRACE");
1876*7c478bd9Sstevel@tonic-gate 	if (NULL == env_val)
1877*7c478bd9Sstevel@tonic-gate 		return;
1878*7c478bd9Sstevel@tonic-gate 
1879*7c478bd9Sstevel@tonic-gate 	for (p = env_val; *p; p++) {
1880*7c478bd9Sstevel@tonic-gate 		trace_option[(*p) & 0x007f] = 1;
1881*7c478bd9Sstevel@tonic-gate 	}
1882*7c478bd9Sstevel@tonic-gate }
1883*7c478bd9Sstevel@tonic-gate 
1884*7c478bd9Sstevel@tonic-gate static void
1885*7c478bd9Sstevel@tonic-gate trace_message(char	*format, ...)
1886*7c478bd9Sstevel@tonic-gate {
1887*7c478bd9Sstevel@tonic-gate 	va_list	ap;
1888*7c478bd9Sstevel@tonic-gate 
1889*7c478bd9Sstevel@tonic-gate 	va_start(ap, format);
1890*7c478bd9Sstevel@tonic-gate 
1891*7c478bd9Sstevel@tonic-gate 	(void) vfprintf(stderr, format, ap);
1892*7c478bd9Sstevel@tonic-gate 
1893*7c478bd9Sstevel@tonic-gate 	va_end(ap);
1894*7c478bd9Sstevel@tonic-gate }
1895*7c478bd9Sstevel@tonic-gate #endif /* DEBUG */
1896