4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 #pragma ident "%Z%%M% %I% %E% SMI"
34 #include <sys/types.h>
52 static void trace_init(void);
53 static void trace_message(char *, ...);
55 static char trace_option
[128];
57 #define TRACE(c) (*(trace_option + (c & 0x007f)))
58 #define TRACE_MESSAGE(c, args) ((TRACE(c))? trace_message args: (void)0)
64 #define TRACE_MESSAGE(c, args)
70 * ITM reference information
72 typedef struct _itm_ref
{
73 char *name
; /* ITM file name */
74 itm_hdr_t
*hdr
; /* address of ITM */
75 size_t len
; /* length of ITM */
80 * struct _icv_state; to keep status
82 typedef struct _icv_state
{
83 struct _itm_ref
*itm
; /* reference to ITM */
84 itm_hdr_t
*itm_hdr
; /* address of ITM */
85 itm_tbl_hdr_t
*direc
; /* current direction */
86 itm_place_t default_action
; /* default action */
87 itm_num_t
*regs
; /* register */
88 itm_num_t reg_num
; /* number of register */
89 #if defined(OP_DEPTH_MAX)
90 int op_depth
; /* depth of operation */
91 #endif /* OP_DEPTH_MAX */
98 void * _icv_open(const char *);
99 void _icv_close(icv_state_t
*);
100 size_t _icv_iconv(icv_state_t
*, const unsigned char **,
101 size_t *, unsigned char **, size_t *);
103 static size_t map_i_f(itm_tbl_hdr_t
*,
104 const unsigned char **, size_t *,
105 unsigned char **, size_t *, long);
106 static size_t map_l_f(itm_tbl_hdr_t
*,
107 const unsigned char **, size_t *,
108 unsigned char **, size_t *, long);
109 static size_t map_h_l(itm_tbl_hdr_t
*,
110 const unsigned char **, size_t *,
111 unsigned char **, size_t *, long);
112 static size_t map_d_e_l(itm_tbl_hdr_t
*,
113 const unsigned char **, size_t *,
114 unsigned char **, size_t *, long);
115 static size_t eval_cond_tbl(icv_state_t
*, itm_place_t
,
116 const unsigned char **, size_t *,
117 size_t, itm_direc_t
*);
118 static size_t eval_op_tbl(icv_state_t
*, itm_place_t
,
119 const unsigned char **, size_t *,
120 unsigned char **, size_t *);
121 static size_t eval_op(icv_state_t
*, itm_place2_t
,
122 const unsigned char **, size_t *,
123 unsigned char **, size_t *);
125 static itm_num_t
eval_expr(icv_state_t
*, itm_place_t
,
126 size_t, const unsigned char *, size_t);
128 static void itm_ref_free(int, void *, void *, void *, size_t);
129 static itm_ref_t
*itm_ref_inc(const char *);
130 static void itm_ref_dec(itm_ref_t
*);
132 static void op_init_default(icv_state_t
*);
133 static void op_reset_default(icv_state_t
*);
134 static void regs_init(icv_state_t
*);
141 #define ADDR(place) ((void *)(((char *)(ist->itm_hdr)) +\
142 ((itm_place2_t)(place.itm_ptr))))
143 #define ADDR2(place2) ((void *)(((char *)(ist->itm_hdr)) +\
144 ((itm_place2_t)(place2))))
145 #define DADDR(n) (((n)->size <= (sizeof ((n)->place.itm_64d))) ? \
146 ((unsigned char *)(&((n)->place.itm_64d))) :\
147 ((unsigned char *)(ADDR((n)->place))))
149 #define REG(n) (*(ist->regs + (n)))
150 #define DISCARD(c) (((*inbuf) = (void *)((*inbuf) + (c))),\
151 ((*inbytesleft) -= (c)))
152 #define GET(c) ((c) = **inbuf, (*inbuf)++, (*inbytesleft)--)
153 #define PUT(c) (**outbuf = (c), (*outbuf)++, (*outbytesleft)--)
155 #define RETVALERR ((size_t)(-1))
156 #define RETVALDIR ((size_t)(-2))
157 #define RETVALBRK ((size_t)(-3))
158 #define RETVALRET ((size_t)(-4))
160 #define UPDATE_ARGS() (*inbuf = ip, \
161 *inbytesleft = ileft, \
163 *outbytesleft = oleft)
166 * Open; called from iconv_open()
169 _icv_open(const char *itm
)
182 * _icv_open() primaty task
184 itm_ref
= itm_ref_inc(itm
);
185 if (NULL
== itm_ref
) {
186 return ((void *)(-1));
189 if (NULL
== (ist
= malloc(sizeof (icv_state_t
)))) {
191 itm_ref_dec(itm_ref
);
197 ist
->itm_hdr
= ist
->itm
->hdr
;
198 ist
->reg_num
= ist
->itm
->hdr
->reg_num
;
201 ist
->direc
= ADDR(hdr
->direc_init_tbl
);
202 ist
->default_action
.itm_64d
= 0;
203 #if defined(OP_DEPTH_MAX)
205 #endif /* OP_DEPTH_MAX */
211 if (hdr
->itm_size
.itm_ptr
<= hdr
->direc_init_tbl
.itm_ptr
) {
214 return ((void *)(-1));
218 /* allocate register region */
219 if (hdr
->reg_num
<= 0) {
222 ist
->regs
= malloc((sizeof (itm_num_t
)) * hdr
->reg_num
);
223 if (NULL
== ist
->regs
) {
227 return ((void *)(-1));
229 (void) memset(ist
->regs
, 0,
230 (sizeof (itm_num_t
)) * hdr
->reg_num
);
234 /* evaluate init operation */
235 if (0 != ist
->itm_hdr
->op_init_tbl
.itm_ptr
) {
236 const unsigned char *ip
= NULL
;
238 unsigned char *op
= NULL
;
240 (void) eval_op_tbl(ist
, ist
->itm_hdr
->op_init_tbl
, &ip
,
241 &ileft
, &op
, &oleft
);
243 op_init_default(ist
);
251 * Close; called from iconv_close
254 _icv_close(icv_state_t
*ist
)
260 itm_ref_dec(ist
->itm
);
267 * Actual conversion; called from iconv()
272 const unsigned char **inbuf
,
274 unsigned char **outbuf
,
275 size_t *outbytesleft
)
280 const unsigned char *ip
;
286 TRACE_MESSAGE('e', ("_icv_iconv: error=%d\n", errno
));
287 return ((size_t)(-1));
293 if (NULL
== inbytesleft
) {
295 inbytesleft
= &ileft
;
302 TRACE_MESSAGE('i', ("_icv_iconv(inbuf=%p inbytesleft=%ld "
303 "outbuf=%p outbytesleft=%ld)\n", (NULL
== inbuf
) ? 0 : *inbuf
,
304 (NULL
== inbytesleft
) ? 0 : *inbytesleft
,
305 (NULL
== outbuf
) ? 0 : *outbuf
,
306 (NULL
== outbytesleft
) ? 0 : *outbytesleft
));
309 * If (NULL == inbuf || NULL == *inbuf) then this conversion is
310 * placed into initial state.
312 if ((NULL
== inbuf
) || (NULL
== *inbuf
)) {
313 if (0 != hdr
->op_reset_tbl
.itm_ptr
) {
314 ist
->direc
= ADDR(hdr
->direc_init_tbl
);
315 retval
= eval_op_tbl(ist
, hdr
->op_reset_tbl
, inbuf
,
316 inbytesleft
, outbuf
, outbytesleft
);
317 if ((size_t)(-1) == retval
) {
321 op_reset_default(ist
);
323 return ((size_t)(0));
326 if (ITM_TBL_MAP_INDEX_FIXED_1_1
== ist
->direc
->type
) {
327 itm_map_idx_fix_hdr_t
*map_hdr
;
329 const unsigned char *ip
;
334 map_hdr
= (itm_map_idx_fix_hdr_t
*)(ist
->direc
+ 1);
335 map
= (char *)(map_hdr
+ 1);
337 if (1 == map_hdr
->default_error
) {
338 retval
= map_i_f(ist
->direc
, inbuf
, inbytesleft
,
339 outbuf
, outbytesleft
, 0);
344 ileft
= *inbytesleft
;
346 oleft
= *outbytesleft
;
352 TRACE_MESSAGE('e', ("_icv_iconv: error=%d\n",
356 *(op
++) = *(map
+ *(ip
++));
363 } else if (ITM_TBL_MAP_INDEX_FIXED
== ist
->direc
->type
) {
364 retval
= map_i_f(ist
->direc
, inbuf
, inbytesleft
,
365 outbuf
, outbytesleft
, 0);
367 } else if (ITM_TBL_MAP_HASH
== ist
->direc
->type
) {
368 retval
= map_h_l(ist
->direc
, inbuf
, inbytesleft
,
369 outbuf
, outbytesleft
, 0);
371 } else if (ITM_TBL_MAP_DENSE_ENC
== ist
->direc
->type
) {
372 retval
= map_d_e_l(ist
->direc
, inbuf
, inbytesleft
,
373 outbuf
, outbytesleft
, 0);
375 } else if (ITM_TBL_MAP_LOOKUP
== ist
->direc
->type
) {
376 retval
= map_l_f(ist
->direc
, inbuf
, inbytesleft
,
377 outbuf
, outbytesleft
, 0);
381 #if defined(OP_DEPTH_MAX)
383 #endif /* OP_DEPTH_MAX */
387 * Main loop; basically 1 loop per 1 output character
390 while (0 < *inbytesleft
) {
391 itm_tbl_hdr_t
*direc_hdr
;
395 direc_hdr
= ist
->direc
;
396 direc
= (itm_direc_t
*)(ist
->direc
+ 1);
397 for (i
= 0; /* NULL */; i
++, direc
++) {
398 if (i
>= direc_hdr
->number
) {
399 if (0 == ist
->default_action
.itm_ptr
) {
402 ("_icv_iconv:error=%d\n", errno
));
403 return ((size_t)(-1));
408 action
= ist
->default_action
;
409 type
= ((itm_tbl_hdr_t
*)(ADDR(action
)))->type
;
411 ("escape seq (default action=%6p, "
412 "type=%ld) executing\n",
413 action
.itm_ptr
, type
));
414 } else if (0 != direc
->condition
.itm_ptr
) {
415 retval
= eval_cond_tbl(ist
, direc
->condition
,
416 inbuf
, inbytesleft
, *outbytesleft
, direc
);
417 if ((size_t)(0) == retval
) {
419 } else if ((size_t)(-1) == retval
) {
421 } else if ((size_t)(2) == retval
) {
422 goto retry_cond_eval
;
424 action
= direc
->action
;
425 type
= ((itm_tbl_hdr_t
*)(ADDR(action
)))->type
;
427 action
= direc
->action
;
428 type
= ((itm_tbl_hdr_t
*)(ADDR(action
)))->type
;
432 ("inbytesleft=%ld; type=%ld:action=%p\n",
433 *inbytesleft
, type
, action
.itm_ptr
));
434 switch (ITM_TBL_MASK
& type
) {
436 retval
= eval_op_tbl(ist
, action
,
437 inbuf
, inbytesleft
, outbuf
, outbytesleft
);
438 if ((size_t)(-1) == retval
) {
443 ist
->direc
= ADDR(action
);
447 case ITM_TBL_MAP_INDEX_FIXED_1_1
:
448 case ITM_TBL_MAP_INDEX_FIXED
:
449 retval
= map_i_f(ADDR(action
),
451 outbuf
, outbytesleft
, 1);
453 case ITM_TBL_MAP_HASH
:
454 retval
= map_h_l(ADDR(action
),
456 outbuf
, outbytesleft
, 1);
458 case ITM_TBL_MAP_DENSE_ENC
:
459 retval
= map_d_e_l(ADDR(action
),
461 outbuf
, outbytesleft
, 1);
463 case ITM_TBL_MAP_LOOKUP
:
464 retval
= map_l_f(ADDR(action
),
466 outbuf
, outbytesleft
, 1);
471 ("_icv_iconv:error=%d\n", errno
));
472 return ((size_t)(-1));
475 if ((size_t)(-1) == retval
) {
482 ("_icv_iconv:error=%d\n", errno
));
483 return ((size_t)(-1));
498 itm_tbl_hdr_t
*tbl_hdr
,
499 const unsigned char **inbuf
,
501 unsigned char **outbuf
,
502 size_t *outbytesleft
,
505 itm_map_idx_fix_hdr_t
*map_hdr
;
509 const unsigned char *p
;
511 TRACE_MESSAGE('i', ("map_i_f\n"));
513 map_hdr
= (itm_map_idx_fix_hdr_t
*)(tbl_hdr
+ 1);
516 if (*inbytesleft
< map_hdr
->source_len
) {
518 TRACE_MESSAGE('e', ("map_i_f:error=%d\n", errno
));
519 return ((size_t)(-1));
523 for (i
= 0; i
< map_hdr
->source_len
; i
++) {
528 if (((j
< map_hdr
->start
.itm_ptr
) ||
529 (map_hdr
->end
.itm_ptr
< j
)) &&
530 (0 < map_hdr
->default_error
)) {
532 (*inbuf
) = (void*) ((*inbuf
) - map_hdr
->source_len
);
533 (*inbytesleft
) += map_hdr
->source_len
;
534 TRACE_MESSAGE('e', ("map_i_f:error=%d\n", errno
));
535 return ((size_t)(-1));
538 if (*outbytesleft
< map_hdr
->result_len
) {
540 (*inbuf
) = (void *)((*inbuf
) - map_hdr
->source_len
);
541 (*inbytesleft
) += map_hdr
->source_len
;
542 TRACE_MESSAGE('e', ("map_i_f:error=%d\n", errno
));
543 return ((size_t)(-1));
546 if ((j
< map_hdr
->start
.itm_ptr
) ||
547 (map_hdr
->end
.itm_ptr
< j
)) {
548 if (0 == map_hdr
->default_error
) {
549 p
= (((unsigned char *)(map_hdr
+ 1)) +
550 (map_hdr
->result_len
* (tbl_hdr
->number
)));
551 for (i
= 0; i
< map_hdr
->result_len
; i
++) {
555 p
= ((*inbuf
) - map_hdr
->source_len
);
556 for (i
= 0; i
< map_hdr
->source_len
; i
++) {
562 map_error
= (((char *)(map_hdr
+ 1)) +
563 (map_hdr
->result_len
* (tbl_hdr
->number
)) +
564 (j
- map_hdr
->start
.itm_ptr
));
565 if (0 == map_hdr
->default_error
) {
567 (map_error
+ map_hdr
->result_len
);
569 if (((1 == map_hdr
->default_error
) ||
570 (0 < map_hdr
->error_num
)) &&
571 (0 != *(map_error
))) {
574 ((*inbuf
) - map_hdr
->source_len
);
575 (*inbytesleft
) += map_hdr
->source_len
;
577 ("map_i_f:error=%d\n", errno
));
578 return ((size_t)(-1));
580 p
= (((unsigned char *)(map_hdr
+ 1)) +
581 (map_hdr
->result_len
*
582 (j
- map_hdr
->start
.itm_ptr
)));
583 for (i
= 0; i
< map_hdr
->result_len
; i
++) {
587 } while ((0 < *inbytesleft
) && (0 == once
));
598 itm_tbl_hdr_t
*tbl_hdr
,
599 const unsigned char **inbuf
,
601 unsigned char **outbuf
,
602 size_t *outbytesleft
,
605 itm_map_lookup_hdr_t
*map_hdr
;
608 const unsigned char *p
;
613 itm_size_t pair_size
;
615 TRACE_MESSAGE('i', ("map_l_f\n"));
617 map_hdr
= (itm_map_lookup_hdr_t
*)(tbl_hdr
+ 1);
618 map
= (unsigned char *)(map_hdr
+ 1);
619 pair_size
= map_hdr
->source_len
+ 1 + map_hdr
->result_len
;
622 if (*inbytesleft
< map_hdr
->source_len
) {
624 TRACE_MESSAGE('e', ("map_l_f:error=%d\n", errno
));
625 return ((size_t)(-1));
628 for (low
= 0, high
= tbl_hdr
->number
; low
< high
; ) {
629 mid
= (low
+ high
) / 2;
630 p
= map
+ (pair_size
* mid
);
631 for (i
= 0, result
= 0; i
< map_hdr
->source_len
;
633 if (*(unsigned char *)(*inbuf
+ i
) < *p
) {
637 if (*p
< *(unsigned char *)(*inbuf
+ i
)) {
644 } else if (0 < result
) {
646 } else { /* 0 == result */
652 if (map_hdr
->default_error
< 0) {
654 } else if (0 == map_hdr
->default_error
) {
655 p
= map
+ (pair_size
* tbl_hdr
->number
) +
656 map_hdr
->source_len
+ 1;
657 } else if (0 < map_hdr
->default_error
) {
659 TRACE_MESSAGE('e', ("map_l_f:error=%d\n",
661 return ((size_t)(-1));
666 TRACE_MESSAGE('e', ("map_l_f:error=%d\n",
668 return ((size_t)(-1));
673 if (*outbytesleft
< map_hdr
->result_len
) {
675 TRACE_MESSAGE('e', ("map_l_f:error=%d\n", errno
));
676 return ((size_t)(-1));
678 DISCARD(map_hdr
->source_len
);
680 for (i
= 0; i
< map_hdr
->result_len
; i
++) {
683 } while ((0 < *inbytesleft
) && (0 == once
));
685 return ((size_t)(0));
694 itm_tbl_hdr_t
*tbl_hdr
,
695 const unsigned char **inbuf
,
697 unsigned char **outbuf
,
698 size_t *outbytesleft
,
701 itm_map_hash_hdr_t
*map_hdr
;
703 unsigned char *map_error
;
704 unsigned char *map_hash
;
705 unsigned char *map_of
;
706 const unsigned char *p
;
707 const unsigned char *q
;
712 itm_size_t pair_size
;
713 itm_size_t hash_value
;
714 itm_size_t source_len
;
715 itm_size_t result_len
;
717 TRACE_MESSAGE('i', ("map_hash\n"));
719 map_hdr
= (itm_map_hash_hdr_t
*)(tbl_hdr
+ 1);
720 map_error
= (unsigned char *)(map_hdr
+ 1);
721 map_hash
= (map_error
+ map_hdr
->hash_tbl_num
);
722 map_of
= map_hash
+ map_hdr
->hash_tbl_size
;
723 pair_size
= map_hdr
->source_len
+ 1 + map_hdr
->result_len
;
724 source_len
= map_hdr
->source_len
;
725 result_len
= map_hdr
->result_len
;
728 if (*inbytesleft
< source_len
) {
730 TRACE_MESSAGE('e', ("map_h_l:error=%d\n", errno
));
731 return ((size_t)(-1));
736 hash_value
= hash((const char *)(q
), source_len
,
737 map_hdr
->hash_tbl_num
);
738 p
= map_hash
+ (pair_size
* hash_value
);
739 if (1 == *(map_error
+ hash_value
)) {
740 for (i
= 0, result
= 0; i
< source_len
; i
++) {
741 if (*(q
+ i
) != *(p
++)) {
747 ("(h=%d): find pair without conflict\n",
749 } else if (0 == *(map_error
+ hash_value
)) {
750 TRACE_MESSAGE('G', ("(h=%d): No Pair\n", hash_value
));
752 } else /* if (0 < *(map_error + hash_value)) */ {
753 for (i
= 0, result
= 0; i
< source_len
; i
++) {
754 if (*(q
+ i
) != *(p
++)) {
760 for (low
= 0, high
= map_hdr
->hash_of_num
;
761 low
< high
; /* NOP */) {
762 mid
= (low
+ high
) / 2;
763 p
= map_of
+ (pair_size
* mid
);
764 for (i
= 0, result
= 0;
778 } else if (0 < result
) {
780 } else { /* 0 == result */
781 TRACE_MESSAGE('G', ("(h=%d): "
782 "find data on out of "
783 "hashtable with CONFLICT\n",
791 if (map_hdr
->default_error
< 0) {
793 } else if (0 == map_hdr
->default_error
) {
794 p
= map_of
+ map_hdr
->hash_of_size
;
795 } else if (0 < map_hdr
->default_error
) {
796 TRACE_MESSAGE('G', ("(h=%d): NO PAIR\n",
800 ("map_h_l:error=%d\n", errno
));
801 return ((size_t)(-1));
806 TRACE_MESSAGE('G', (" : error pair\n"));
807 TRACE_MESSAGE('e', ("map_l_f:error\n", errno
));
808 return ((size_t)(-1));
813 if (*outbytesleft
< result_len
) {
815 TRACE_MESSAGE('e', ("map_h_l:error=%d\n", errno
));
816 return ((size_t)(-1));
820 for (i
= 0; i
< result_len
; i
++) {
823 } while ((0 < *inbytesleft
) && (0 == once
));
825 return ((size_t)(0));
830 * map-dense_encoding-lookup
834 itm_tbl_hdr_t
*tbl_hdr
,
835 const unsigned char **inbuf
,
837 unsigned char **outbuf
,
838 size_t *outbytesleft
,
841 itm_map_dense_enc_hdr_t
*map_hdr
;
844 const unsigned char *p
;
845 unsigned char *map_ptr
;
846 unsigned char *map_error
;
847 unsigned char *byte_seq_min
;
848 unsigned char *byte_seq_max
;
850 TRACE_MESSAGE('i', ("map_d_e_l\n"));
852 map_hdr
= (itm_map_dense_enc_hdr_t
*)(tbl_hdr
+ 1);
853 map_ptr
= ((unsigned char *)(map_hdr
+ 1) + map_hdr
->source_len
+
854 map_hdr
->source_len
);
855 map_error
= (map_ptr
+ (tbl_hdr
->number
* map_hdr
->result_len
));
856 if (0 == map_hdr
->default_error
) {
857 map_error
= (void *)(map_error
+ map_hdr
->result_len
);
859 byte_seq_min
= (unsigned char *)(map_hdr
+ 1);
860 byte_seq_max
= byte_seq_min
+ map_hdr
->source_len
;
863 if (*inbytesleft
< map_hdr
->source_len
) {
865 TRACE_MESSAGE('e', ("map_d_e_l:error=%d\n", errno
));
866 return ((size_t)(-1));
869 j
= hash_dense_encoding(*inbuf
, map_hdr
->source_len
,
870 byte_seq_min
, byte_seq_max
);
872 if (((j
< 0) || (tbl_hdr
->number
< j
)) &&
873 (0 < map_hdr
->default_error
)) {
875 TRACE_MESSAGE('e', ("map_d_e_l:error=%d\n", errno
));
876 return ((size_t)(-1));
879 if (*outbytesleft
< map_hdr
->result_len
) {
881 TRACE_MESSAGE('e', ("map_d_e_l:error=%d\n", errno
));
882 return ((size_t)(-1));
885 if ((j
< 0) || (tbl_hdr
->number
< j
)) {
886 if (0 == map_hdr
->default_error
) {
887 p
= (map_ptr
+ (tbl_hdr
->number
*
888 map_hdr
->result_len
));
889 for (i
= 0; i
< map_hdr
->result_len
; i
++) {
894 for (i
= 0; i
< map_hdr
->source_len
; i
++) {
899 if ((1 == map_hdr
->default_error
) ||
900 (0 < map_hdr
->error_num
)) {
901 if (0 != *(map_error
+ j
)) {
904 ("map_d_e_l:error=%d\n", errno
));
905 return ((size_t)(-1));
908 p
= (map_ptr
+ (map_hdr
->result_len
* j
));
909 for (i
= 0; i
< map_hdr
->result_len
; i
++) {
913 DISCARD(map_hdr
->source_len
);
914 } while ((0 < *inbytesleft
) && (0 == once
));
916 return ((size_t)(0));
922 * Evaluate condition table
928 itm_place_t cond_place
,
929 const unsigned char **inbuf
,
935 itm_tbl_hdr_t
*cond_hdr
;
942 itm_range_hdr_t
*rtsh
;
945 itm_escapeseq_hdr_t
*eh
;
947 const unsigned char *ip
;
952 ileft
= *inbytesleft
;
953 cond_hdr
= ADDR(cond_place
);
954 cond
= (itm_cond_t
*)(cond_hdr
+ 1);
955 for (i
= 0; i
< cond_hdr
->number
; i
++, cond
++) {
956 switch (cond
->type
) {
957 case ITM_COND_BETWEEN
:
958 rth
= ADDR(cond
->operand
.place
);
959 rtsh
= (itm_range_hdr_t
*)(rth
+ 1);
960 if (ileft
< rtsh
->len
) {
962 TRACE_MESSAGE('e', ("eval_cond_tbl:error=%d\n",
964 retval
= ((size_t)(-1));
965 goto eval_cond_return
;
967 p
= (unsigned char *)(rtsh
+ 1);
969 for (j
= 0; j
< rth
->number
;
970 j
++, p
= (void *)(p
+ (2 * rtsh
->len
))) {
972 for (k
= 0; k
< rtsh
->len
; k
++) {
973 if ((*(ip
+ k
) < *(p
+ k
)) ||
974 (*(p
+ rtsh
->len
+ k
) <
986 ("out of between (%p) len= rtsh=%ld\n",
988 goto eval_cond_return
;
990 break; /* continue */
991 case ITM_COND_ESCAPESEQ
:
993 * if escape sequence occur,
994 * change ist->default_action and return 2.
998 eth
= ADDR(cond
->operand
.place
);
999 eh
= (itm_escapeseq_hdr_t
*)(eth
+ 1);
1000 if (NULL
== ist
->default_action
.itm_ptr
) {
1001 ist
->default_action
= direc
->action
;
1003 ("escape seq (default action=%6p, "
1005 direc
->action
.itm_ptr
, ((itm_tbl_hdr_t
*)
1006 (ADDR(direc
->action
)))->type
));
1009 if (*inbytesleft
< eh
->len_min
) {
1012 for (j
= 0, d
= (itm_data_t
*)(eh
+ 1);
1015 if (*inbytesleft
< d
->size
) {
1018 if (0 == memcmp(*inbuf
, DADDR(d
), d
->size
)) {
1020 ("escape seq: discard=%ld chars\n",
1023 ("escape seq (default "
1024 "action=%6p, type=%ld) set\n",
1025 direc
->action
.itm_ptr
,
1027 (ADDR(direc
->action
)))->type
));
1028 ist
->default_action
= direc
->action
;
1031 goto eval_cond_return
;
1035 goto eval_cond_return
;
1037 break; /* continue */
1039 retval
= eval_expr(ist
, cond
->operand
.place
,
1040 *inbytesleft
, ip
, outbytesleft
);
1042 goto eval_cond_return
;
1046 break; /* continue */
1048 TRACE_MESSAGE('e', ("eval_cond_tbl:illegal cond=%d\n",
1050 retval
= (size_t)-1;
1051 goto eval_cond_return
;
1060 * Evaluate operation table
1066 itm_place_t op_tbl_place
,
1067 const unsigned char **inbuf
,
1068 size_t *inbytesleft
,
1069 unsigned char **outbuf
,
1070 size_t *outbytesleft
)
1072 itm_tbl_hdr_t
*op_hdr
;
1073 itm_op_t
*operation
;
1074 itm_place2_t op_place
;
1080 #if defined(OP_DEPTH_MAX)
1081 if (OP_DEPTH_MAX
<= ist
->op_depth
) {
1083 TRACE_MESSAGE('e', ("eval_op_tbl:error=%d\n", errno
));
1087 #endif /* OP_DEPTH_MAX */
1089 op_hdr
= ADDR(op_tbl_place
);
1090 operation
= (itm_op_t
*)(op_hdr
+ 1);
1092 op_place
= op_tbl_place
.itm_ptr
+ (sizeof (itm_tbl_hdr_t
));
1093 for (i
= 0; i
< op_hdr
->number
; i
++, operation
++,
1094 op_place
+= (sizeof (itm_op_t
))) {
1095 TRACE_MESSAGE('O', ("eval_op_tbl: %ld %p\n", i
, op_place
));
1096 retval
= eval_op(ist
, op_place
, inbuf
, inbytesleft
,
1097 outbuf
, outbytesleft
);
1098 if (((long)(retval
)) < 0) {
1099 #if defined(OP_DEPTH_MAX)
1101 #endif /* OP_DEPTH_MAX */
1106 if (0 == op_hdr
->name
.itm_ptr
) {
1114 #if defined(OP_DEPTH_MAX)
1116 #endif /* OP_DEPTH_MAX */
1122 * Evaluate single operation
1128 itm_place2_t op_place
,
1129 const unsigned char **inbuf
,
1130 size_t *inbytesleft
,
1131 unsigned char **outbuf
,
1132 size_t *outbytesleft
)
1136 itm_op_t
*operation
;
1146 #define EVAL_EXPR(n) \
1147 (expr0 = ADDR(operation->data.operand[(n)]), \
1148 (itm_num_t)((expr0->type == ITM_EXPR_INT) ? \
1149 expr0->data.itm_exnum : \
1150 ((expr0->type == ITM_EXPR_REG) ? \
1151 REG(expr0->data.itm_exnum) : \
1152 ((expr0->type == ITM_EXPR_IN_VECTOR_D) ? \
1153 ((expr0->data.itm_exnum < 0) ? \
1154 (((-1) == expr0->data.itm_exnum) ? *inbytesleft : 0) : \
1155 ((expr0->data.itm_exnum < *inbytesleft) ? \
1156 (*(uchar_t *)(*inbuf + expr0->data.itm_exnum)) : 0)): \
1157 eval_expr(ist, operation->data.operand[(n)], \
1158 *inbytesleft, *inbuf, *outbytesleft)))))
1162 operation
= (itm_op_t
*)ADDR2(op_place
);
1164 switch (operation
->type
) {
1166 num
= eval_expr(ist
, operation
->data
.operand
[0],
1167 *inbytesleft
, *inbuf
, *outbytesleft
);
1168 TRACE_MESSAGE('o', ("ITM_OP_EXPR: %ld\n", retval
));
1171 num
= eval_expr(ist
, operation
->data
.operand
[0],
1172 *inbytesleft
, *inbuf
, *outbytesleft
);
1174 TRACE_MESSAGE('o', ("ITM_OP_ERROR: %ld\n", num
));
1175 retval
= (size_t)(-1);
1177 case ITM_OP_ERROR_D
:
1178 errno
= (int)operation
->data
.itm_opnum
;
1179 TRACE_MESSAGE('o', ("ITM_OP_ERROR_D: %d\n", errno
));
1180 retval
= (size_t)(-1);
1183 expr
= ADDR(operation
->data
.operand
[0]);
1184 if ((*outbytesleft
) == 0) {
1186 TRACE_MESSAGE('e', ("eval_op:error=%d\n", errno
));
1187 return ((size_t)(-1));
1189 c
= eval_expr(ist
, operation
->data
.operand
[0],
1190 *inbytesleft
, *inbuf
, *outbytesleft
);
1192 retval
= *inbytesleft
;
1193 TRACE_MESSAGE('o', ("ITM_OP_OUT: %ld %ld\n", c
, *inbytesleft
));
1196 expr
= ADDR(operation
->data
.operand
[0]);
1197 if ((*outbytesleft
) == 0) {
1199 TRACE_MESSAGE('e', ("eval_op:error=%d\n", errno
));
1200 return ((size_t)(-1));
1202 PUT(0xff & (expr
->data
.itm_exnum
));
1205 expr
= ADDR(operation
->data
.operand
[0]);
1206 if ((*outbytesleft
) == 0) {
1208 TRACE_MESSAGE('e', ("eval_op:error=%d\n", errno
));
1209 return ((size_t)(-1));
1211 z
= expr
->data
.value
.size
;
1212 if (*outbytesleft
< z
) {
1214 TRACE_MESSAGE('e', ("eval_op:error=%d\n", errno
));
1215 return ((size_t)(-1));
1217 p
= DADDR(&(expr
->data
.value
));
1218 for (; 0 < z
; --z
, p
++) {
1223 expr
= ADDR(operation
->data
.operand
[0]);
1224 if ((*outbytesleft
) == 0) {
1226 TRACE_MESSAGE('e', ("eval_op:error=%d\n", errno
));
1227 return ((size_t)(-1));
1229 c
= REG(expr
->data
.itm_exnum
);
1232 case ITM_OP_OUT_INVD
:
1233 expr
= ADDR(operation
->data
.operand
[0]);
1234 if ((*outbytesleft
) == 0) {
1236 TRACE_MESSAGE('e', ("eval_op:error=%d\n", errno
));
1237 return ((size_t)(-1));
1239 z
= (((0 <= expr
->data
.itm_exnum
) &&
1240 (expr
->data
.itm_exnum
< *inbytesleft
)) ?
1241 (*((unsigned char *)(*inbuf
+ expr
->data
.itm_exnum
))) :
1242 (((-1) == expr
->data
.itm_exnum
) ? *inbytesleft
: 0));
1245 case ITM_OP_DISCARD
:
1246 #if defined(EVAL_EXPR)
1248 #else /* !defined(EVAL_EXPR) */
1249 num
= eval_expr(ist
, operation
->data
.operand
[0],
1250 *inbytesleft
, *inbuf
, *outbytesleft
);
1251 #endif /* defined(EVAL_EXPR) */
1252 TRACE_MESSAGE('o', ("ITM_OP_DISCARD: %ld\n", num
));
1253 #if defined(DISCARD)
1254 DISCARD((num
<= *inbytesleft
) ? ((ulong_t
)num
) : *inbytesleft
);
1255 #else /* defined(DISCARD) */
1256 for (num
= ((num
<= *inbytesleft
) ? num
: *inbytesleft
);
1260 #endif /* defined(DISCARD) */
1262 case ITM_OP_DISCARD_D
:
1263 num
= operation
->data
.itm_opnum
;
1264 TRACE_MESSAGE('o', ("ITM_OP_DISCARD_D: %ld\n", num
));
1265 #if defined(DISCARD)
1266 DISCARD((num
<= *inbytesleft
) ? num
: *inbytesleft
);
1267 #else /* defined(DISCARD) */
1268 for (num
= ((num
<= *inbytesleft
) ? num
: *inbytesleft
);
1272 #endif /* defined(DISCARD) */
1275 c
= eval_expr(ist
, operation
->data
.operand
[0],
1276 *inbytesleft
, *inbuf
, *outbytesleft
);
1277 TRACE_MESSAGE('o', ("ITM_OP_IF: %ld\n", c
));
1279 retval
= eval_op_tbl(ist
, operation
->data
.operand
[1],
1280 inbuf
, inbytesleft
, outbuf
, outbytesleft
);
1283 case ITM_OP_IF_ELSE
:
1284 c
= eval_expr(ist
, operation
->data
.operand
[0],
1285 *inbytesleft
, *inbuf
, *outbytesleft
);
1286 TRACE_MESSAGE('o', ("ITM_OP_IF_ELSE: %ld\n", c
));
1288 retval
= eval_op_tbl(ist
, operation
->data
.operand
[1],
1289 inbuf
, inbytesleft
, outbuf
, outbytesleft
);
1291 retval
= eval_op_tbl(ist
, operation
->data
.operand
[2],
1292 inbuf
, inbytesleft
, outbuf
, outbytesleft
);
1295 case ITM_OP_DIRECTION
:
1296 TRACE_MESSAGE('o', ("ITM_OP_DIRECTION: %p\n",
1297 operation
->data
.operand
[0].itm_ptr
));
1298 ist
->direc
= ADDR(operation
->data
.operand
[0]);
1299 return ((size_t)(-2));
1301 TRACE_MESSAGE('o', ("ITM_OP_MAP: %p\n",
1302 operation
->data
.operand
[0].itm_ptr
));
1304 if (0 != operation
->data
.operand
[1].itm_ptr
) {
1305 #if defined(EVAL_EXPR)
1307 #else /* !defined(EVAL_EXPR) */
1308 i
= eval_expr(ist
, operation
->data
.operand
[1],
1309 *inbytesleft
, *inbuf
, *outbytesleft
);
1310 #endif /* defined(EVAL_EXPR) */
1311 (*inbytesleft
) -= i
;
1316 * Based on what is the maptype, we call the corresponding
1319 h
= ADDR(operation
->data
.operand
[0]);
1322 case ITM_TBL_MAP_INDEX_FIXED
:
1323 case ITM_TBL_MAP_INDEX_FIXED_1_1
:
1324 retval
= map_i_f(h
, inbuf
, inbytesleft
,
1325 outbuf
, outbytesleft
, 1);
1327 case ITM_TBL_MAP_HASH
:
1328 retval
= map_h_l(h
, inbuf
, inbytesleft
,
1329 outbuf
, outbytesleft
, 1);
1331 case ITM_TBL_MAP_DENSE_ENC
:
1332 retval
= map_d_e_l(h
, inbuf
, inbytesleft
,
1333 outbuf
, outbytesleft
, 1);
1335 case ITM_TBL_MAP_LOOKUP
:
1336 retval
= map_l_f(h
, inbuf
, inbytesleft
,
1337 outbuf
, outbytesleft
, 1);
1341 * This should not be possible, but in case we
1342 * have an incorrect maptype, don't fall back to
1343 * map_i_f(). Instead, because it is an error, return
1344 * an error. See CR 6622765.
1347 TRACE_MESSAGE('e', ("eval_op:error=%d\n", errno
));
1348 retval
= (size_t)-1;
1352 if ((size_t)(-1) == retval
) {
1353 (*outbytesleft
) += i
;
1357 case ITM_OP_OPERATION
:
1358 TRACE_MESSAGE('o', ("ITM_OP_OPERATION: %p\n",
1359 operation
->data
.operand
[0].itm_ptr
));
1360 retval
= eval_op_tbl(ist
, operation
->data
.operand
[0],
1361 inbuf
, inbytesleft
, outbuf
, outbytesleft
);
1365 TRACE_MESSAGE('o', ("ITM_OP_INIT: %p\n",
1366 ist
->itm_hdr
->op_init_tbl
));
1367 if (0 != ist
->itm_hdr
->op_init_tbl
.itm_ptr
) {
1368 retval
= eval_op_tbl(ist
, ist
->itm_hdr
->op_init_tbl
,
1369 inbuf
, inbytesleft
, outbuf
, outbytesleft
);
1371 op_init_default(ist
);
1372 retval
= (size_t)-2;
1376 TRACE_MESSAGE('o', ("ITM_OP_RESET: %p\n",
1377 ist
->itm_hdr
->op_reset_tbl
));
1378 if (0 != ist
->itm_hdr
->op_reset_tbl
.itm_ptr
) {
1379 retval
= eval_op_tbl(ist
, ist
->itm_hdr
->op_reset_tbl
,
1380 inbuf
, inbytesleft
, outbuf
, outbytesleft
);
1382 op_reset_default(ist
);
1383 retval
= (size_t)-2;
1387 TRACE_MESSAGE('o', ("ITM_OP_BREAK\n"));
1390 TRACE_MESSAGE('o', ("ITM_OP_RETURN\n"));
1392 case ITM_OP_PRINTCHR
:
1393 c
= eval_expr(ist
, operation
->data
.operand
[0], *inbytesleft
,
1394 *inbuf
, *outbytesleft
);
1395 (void) fputc((uchar_t
)c
, stderr
);
1396 TRACE_MESSAGE('o', ("ITM_OP_PRINTCHR: %ld %ld\n",
1399 case ITM_OP_PRINTHD
:
1400 c
= eval_expr(ist
, operation
->data
.operand
[0], *inbytesleft
,
1401 *inbuf
, *outbytesleft
);
1402 (void) fprintf(stderr
, "%lx", c
);
1403 TRACE_MESSAGE('o', ("ITM_OP_PRINTHD: %ld %ld\n",
1406 case ITM_OP_PRINTINT
:
1407 c
= eval_expr(ist
, operation
->data
.operand
[0], *inbytesleft
,
1408 *inbuf
, *outbytesleft
);
1409 (void) fprintf(stderr
, "%ld", c
);
1410 TRACE_MESSAGE('o', ("ITM_OP_PRINTINT: %ld %ld\n",
1413 default: /* never */
1415 TRACE_MESSAGE('e', ("eval_op:error=%d\n", errno
));
1416 return (size_t)(-1);
1425 * Evaluate expression
1430 itm_place_t expr_place
,
1432 const unsigned char *inbuf
,
1433 size_t outbytesleft
)
1436 itm_expr_t
*expr_op
;
1444 #define EVAL_EXPR_E(n) (eval_expr(ist, expr->data.operand[(n)], \
1445 inbytesleft, inbuf, outbytesleft))
1446 #define EVAL_EXPR_D(n) ((itm_num_t)(expr->data.operand[(n)].itm_ptr))
1447 #define EVAL_EXPR_R(n) (REG((itm_num_t)(expr->data.operand[(n)].itm_ptr)))
1448 #define EVAL_EXPR_INVD(n) \
1449 ((num0 ## n) = ((itm_num_t)(expr->data.operand[(n)].itm_ptr)), \
1450 ((num0 ## n) < 0) ? \
1451 (((-1) == (num0 ## n)) ? inbytesleft : 0) : \
1452 (((num0 ## n) < inbytesleft) ? \
1453 (*(unsigned char *)(inbuf + (num0 ## n))) : 0))
1454 #define EVAL_EXPR(n) \
1455 (expr0 = ADDR(expr->data.operand[(n)]), \
1456 (itm_num_t)((expr0->type == ITM_EXPR_INT) ? \
1457 expr0->data.itm_exnum : \
1458 ((expr0->type == ITM_EXPR_REG) ? \
1459 REG(expr0->data.itm_exnum) : \
1460 ((expr0->type == ITM_EXPR_IN_VECTOR_D) ? \
1461 ((expr0->data.itm_exnum < 0) ? \
1462 (((-1) == expr0->data.itm_exnum) ? inbytesleft : 0) : \
1463 ((expr0->data.itm_exnum < inbytesleft) ? \
1464 (*(uchar_t *)(inbuf + expr0->data.itm_exnum)) : 0)) : \
1465 eval_expr(ist, expr->data.operand[(n)], \
1466 inbytesleft, inbuf, outbytesleft)))))
1468 #define EVAL_OP_BIN_PROTO(op, name, name0, name1) \
1469 case ITM_EXPR_##name##_##name0##_##name1: \
1470 return (EVAL_EXPR_##name0(0) op EVAL_EXPR_##name1(1));
1472 #define EVAL_OP_BIN1(op, name) \
1473 EVAL_OP_BIN_PROTO(op, name, E, E) \
1474 EVAL_OP_BIN_PROTO(op, name, E, D) \
1475 EVAL_OP_BIN_PROTO(op, name, E, R) \
1476 EVAL_OP_BIN_PROTO(op, name, E, INVD)
1478 #define EVAL_OP_BIN2(op, name) \
1479 EVAL_OP_BIN_PROTO(op, name, D, E) \
1480 EVAL_OP_BIN_PROTO(op, name, D, D) \
1481 EVAL_OP_BIN_PROTO(op, name, D, R) \
1482 EVAL_OP_BIN_PROTO(op, name, D, INVD)
1484 #define EVAL_OP_BIN3(op, name) \
1485 EVAL_OP_BIN_PROTO(op, name, R, E) \
1486 EVAL_OP_BIN_PROTO(op, name, R, D) \
1487 EVAL_OP_BIN_PROTO(op, name, R, R) \
1488 EVAL_OP_BIN_PROTO(op, name, R, INVD)
1490 #define EVAL_OP_BIN4(op, name) \
1491 EVAL_OP_BIN_PROTO(op, name, INVD, E) \
1492 EVAL_OP_BIN_PROTO(op, name, INVD, D) \
1493 EVAL_OP_BIN_PROTO(op, name, INVD, R) \
1494 EVAL_OP_BIN_PROTO(op, name, INVD, INVD)
1496 #define EVAL_OP_BIN_PROTECT_PROTO(op, name, name0, name1) \
1497 case ITM_EXPR_##name##_##name0##_##name1: \
1498 num = EVAL_EXPR_##name1(1); \
1500 return (EVAL_EXPR_##name0(0) op num); \
1505 #define EVAL_OP_BIN_PROTECT1(op, name) \
1506 EVAL_OP_BIN_PROTECT_PROTO(op, name, E, E) \
1507 EVAL_OP_BIN_PROTECT_PROTO(op, name, E, D) \
1508 EVAL_OP_BIN_PROTECT_PROTO(op, name, E, R) \
1509 EVAL_OP_BIN_PROTECT_PROTO(op, name, E, INVD)
1511 #define EVAL_OP_BIN_PROTECT2(op, name) \
1512 EVAL_OP_BIN_PROTECT_PROTO(op, name, D, E) \
1513 EVAL_OP_BIN_PROTECT_PROTO(op, name, D, D) \
1514 EVAL_OP_BIN_PROTECT_PROTO(op, name, D, R) \
1515 EVAL_OP_BIN_PROTECT_PROTO(op, name, D, INVD)
1517 #define EVAL_OP_BIN_PROTECT3(op, name) \
1518 EVAL_OP_BIN_PROTECT_PROTO(op, name, R, E) \
1519 EVAL_OP_BIN_PROTECT_PROTO(op, name, R, D) \
1520 EVAL_OP_BIN_PROTECT_PROTO(op, name, R, R) \
1521 EVAL_OP_BIN_PROTECT_PROTO(op, name, R, INVD)
1523 #define EVAL_OP_BIN_PROTECT4(op, name) \
1524 EVAL_OP_BIN_PROTECT_PROTO(op, name, INVD, E) \
1525 EVAL_OP_BIN_PROTECT_PROTO(op, name, INVD, D) \
1526 EVAL_OP_BIN_PROTECT_PROTO(op, name, INVD, R) \
1527 EVAL_OP_BIN_PROTECT_PROTO(op, name, INVD, INVD)
1529 expr
= ADDR(expr_place
);
1531 switch (expr
->type
) {
1532 case ITM_EXPR_NONE
: /* not used */
1534 case ITM_EXPR_NOP
: /* not used */
1536 case ITM_EXPR_NAME
: /* not used */
1538 case ITM_EXPR_INT
: /* integer */
1539 return (expr
->data
.itm_exnum
);
1540 case ITM_EXPR_SEQ
: /* byte sequence */
1541 if ((sizeof (itm_place_t
)) < expr
->data
.value
.size
) {
1542 p
= (unsigned char *)ADDR(expr
->data
.value
.place
);
1544 p
= (unsigned char *)&(expr
->data
.value
.place
);
1546 for (i
= 0, num
= 0; i
< expr
->data
.value
.size
; i
++, p
++) {
1547 num
= ((num
<< 8) | *p
);
1550 case ITM_EXPR_REG
: /* register */
1551 return (REG(expr
->data
.itm_exnum
));
1552 case ITM_EXPR_IN_VECTOR
: /* in[expr] */
1554 if ((0 <= num
) && (num
< inbytesleft
)) {
1555 return (*((unsigned char *)(inbuf
+ num
)));
1556 } else if ((-1) == num
) {
1557 return (inbytesleft
);
1561 case ITM_EXPR_IN_VECTOR_D
: /* in[DECIMAL] */
1562 num
= expr
->data
.itm_exnum
;
1563 if ((0 <= num
) && (num
< inbytesleft
)) {
1564 return (*((unsigned char *)(inbuf
+ num
)));
1565 } else if ((-1) == num
) {
1566 return (inbytesleft
);
1570 case ITM_EXPR_OUT
: /* out */
1571 return (outbytesleft
);
1572 case ITM_EXPR_TRUE
: /* true */
1574 case ITM_EXPR_FALSE
: /* false */
1576 case ITM_EXPR_UMINUS
: /* unary minus */
1577 return ((-1) * EVAL_EXPR(0));
1578 #define PLUS_FOR_CSTYLE_CLEAN +
1579 #define MINUS_FOR_CSTYLE_CLEAN -
1580 #define MUL_FOR_CSTYLE_CLEAN *
1581 #define DIV_FOR_CSTYLE_CLEAN /
1582 #define MOD_FOR_CSTYLE_CLEAN %
1583 #define SHIFT_L_FOR_CSTYLE_CLEAN <<
1584 #define SHIFT_R_FOR_CSTYLE_CLEAN >>
1585 #define OR_FOR_CSTYLE_CLEAN |
1586 #define XOR_FOR_CSTYLE_CLEAN ^
1587 #define AND_FOR_CSTYLE_CLEAN &
1588 #define EQ_FOR_CSTYLE_CLEAN ==
1589 #define NE_FOR_CSTYLE_CLEAN !=
1590 #define GT_FOR_CSTYLE_CLEAN >
1591 #define GE_FOR_CSTYLE_CLEAN >=
1592 #define LT_FOR_CSTYLE_CLEAN <
1593 #define LE_FOR_CSTYLE_CLEAN <=
1594 EVAL_OP_BIN1(PLUS_FOR_CSTYLE_CLEAN
, PLUS
) /* A + B */
1595 EVAL_OP_BIN2(PLUS_FOR_CSTYLE_CLEAN
, PLUS
) /* A + B */
1596 EVAL_OP_BIN3(PLUS_FOR_CSTYLE_CLEAN
, PLUS
) /* A + B */
1597 EVAL_OP_BIN4(PLUS_FOR_CSTYLE_CLEAN
, PLUS
) /* A + B */
1599 EVAL_OP_BIN1(MINUS_FOR_CSTYLE_CLEAN
, MINUS
) /* A - B */
1600 EVAL_OP_BIN2(MINUS_FOR_CSTYLE_CLEAN
, MINUS
) /* A - B */
1601 EVAL_OP_BIN3(MINUS_FOR_CSTYLE_CLEAN
, MINUS
) /* A - B */
1602 EVAL_OP_BIN4(MINUS_FOR_CSTYLE_CLEAN
, MINUS
) /* A - B */
1604 EVAL_OP_BIN1(MUL_FOR_CSTYLE_CLEAN
, MUL
) /* A * B */
1605 EVAL_OP_BIN2(MUL_FOR_CSTYLE_CLEAN
, MUL
) /* A * B */
1606 EVAL_OP_BIN3(MUL_FOR_CSTYLE_CLEAN
, MUL
) /* A * B */
1607 EVAL_OP_BIN4(MUL_FOR_CSTYLE_CLEAN
, MUL
) /* A * B */
1609 EVAL_OP_BIN_PROTECT1(DIV_FOR_CSTYLE_CLEAN
, DIV
) /* A / B */
1610 EVAL_OP_BIN_PROTECT2(DIV_FOR_CSTYLE_CLEAN
, DIV
) /* A / B */
1611 EVAL_OP_BIN_PROTECT3(DIV_FOR_CSTYLE_CLEAN
, DIV
) /* A / B */
1612 EVAL_OP_BIN_PROTECT4(DIV_FOR_CSTYLE_CLEAN
, DIV
) /* A / B */
1614 EVAL_OP_BIN_PROTECT1(MOD_FOR_CSTYLE_CLEAN
, MOD
) /* A % B */
1615 EVAL_OP_BIN_PROTECT2(MOD_FOR_CSTYLE_CLEAN
, MOD
) /* A % B */
1616 EVAL_OP_BIN_PROTECT3(MOD_FOR_CSTYLE_CLEAN
, MOD
) /* A % B */
1617 EVAL_OP_BIN_PROTECT4(MOD_FOR_CSTYLE_CLEAN
, MOD
) /* A % B */
1619 EVAL_OP_BIN1(SHIFT_L_FOR_CSTYLE_CLEAN
, SHIFT_L
) /* A << B */
1620 EVAL_OP_BIN2(SHIFT_L_FOR_CSTYLE_CLEAN
, SHIFT_L
) /* A << B */
1621 EVAL_OP_BIN3(SHIFT_L_FOR_CSTYLE_CLEAN
, SHIFT_L
) /* A << B */
1622 EVAL_OP_BIN4(SHIFT_L_FOR_CSTYLE_CLEAN
, SHIFT_L
) /* A << B */
1624 EVAL_OP_BIN1(SHIFT_R_FOR_CSTYLE_CLEAN
, SHIFT_R
) /* A >> B */
1625 EVAL_OP_BIN2(SHIFT_R_FOR_CSTYLE_CLEAN
, SHIFT_R
) /* A >> B */
1626 EVAL_OP_BIN3(SHIFT_R_FOR_CSTYLE_CLEAN
, SHIFT_R
) /* A >> B */
1627 EVAL_OP_BIN4(SHIFT_R_FOR_CSTYLE_CLEAN
, SHIFT_R
) /* A >> B */
1629 EVAL_OP_BIN1(OR_FOR_CSTYLE_CLEAN
, OR
) /* A | B */
1630 EVAL_OP_BIN2(OR_FOR_CSTYLE_CLEAN
, OR
) /* A | B */
1631 EVAL_OP_BIN3(OR_FOR_CSTYLE_CLEAN
, OR
) /* A | B */
1632 EVAL_OP_BIN4(OR_FOR_CSTYLE_CLEAN
, OR
) /* A | B */
1634 EVAL_OP_BIN1(XOR_FOR_CSTYLE_CLEAN
, XOR
) /* A ^ B */
1635 EVAL_OP_BIN2(XOR_FOR_CSTYLE_CLEAN
, XOR
) /* A ^ B */
1636 EVAL_OP_BIN3(XOR_FOR_CSTYLE_CLEAN
, XOR
) /* A ^ B */
1637 EVAL_OP_BIN4(XOR_FOR_CSTYLE_CLEAN
, XOR
) /* A ^ B */
1639 EVAL_OP_BIN1(AND_FOR_CSTYLE_CLEAN
, AND
) /* A & B */
1640 EVAL_OP_BIN2(AND_FOR_CSTYLE_CLEAN
, AND
) /* A & B */
1641 EVAL_OP_BIN3(AND_FOR_CSTYLE_CLEAN
, AND
) /* A & B */
1642 EVAL_OP_BIN4(AND_FOR_CSTYLE_CLEAN
, AND
) /* A & B */
1644 EVAL_OP_BIN1(EQ_FOR_CSTYLE_CLEAN
, EQ
) /* A == B */
1645 EVAL_OP_BIN2(EQ_FOR_CSTYLE_CLEAN
, EQ
) /* A == B */
1646 EVAL_OP_BIN3(EQ_FOR_CSTYLE_CLEAN
, EQ
) /* A == B */
1647 EVAL_OP_BIN4(EQ_FOR_CSTYLE_CLEAN
, EQ
) /* A == B */
1649 EVAL_OP_BIN1(NE_FOR_CSTYLE_CLEAN
, NE
) /* A != B */
1650 EVAL_OP_BIN2(NE_FOR_CSTYLE_CLEAN
, NE
) /* A != B */
1651 EVAL_OP_BIN3(NE_FOR_CSTYLE_CLEAN
, NE
) /* A != B */
1652 EVAL_OP_BIN4(NE_FOR_CSTYLE_CLEAN
, NE
) /* A != B */
1654 EVAL_OP_BIN1(GT_FOR_CSTYLE_CLEAN
, GT
) /* A > B */
1655 EVAL_OP_BIN2(GT_FOR_CSTYLE_CLEAN
, GT
) /* A > B */
1656 EVAL_OP_BIN3(GT_FOR_CSTYLE_CLEAN
, GT
) /* A > B */
1657 EVAL_OP_BIN4(GT_FOR_CSTYLE_CLEAN
, GT
) /* A > B */
1659 EVAL_OP_BIN1(GE_FOR_CSTYLE_CLEAN
, GE
) /* A >= B */
1660 EVAL_OP_BIN2(GE_FOR_CSTYLE_CLEAN
, GE
) /* A >= B */
1661 EVAL_OP_BIN3(GE_FOR_CSTYLE_CLEAN
, GE
) /* A >= B */
1662 EVAL_OP_BIN4(GE_FOR_CSTYLE_CLEAN
, GE
) /* A >= B */
1664 EVAL_OP_BIN1(LT_FOR_CSTYLE_CLEAN
, LT
) /* A < B */
1665 EVAL_OP_BIN2(LT_FOR_CSTYLE_CLEAN
, LT
) /* A < B */
1666 EVAL_OP_BIN3(LT_FOR_CSTYLE_CLEAN
, LT
) /* A < B */
1667 EVAL_OP_BIN4(LT_FOR_CSTYLE_CLEAN
, LT
) /* A < B */
1669 EVAL_OP_BIN1(LE_FOR_CSTYLE_CLEAN
, LE
) /* A <= B */
1670 EVAL_OP_BIN2(LE_FOR_CSTYLE_CLEAN
, LE
) /* A <= B */
1671 EVAL_OP_BIN3(LE_FOR_CSTYLE_CLEAN
, LE
) /* A <= B */
1672 EVAL_OP_BIN4(LE_FOR_CSTYLE_CLEAN
, LE
) /* A <= B */
1674 case ITM_EXPR_NOT
: /* !A */
1675 return (!(EVAL_EXPR(0)));
1676 case ITM_EXPR_NEG
: /* ~A */
1677 return (~(EVAL_EXPR(0)));
1678 case ITM_EXPR_LOR
: /* A || B */
1679 if (0 != (num
= EVAL_EXPR(0)))
1681 if (0 != (num
= EVAL_EXPR(1)))
1684 case ITM_EXPR_LAND
: /* A && B */
1685 if (0 == EVAL_EXPR(0))
1687 if (0 == (num
= EVAL_EXPR(1)))
1690 case ITM_EXPR_ASSIGN
: /* A = B */
1692 if (expr
->data
.operand
[0].itm_ptr
< ist
->itm_hdr
->reg_num
) {
1693 return (*(ist
->regs
+ expr
->data
.operand
[0].itm_ptr
)
1698 case ITM_EXPR_IN_EQ
: /* in == A */
1699 expr_op
= ADDR(expr
->data
.operand
[0]);
1700 switch (expr_op
->type
) {
1702 if (inbytesleft
< expr_op
->data
.value
.size
) {
1705 p
= DADDR(&(expr_op
->data
.value
));
1706 for (i
= 0; i
< expr_op
->data
.value
.size
; i
++, p
++) {
1707 if (*p
!= *(inbuf
+ i
)) {
1714 return (num
== *((unsigned char *)inbuf
));
1725 #undef EVAL_EXPR_INVD
1731 * maintain ITM reference information
1734 itm_ref_free(int fd
, void *ptr0
, void *ptr1
, void *ptr2
, size_t len
)
1744 (void) munmap(ptr2
, len
);
1750 itm_ref_inc(const char *itm
)
1757 fd
= open(itm
, O_RDONLY
, 0);
1759 itm_ref_free(-1, NULL
, NULL
, NULL
, 0);
1763 if (fstat(fd
, &st
) == -1) {
1764 itm_ref_free(fd
, NULL
, NULL
, NULL
, 0);
1767 hdr
= (void *) mmap(NULL
, st
.st_size
, PROT_READ
, MAP_SHARED
, fd
, 0);
1768 if (MAP_FAILED
== hdr
) {
1769 itm_ref_free(fd
, NULL
, NULL
, NULL
, 0);
1775 ref
= malloc(sizeof (itm_ref_t
));
1777 itm_ref_free(-1, NULL
, NULL
, hdr
, st
.st_size
);
1780 ref
->name
= malloc(strlen(itm
) + 1);
1781 if (NULL
== ref
->name
) {
1782 itm_ref_free(-1, ref
, NULL
, hdr
, st
.st_size
);
1785 (void) strcpy(ref
->name
, itm
);
1787 ref
->len
= st
.st_size
;
1789 if ((hdr
->ident
[0] != ITM_IDENT_0
) ||
1790 (hdr
->ident
[1] != ITM_IDENT_1
) ||
1791 (hdr
->ident
[2] != ITM_IDENT_2
) ||
1792 (hdr
->ident
[3] != ITM_IDENT_3
) ||
1793 (hdr
->spec
[0] != ITM_SPEC_0
) ||
1794 (hdr
->spec
[1] != ITM_SPEC_1
) ||
1795 (hdr
->spec
[2] != ITM_SPEC_2
) ||
1796 #if defined(_LITTLE_ENDIAN)
1798 ((hdr
->spec
[3] != ITM_SPEC_3_32_LITTLE_ENDIAN
) &&
1799 (hdr
->spec
[3] != ITM_SPEC_3_64_LITTLE_ENDIAN
)) ||
1801 (hdr
->spec
[3] != ITM_SPEC_3_32_LITTLE_ENDIAN
) ||
1805 ((hdr
->spec
[3] != ITM_SPEC_3_32_BIG_ENDIAN
) &&
1806 (hdr
->spec
[3] != ITM_SPEC_3_64_BIG_ENDIAN
)) ||
1808 (hdr
->spec
[3] != ITM_SPEC_3_32_BIG_ENDIAN
) ||
1811 (hdr
->version
[0] != ITM_VER_0
) ||
1812 (hdr
->version
[1] != ITM_VER_1
) ||
1813 (hdr
->version
[2] != ITM_VER_2
) ||
1814 (hdr
->version
[3] != ITM_VER_3
) ||
1815 (((size_t)(hdr
->itm_size
.itm_ptr
)) != st
.st_size
)) {
1816 itm_ref_free(-1, ref
, ref
->name
, ref
->hdr
, ref
->len
);
1818 TRACE_MESSAGE('e', ("itm_ref_inc:error=%d\n", errno
));
1827 itm_ref_dec(itm_ref_t
*ref
)
1829 (void) munmap((char *)(ref
->hdr
), ref
->len
);
1836 op_init_default(icv_state_t
*ist
)
1838 ist
->direc
= ADDR(ist
->itm_hdr
->direc_init_tbl
);
1844 op_reset_default(icv_state_t
*ist
)
1846 ist
->direc
= ADDR(ist
->itm_hdr
->direc_init_tbl
);
1852 regs_init(icv_state_t
*ist
)
1854 if (0 < ist
->itm_hdr
->reg_num
) {
1855 (void) memset(ist
->regs
, 0,
1856 (sizeof (itm_num_t
)) * ist
->itm_hdr
->reg_num
);
1868 env_val
= getenv("ITM_INT_TRACE");
1869 if (NULL
== env_val
)
1872 for (p
= env_val
; *p
; p
++) {
1873 trace_option
[(*p
) & 0x007f] = 1;
1878 trace_message(char *format
, ...)
1882 va_start(ap
, format
);
1884 (void) vfprintf(stderr
, format
, ap
);