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.
32 #include <sys/types.h>
50 static void trace_init(void);
51 static void trace_message(char *, ...);
53 static char trace_option
[128];
55 #define TRACE(c) (*(trace_option + (c & 0x007f)))
56 #define TRACE_MESSAGE(c, args) ((TRACE(c))? trace_message args: (void)0)
62 #define TRACE_MESSAGE(c, args)
68 * ITM reference information
70 typedef struct _itm_ref
{
71 char *name
; /* ITM file name */
72 itm_hdr_t
*hdr
; /* address of ITM */
73 size_t len
; /* length of ITM */
78 * struct _icv_state; to keep status
80 typedef struct _icv_state
{
81 struct _itm_ref
*itm
; /* reference to ITM */
82 itm_hdr_t
*itm_hdr
; /* address of ITM */
83 itm_tbl_hdr_t
*direc
; /* current direction */
84 itm_place_t default_action
; /* default action */
85 itm_num_t
*regs
; /* register */
86 itm_num_t reg_num
; /* number of register */
87 #if defined(OP_DEPTH_MAX)
88 int op_depth
; /* depth of operation */
89 #endif /* OP_DEPTH_MAX */
96 void * _icv_open(const char *);
97 void _icv_close(icv_state_t
*);
98 size_t _icv_iconv(icv_state_t
*, const unsigned char **,
99 size_t *, unsigned char **, size_t *);
101 static size_t map_i_f(itm_tbl_hdr_t
*,
102 const unsigned char **, size_t *,
103 unsigned char **, size_t *, long);
104 static size_t map_l_f(itm_tbl_hdr_t
*,
105 const unsigned char **, size_t *,
106 unsigned char **, size_t *, long);
107 static size_t map_h_l(itm_tbl_hdr_t
*,
108 const unsigned char **, size_t *,
109 unsigned char **, size_t *, long);
110 static size_t map_d_e_l(itm_tbl_hdr_t
*,
111 const unsigned char **, size_t *,
112 unsigned char **, size_t *, long);
113 static size_t eval_cond_tbl(icv_state_t
*, itm_place_t
,
114 const unsigned char **, size_t *,
115 size_t, itm_direc_t
*);
116 static size_t eval_op_tbl(icv_state_t
*, itm_place_t
,
117 const unsigned char **, size_t *,
118 unsigned char **, size_t *);
119 static size_t eval_op(icv_state_t
*, itm_place2_t
,
120 const unsigned char **, size_t *,
121 unsigned char **, size_t *);
123 static itm_num_t
eval_expr(icv_state_t
*, itm_place_t
,
124 size_t, const unsigned char *, size_t);
126 static void itm_ref_free(int, void *, void *, void *, size_t);
127 static itm_ref_t
*itm_ref_inc(const char *);
128 static void itm_ref_dec(itm_ref_t
*);
130 static void op_init_default(icv_state_t
*);
131 static void op_reset_default(icv_state_t
*);
132 static void regs_init(icv_state_t
*);
139 #define ADDR(place) ((void *)(((char *)(ist->itm_hdr)) +\
140 ((itm_place2_t)(place.itm_ptr))))
141 #define ADDR2(place2) ((void *)(((char *)(ist->itm_hdr)) +\
142 ((itm_place2_t)(place2))))
143 #define DADDR(n) (((n)->size <= (sizeof ((n)->place.itm_64d))) ? \
144 ((unsigned char *)(&((n)->place.itm_64d))) :\
145 ((unsigned char *)(ADDR((n)->place))))
147 #define REG(n) (*(ist->regs + (n)))
148 #define DISCARD(c) (((*inbuf) = (void *)((*inbuf) + (c))),\
149 ((*inbytesleft) -= (c)))
150 #define GET(c) ((c) = **inbuf, (*inbuf)++, (*inbytesleft)--)
151 #define PUT(c) (**outbuf = (c), (*outbuf)++, (*outbytesleft)--)
153 #define RETVALERR ((size_t)(-1))
154 #define RETVALDIR ((size_t)(-2))
155 #define RETVALBRK ((size_t)(-3))
156 #define RETVALRET ((size_t)(-4))
158 #define UPDATE_ARGS() (*inbuf = ip, \
159 *inbytesleft = ileft, \
161 *outbytesleft = oleft)
164 * Open; called from iconv_open()
167 _icv_open(const char *itm
)
180 * _icv_open() primaty task
182 itm_ref
= itm_ref_inc(itm
);
183 if (NULL
== itm_ref
) {
184 return ((void *)(-1));
187 if (NULL
== (ist
= malloc(sizeof (icv_state_t
)))) {
189 itm_ref_dec(itm_ref
);
195 ist
->itm_hdr
= ist
->itm
->hdr
;
196 ist
->reg_num
= ist
->itm
->hdr
->reg_num
;
199 ist
->direc
= ADDR(hdr
->direc_init_tbl
);
200 ist
->default_action
.itm_64d
= 0;
201 #if defined(OP_DEPTH_MAX)
203 #endif /* OP_DEPTH_MAX */
209 if (hdr
->itm_size
.itm_ptr
<= hdr
->direc_init_tbl
.itm_ptr
) {
212 return ((void *)(-1));
216 /* allocate register region */
217 if (hdr
->reg_num
<= 0) {
220 ist
->regs
= malloc((sizeof (itm_num_t
)) * hdr
->reg_num
);
221 if (NULL
== ist
->regs
) {
225 return ((void *)(-1));
227 (void) memset(ist
->regs
, 0,
228 (sizeof (itm_num_t
)) * hdr
->reg_num
);
232 /* evaluate init operation */
233 if (0 != ist
->itm_hdr
->op_init_tbl
.itm_ptr
) {
234 const unsigned char *ip
= NULL
;
236 unsigned char *op
= NULL
;
238 (void) eval_op_tbl(ist
, ist
->itm_hdr
->op_init_tbl
, &ip
,
239 &ileft
, &op
, &oleft
);
241 op_init_default(ist
);
249 * Close; called from iconv_close
252 _icv_close(icv_state_t
*ist
)
258 itm_ref_dec(ist
->itm
);
265 * Actual conversion; called from iconv()
270 const unsigned char **inbuf
,
272 unsigned char **outbuf
,
273 size_t *outbytesleft
)
278 const unsigned char *ip
;
284 TRACE_MESSAGE('e', ("_icv_iconv: error=%d\n", errno
));
285 return ((size_t)(-1));
291 if (NULL
== inbytesleft
) {
293 inbytesleft
= &ileft
;
300 TRACE_MESSAGE('i', ("_icv_iconv(inbuf=%p inbytesleft=%ld "
301 "outbuf=%p outbytesleft=%ld)\n", (NULL
== inbuf
) ? 0 : *inbuf
,
302 (NULL
== inbytesleft
) ? 0 : *inbytesleft
,
303 (NULL
== outbuf
) ? 0 : *outbuf
,
304 (NULL
== outbytesleft
) ? 0 : *outbytesleft
));
307 * If (NULL == inbuf || NULL == *inbuf) then this conversion is
308 * placed into initial state.
310 if ((NULL
== inbuf
) || (NULL
== *inbuf
)) {
311 if (0 != hdr
->op_reset_tbl
.itm_ptr
) {
312 ist
->direc
= ADDR(hdr
->direc_init_tbl
);
313 retval
= eval_op_tbl(ist
, hdr
->op_reset_tbl
, inbuf
,
314 inbytesleft
, outbuf
, outbytesleft
);
315 if ((size_t)(-1) == retval
) {
319 op_reset_default(ist
);
321 return ((size_t)(0));
324 if (ITM_TBL_MAP_INDEX_FIXED_1_1
== ist
->direc
->type
) {
325 itm_map_idx_fix_hdr_t
*map_hdr
;
327 const unsigned char *ip
;
332 map_hdr
= (itm_map_idx_fix_hdr_t
*)(ist
->direc
+ 1);
333 map
= (char *)(map_hdr
+ 1);
335 if (1 == map_hdr
->default_error
) {
336 retval
= map_i_f(ist
->direc
, inbuf
, inbytesleft
,
337 outbuf
, outbytesleft
, 0);
342 ileft
= *inbytesleft
;
344 oleft
= *outbytesleft
;
350 TRACE_MESSAGE('e', ("_icv_iconv: error=%d\n",
354 *(op
++) = *(map
+ *(ip
++));
361 } else if (ITM_TBL_MAP_INDEX_FIXED
== ist
->direc
->type
) {
362 retval
= map_i_f(ist
->direc
, inbuf
, inbytesleft
,
363 outbuf
, outbytesleft
, 0);
365 } else if (ITM_TBL_MAP_HASH
== ist
->direc
->type
) {
366 retval
= map_h_l(ist
->direc
, inbuf
, inbytesleft
,
367 outbuf
, outbytesleft
, 0);
369 } else if (ITM_TBL_MAP_DENSE_ENC
== ist
->direc
->type
) {
370 retval
= map_d_e_l(ist
->direc
, inbuf
, inbytesleft
,
371 outbuf
, outbytesleft
, 0);
373 } else if (ITM_TBL_MAP_LOOKUP
== ist
->direc
->type
) {
374 retval
= map_l_f(ist
->direc
, inbuf
, inbytesleft
,
375 outbuf
, outbytesleft
, 0);
379 #if defined(OP_DEPTH_MAX)
381 #endif /* OP_DEPTH_MAX */
385 * Main loop; basically 1 loop per 1 output character
388 while (0 < *inbytesleft
) {
389 itm_tbl_hdr_t
*direc_hdr
;
393 direc_hdr
= ist
->direc
;
394 direc
= (itm_direc_t
*)(ist
->direc
+ 1);
395 for (i
= 0; /* NULL */; i
++, direc
++) {
396 if (i
>= direc_hdr
->number
) {
397 if (0 == ist
->default_action
.itm_ptr
) {
400 ("_icv_iconv:error=%d\n", errno
));
401 return ((size_t)(-1));
406 action
= ist
->default_action
;
407 type
= ((itm_tbl_hdr_t
*)(ADDR(action
)))->type
;
409 ("escape seq (default action=%6p, "
410 "type=%ld) executing\n",
411 action
.itm_ptr
, type
));
412 } else if (0 != direc
->condition
.itm_ptr
) {
413 retval
= eval_cond_tbl(ist
, direc
->condition
,
414 inbuf
, inbytesleft
, *outbytesleft
, direc
);
415 if ((size_t)(0) == retval
) {
417 } else if ((size_t)(-1) == retval
) {
419 } else if ((size_t)(2) == retval
) {
420 goto retry_cond_eval
;
422 action
= direc
->action
;
423 type
= ((itm_tbl_hdr_t
*)(ADDR(action
)))->type
;
425 action
= direc
->action
;
426 type
= ((itm_tbl_hdr_t
*)(ADDR(action
)))->type
;
430 ("inbytesleft=%ld; type=%ld:action=%p\n",
431 *inbytesleft
, type
, action
.itm_ptr
));
432 switch (ITM_TBL_MASK
& type
) {
434 retval
= eval_op_tbl(ist
, action
,
435 inbuf
, inbytesleft
, outbuf
, outbytesleft
);
436 if ((size_t)(-1) == retval
) {
441 ist
->direc
= ADDR(action
);
445 case ITM_TBL_MAP_INDEX_FIXED_1_1
:
446 case ITM_TBL_MAP_INDEX_FIXED
:
447 retval
= map_i_f(ADDR(action
),
449 outbuf
, outbytesleft
, 1);
451 case ITM_TBL_MAP_HASH
:
452 retval
= map_h_l(ADDR(action
),
454 outbuf
, outbytesleft
, 1);
456 case ITM_TBL_MAP_DENSE_ENC
:
457 retval
= map_d_e_l(ADDR(action
),
459 outbuf
, outbytesleft
, 1);
461 case ITM_TBL_MAP_LOOKUP
:
462 retval
= map_l_f(ADDR(action
),
464 outbuf
, outbytesleft
, 1);
469 ("_icv_iconv:error=%d\n", errno
));
470 return ((size_t)(-1));
473 if ((size_t)(-1) == retval
) {
480 ("_icv_iconv:error=%d\n", errno
));
481 return ((size_t)(-1));
496 itm_tbl_hdr_t
*tbl_hdr
,
497 const unsigned char **inbuf
,
499 unsigned char **outbuf
,
500 size_t *outbytesleft
,
503 itm_map_idx_fix_hdr_t
*map_hdr
;
507 const unsigned char *p
;
509 TRACE_MESSAGE('i', ("map_i_f\n"));
511 map_hdr
= (itm_map_idx_fix_hdr_t
*)(tbl_hdr
+ 1);
514 if (*inbytesleft
< map_hdr
->source_len
) {
516 TRACE_MESSAGE('e', ("map_i_f:error=%d\n", errno
));
517 return ((size_t)(-1));
521 for (i
= 0; i
< map_hdr
->source_len
; i
++) {
526 if (((j
< map_hdr
->start
.itm_ptr
) ||
527 (map_hdr
->end
.itm_ptr
< j
)) &&
528 (0 < map_hdr
->default_error
)) {
530 (*inbuf
) = (void*) ((*inbuf
) - map_hdr
->source_len
);
531 (*inbytesleft
) += map_hdr
->source_len
;
532 TRACE_MESSAGE('e', ("map_i_f:error=%d\n", errno
));
533 return ((size_t)(-1));
536 if (*outbytesleft
< map_hdr
->result_len
) {
538 (*inbuf
) = (void *)((*inbuf
) - map_hdr
->source_len
);
539 (*inbytesleft
) += map_hdr
->source_len
;
540 TRACE_MESSAGE('e', ("map_i_f:error=%d\n", errno
));
541 return ((size_t)(-1));
544 if ((j
< map_hdr
->start
.itm_ptr
) ||
545 (map_hdr
->end
.itm_ptr
< j
)) {
546 if (0 == map_hdr
->default_error
) {
547 p
= (((unsigned char *)(map_hdr
+ 1)) +
548 (map_hdr
->result_len
* (tbl_hdr
->number
)));
549 for (i
= 0; i
< map_hdr
->result_len
; i
++) {
553 p
= ((*inbuf
) - map_hdr
->source_len
);
554 for (i
= 0; i
< map_hdr
->source_len
; i
++) {
560 map_error
= (((char *)(map_hdr
+ 1)) +
561 (map_hdr
->result_len
* (tbl_hdr
->number
)) +
562 (j
- map_hdr
->start
.itm_ptr
));
563 if (0 == map_hdr
->default_error
) {
565 (map_error
+ map_hdr
->result_len
);
567 if (((1 == map_hdr
->default_error
) ||
568 (0 < map_hdr
->error_num
)) &&
569 (0 != *(map_error
))) {
572 ((*inbuf
) - map_hdr
->source_len
);
573 (*inbytesleft
) += map_hdr
->source_len
;
575 ("map_i_f:error=%d\n", errno
));
576 return ((size_t)(-1));
578 p
= (((unsigned char *)(map_hdr
+ 1)) +
579 (map_hdr
->result_len
*
580 (j
- map_hdr
->start
.itm_ptr
)));
581 for (i
= 0; i
< map_hdr
->result_len
; i
++) {
585 } while ((0 < *inbytesleft
) && (0 == once
));
596 itm_tbl_hdr_t
*tbl_hdr
,
597 const unsigned char **inbuf
,
599 unsigned char **outbuf
,
600 size_t *outbytesleft
,
603 itm_map_lookup_hdr_t
*map_hdr
;
606 const unsigned char *p
;
611 itm_size_t pair_size
;
613 TRACE_MESSAGE('i', ("map_l_f\n"));
615 map_hdr
= (itm_map_lookup_hdr_t
*)(tbl_hdr
+ 1);
616 map
= (unsigned char *)(map_hdr
+ 1);
617 pair_size
= map_hdr
->source_len
+ 1 + map_hdr
->result_len
;
620 if (*inbytesleft
< map_hdr
->source_len
) {
622 TRACE_MESSAGE('e', ("map_l_f:error=%d\n", errno
));
623 return ((size_t)(-1));
626 for (low
= 0, high
= tbl_hdr
->number
; low
< high
; ) {
627 mid
= (low
+ high
) / 2;
628 p
= map
+ (pair_size
* mid
);
629 for (i
= 0, result
= 0; i
< map_hdr
->source_len
;
631 if (*(unsigned char *)(*inbuf
+ i
) < *p
) {
635 if (*p
< *(unsigned char *)(*inbuf
+ i
)) {
642 } else if (0 < result
) {
644 } else { /* 0 == result */
650 if (map_hdr
->default_error
< 0) {
652 } else if (0 == map_hdr
->default_error
) {
653 p
= map
+ (pair_size
* tbl_hdr
->number
) +
654 map_hdr
->source_len
+ 1;
655 } else if (0 < map_hdr
->default_error
) {
657 TRACE_MESSAGE('e', ("map_l_f:error=%d\n",
659 return ((size_t)(-1));
664 TRACE_MESSAGE('e', ("map_l_f:error=%d\n",
666 return ((size_t)(-1));
671 if (*outbytesleft
< map_hdr
->result_len
) {
673 TRACE_MESSAGE('e', ("map_l_f:error=%d\n", errno
));
674 return ((size_t)(-1));
676 DISCARD(map_hdr
->source_len
);
678 for (i
= 0; i
< map_hdr
->result_len
; i
++) {
681 } while ((0 < *inbytesleft
) && (0 == once
));
683 return ((size_t)(0));
692 itm_tbl_hdr_t
*tbl_hdr
,
693 const unsigned char **inbuf
,
695 unsigned char **outbuf
,
696 size_t *outbytesleft
,
699 itm_map_hash_hdr_t
*map_hdr
;
701 unsigned char *map_error
;
702 unsigned char *map_hash
;
703 unsigned char *map_of
;
704 const unsigned char *p
;
705 const unsigned char *q
;
710 itm_size_t pair_size
;
711 itm_size_t hash_value
;
712 itm_size_t source_len
;
713 itm_size_t result_len
;
715 TRACE_MESSAGE('i', ("map_hash\n"));
717 map_hdr
= (itm_map_hash_hdr_t
*)(tbl_hdr
+ 1);
718 map_error
= (unsigned char *)(map_hdr
+ 1);
719 map_hash
= (map_error
+ map_hdr
->hash_tbl_num
);
720 map_of
= map_hash
+ map_hdr
->hash_tbl_size
;
721 pair_size
= map_hdr
->source_len
+ 1 + map_hdr
->result_len
;
722 source_len
= map_hdr
->source_len
;
723 result_len
= map_hdr
->result_len
;
726 if (*inbytesleft
< source_len
) {
728 TRACE_MESSAGE('e', ("map_h_l:error=%d\n", errno
));
729 return ((size_t)(-1));
734 hash_value
= hash((const char *)(q
), source_len
,
735 map_hdr
->hash_tbl_num
);
736 p
= map_hash
+ (pair_size
* hash_value
);
737 if (1 == *(map_error
+ hash_value
)) {
738 for (i
= 0, result
= 0; i
< source_len
; i
++) {
739 if (*(q
+ i
) != *(p
++)) {
745 ("(h=%d): find pair without conflict\n",
747 } else if (0 == *(map_error
+ hash_value
)) {
748 TRACE_MESSAGE('G', ("(h=%d): No Pair\n", hash_value
));
750 } else /* if (0 < *(map_error + hash_value)) */ {
751 for (i
= 0, result
= 0; i
< source_len
; i
++) {
752 if (*(q
+ i
) != *(p
++)) {
758 for (low
= 0, high
= map_hdr
->hash_of_num
;
759 low
< high
; /* NOP */) {
760 mid
= (low
+ high
) / 2;
761 p
= map_of
+ (pair_size
* mid
);
762 for (i
= 0, result
= 0;
776 } else if (0 < result
) {
778 } else { /* 0 == result */
779 TRACE_MESSAGE('G', ("(h=%d): "
780 "find data on out of "
781 "hashtable with CONFLICT\n",
789 if (map_hdr
->default_error
< 0) {
791 } else if (0 == map_hdr
->default_error
) {
792 p
= map_of
+ map_hdr
->hash_of_size
;
793 } else if (0 < map_hdr
->default_error
) {
794 TRACE_MESSAGE('G', ("(h=%d): NO PAIR\n",
798 ("map_h_l:error=%d\n", errno
));
799 return ((size_t)(-1));
804 TRACE_MESSAGE('G', (" : error pair\n"));
805 TRACE_MESSAGE('e', ("map_l_f:error\n", errno
));
806 return ((size_t)(-1));
811 if (*outbytesleft
< result_len
) {
813 TRACE_MESSAGE('e', ("map_h_l:error=%d\n", errno
));
814 return ((size_t)(-1));
818 for (i
= 0; i
< result_len
; i
++) {
821 } while ((0 < *inbytesleft
) && (0 == once
));
823 return ((size_t)(0));
828 * map-dense_encoding-lookup
832 itm_tbl_hdr_t
*tbl_hdr
,
833 const unsigned char **inbuf
,
835 unsigned char **outbuf
,
836 size_t *outbytesleft
,
839 itm_map_dense_enc_hdr_t
*map_hdr
;
842 const unsigned char *p
;
843 unsigned char *map_ptr
;
844 unsigned char *map_error
;
845 unsigned char *byte_seq_min
;
846 unsigned char *byte_seq_max
;
848 TRACE_MESSAGE('i', ("map_d_e_l\n"));
850 map_hdr
= (itm_map_dense_enc_hdr_t
*)(tbl_hdr
+ 1);
851 map_ptr
= ((unsigned char *)(map_hdr
+ 1) + map_hdr
->source_len
+
852 map_hdr
->source_len
);
853 map_error
= (map_ptr
+ (tbl_hdr
->number
* map_hdr
->result_len
));
854 if (0 == map_hdr
->default_error
) {
855 map_error
= (void *)(map_error
+ map_hdr
->result_len
);
857 byte_seq_min
= (unsigned char *)(map_hdr
+ 1);
858 byte_seq_max
= byte_seq_min
+ map_hdr
->source_len
;
861 if (*inbytesleft
< map_hdr
->source_len
) {
863 TRACE_MESSAGE('e', ("map_d_e_l:error=%d\n", errno
));
864 return ((size_t)(-1));
867 j
= hash_dense_encoding(*inbuf
, map_hdr
->source_len
,
868 byte_seq_min
, byte_seq_max
);
870 if (((j
< 0) || (tbl_hdr
->number
< j
)) &&
871 (0 < map_hdr
->default_error
)) {
873 TRACE_MESSAGE('e', ("map_d_e_l:error=%d\n", errno
));
874 return ((size_t)(-1));
877 if (*outbytesleft
< map_hdr
->result_len
) {
879 TRACE_MESSAGE('e', ("map_d_e_l:error=%d\n", errno
));
880 return ((size_t)(-1));
883 if ((j
< 0) || (tbl_hdr
->number
< j
)) {
884 if (0 == map_hdr
->default_error
) {
885 p
= (map_ptr
+ (tbl_hdr
->number
*
886 map_hdr
->result_len
));
887 for (i
= 0; i
< map_hdr
->result_len
; i
++) {
892 for (i
= 0; i
< map_hdr
->source_len
; i
++) {
897 if ((1 == map_hdr
->default_error
) ||
898 (0 < map_hdr
->error_num
)) {
899 if (0 != *(map_error
+ j
)) {
902 ("map_d_e_l:error=%d\n", errno
));
903 return ((size_t)(-1));
906 p
= (map_ptr
+ (map_hdr
->result_len
* j
));
907 for (i
= 0; i
< map_hdr
->result_len
; i
++) {
911 DISCARD(map_hdr
->source_len
);
912 } while ((0 < *inbytesleft
) && (0 == once
));
914 return ((size_t)(0));
920 * Evaluate condition table
926 itm_place_t cond_place
,
927 const unsigned char **inbuf
,
933 itm_tbl_hdr_t
*cond_hdr
;
940 itm_range_hdr_t
*rtsh
;
943 itm_escapeseq_hdr_t
*eh
;
945 const unsigned char *ip
;
950 ileft
= *inbytesleft
;
951 cond_hdr
= ADDR(cond_place
);
952 cond
= (itm_cond_t
*)(cond_hdr
+ 1);
953 for (i
= 0; i
< cond_hdr
->number
; i
++, cond
++) {
954 switch (cond
->type
) {
955 case ITM_COND_BETWEEN
:
956 rth
= ADDR(cond
->operand
.place
);
957 rtsh
= (itm_range_hdr_t
*)(rth
+ 1);
958 if (ileft
< rtsh
->len
) {
960 TRACE_MESSAGE('e', ("eval_cond_tbl:error=%d\n",
962 retval
= ((size_t)(-1));
963 goto eval_cond_return
;
965 p
= (unsigned char *)(rtsh
+ 1);
967 for (j
= 0; j
< rth
->number
;
968 j
++, p
= (void *)(p
+ (2 * rtsh
->len
))) {
970 for (k
= 0; k
< rtsh
->len
; k
++) {
971 if ((*(ip
+ k
) < *(p
+ k
)) ||
972 (*(p
+ rtsh
->len
+ k
) <
984 ("out of between (%p) len= rtsh=%ld\n",
986 goto eval_cond_return
;
988 break; /* continue */
989 case ITM_COND_ESCAPESEQ
:
991 * if escape sequence occur,
992 * change ist->default_action and return 2.
996 eth
= ADDR(cond
->operand
.place
);
997 eh
= (itm_escapeseq_hdr_t
*)(eth
+ 1);
998 if (ist
->default_action
.itm_ptr
== (uintptr_t)NULL
) {
999 ist
->default_action
= direc
->action
;
1001 ("escape seq (default action=%6p, "
1003 direc
->action
.itm_ptr
, ((itm_tbl_hdr_t
*)
1004 (ADDR(direc
->action
)))->type
));
1007 if (*inbytesleft
< eh
->len_min
) {
1010 for (j
= 0, d
= (itm_data_t
*)(eh
+ 1);
1013 if (*inbytesleft
< d
->size
) {
1016 if (0 == memcmp(*inbuf
, DADDR(d
), d
->size
)) {
1018 ("escape seq: discard=%ld chars\n",
1021 ("escape seq (default "
1022 "action=%6p, type=%ld) set\n",
1023 direc
->action
.itm_ptr
,
1025 (ADDR(direc
->action
)))->type
));
1026 ist
->default_action
= direc
->action
;
1029 goto eval_cond_return
;
1033 goto eval_cond_return
;
1035 break; /* continue */
1037 retval
= eval_expr(ist
, cond
->operand
.place
,
1038 *inbytesleft
, ip
, outbytesleft
);
1040 goto eval_cond_return
;
1044 break; /* continue */
1046 TRACE_MESSAGE('e', ("eval_cond_tbl:illegal cond=%d\n",
1048 retval
= (size_t)-1;
1049 goto eval_cond_return
;
1058 * Evaluate operation table
1064 itm_place_t op_tbl_place
,
1065 const unsigned char **inbuf
,
1066 size_t *inbytesleft
,
1067 unsigned char **outbuf
,
1068 size_t *outbytesleft
)
1070 itm_tbl_hdr_t
*op_hdr
;
1071 itm_op_t
*operation
;
1072 itm_place2_t op_place
;
1078 #if defined(OP_DEPTH_MAX)
1079 if (OP_DEPTH_MAX
<= ist
->op_depth
) {
1081 TRACE_MESSAGE('e', ("eval_op_tbl:error=%d\n", errno
));
1085 #endif /* OP_DEPTH_MAX */
1087 op_hdr
= ADDR(op_tbl_place
);
1088 operation
= (itm_op_t
*)(op_hdr
+ 1);
1090 op_place
= op_tbl_place
.itm_ptr
+ (sizeof (itm_tbl_hdr_t
));
1091 for (i
= 0; i
< op_hdr
->number
; i
++, operation
++,
1092 op_place
+= (sizeof (itm_op_t
))) {
1093 TRACE_MESSAGE('O', ("eval_op_tbl: %ld %p\n", i
, op_place
));
1094 retval
= eval_op(ist
, op_place
, inbuf
, inbytesleft
,
1095 outbuf
, outbytesleft
);
1096 if (((long)(retval
)) < 0) {
1097 #if defined(OP_DEPTH_MAX)
1099 #endif /* OP_DEPTH_MAX */
1104 if (0 == op_hdr
->name
.itm_ptr
) {
1112 #if defined(OP_DEPTH_MAX)
1114 #endif /* OP_DEPTH_MAX */
1120 * Evaluate single operation
1126 itm_place2_t op_place
,
1127 const unsigned char **inbuf
,
1128 size_t *inbytesleft
,
1129 unsigned char **outbuf
,
1130 size_t *outbytesleft
)
1134 itm_op_t
*operation
;
1144 #define EVAL_EXPR(n) \
1145 (expr0 = ADDR(operation->data.operand[(n)]), \
1146 (itm_num_t)((expr0->type == ITM_EXPR_INT) ? \
1147 expr0->data.itm_exnum : \
1148 ((expr0->type == ITM_EXPR_REG) ? \
1149 REG(expr0->data.itm_exnum) : \
1150 ((expr0->type == ITM_EXPR_IN_VECTOR_D) ? \
1151 ((expr0->data.itm_exnum < 0) ? \
1152 (((-1) == expr0->data.itm_exnum) ? *inbytesleft : 0) : \
1153 ((expr0->data.itm_exnum < *inbytesleft) ? \
1154 (*(uchar_t *)(*inbuf + expr0->data.itm_exnum)) : 0)): \
1155 eval_expr(ist, operation->data.operand[(n)], \
1156 *inbytesleft, *inbuf, *outbytesleft)))))
1160 operation
= (itm_op_t
*)ADDR2(op_place
);
1162 switch (operation
->type
) {
1164 num
= eval_expr(ist
, operation
->data
.operand
[0],
1165 *inbytesleft
, *inbuf
, *outbytesleft
);
1166 TRACE_MESSAGE('o', ("ITM_OP_EXPR: %ld\n", retval
));
1169 num
= eval_expr(ist
, operation
->data
.operand
[0],
1170 *inbytesleft
, *inbuf
, *outbytesleft
);
1172 TRACE_MESSAGE('o', ("ITM_OP_ERROR: %ld\n", num
));
1173 retval
= (size_t)(-1);
1175 case ITM_OP_ERROR_D
:
1176 errno
= (int)operation
->data
.itm_opnum
;
1177 TRACE_MESSAGE('o', ("ITM_OP_ERROR_D: %d\n", errno
));
1178 retval
= (size_t)(-1);
1181 expr
= ADDR(operation
->data
.operand
[0]);
1182 if ((*outbytesleft
) == 0) {
1184 TRACE_MESSAGE('e', ("eval_op:error=%d\n", errno
));
1185 return ((size_t)(-1));
1187 c
= eval_expr(ist
, operation
->data
.operand
[0],
1188 *inbytesleft
, *inbuf
, *outbytesleft
);
1190 retval
= *inbytesleft
;
1191 TRACE_MESSAGE('o', ("ITM_OP_OUT: %ld %ld\n", c
, *inbytesleft
));
1194 expr
= ADDR(operation
->data
.operand
[0]);
1195 if ((*outbytesleft
) == 0) {
1197 TRACE_MESSAGE('e', ("eval_op:error=%d\n", errno
));
1198 return ((size_t)(-1));
1200 PUT(0xff & (expr
->data
.itm_exnum
));
1203 expr
= ADDR(operation
->data
.operand
[0]);
1204 if ((*outbytesleft
) == 0) {
1206 TRACE_MESSAGE('e', ("eval_op:error=%d\n", errno
));
1207 return ((size_t)(-1));
1209 z
= expr
->data
.value
.size
;
1210 if (*outbytesleft
< z
) {
1212 TRACE_MESSAGE('e', ("eval_op:error=%d\n", errno
));
1213 return ((size_t)(-1));
1215 p
= DADDR(&(expr
->data
.value
));
1216 for (; 0 < z
; --z
, p
++) {
1221 expr
= ADDR(operation
->data
.operand
[0]);
1222 if ((*outbytesleft
) == 0) {
1224 TRACE_MESSAGE('e', ("eval_op:error=%d\n", errno
));
1225 return ((size_t)(-1));
1227 c
= REG(expr
->data
.itm_exnum
);
1230 case ITM_OP_OUT_INVD
:
1231 expr
= ADDR(operation
->data
.operand
[0]);
1232 if ((*outbytesleft
) == 0) {
1234 TRACE_MESSAGE('e', ("eval_op:error=%d\n", errno
));
1235 return ((size_t)(-1));
1237 z
= (((0 <= expr
->data
.itm_exnum
) &&
1238 (expr
->data
.itm_exnum
< *inbytesleft
)) ?
1239 (*((unsigned char *)(*inbuf
+ expr
->data
.itm_exnum
))) :
1240 (((-1) == expr
->data
.itm_exnum
) ? *inbytesleft
: 0));
1243 case ITM_OP_DISCARD
:
1244 #if defined(EVAL_EXPR)
1246 #else /* !defined(EVAL_EXPR) */
1247 num
= eval_expr(ist
, operation
->data
.operand
[0],
1248 *inbytesleft
, *inbuf
, *outbytesleft
);
1249 #endif /* defined(EVAL_EXPR) */
1250 TRACE_MESSAGE('o', ("ITM_OP_DISCARD: %ld\n", num
));
1251 #if defined(DISCARD)
1252 DISCARD((num
<= *inbytesleft
) ? ((ulong_t
)num
) : *inbytesleft
);
1253 #else /* defined(DISCARD) */
1254 for (num
= ((num
<= *inbytesleft
) ? num
: *inbytesleft
);
1258 #endif /* defined(DISCARD) */
1260 case ITM_OP_DISCARD_D
:
1261 num
= operation
->data
.itm_opnum
;
1262 TRACE_MESSAGE('o', ("ITM_OP_DISCARD_D: %ld\n", num
));
1263 #if defined(DISCARD)
1264 DISCARD((num
<= *inbytesleft
) ? num
: *inbytesleft
);
1265 #else /* defined(DISCARD) */
1266 for (num
= ((num
<= *inbytesleft
) ? num
: *inbytesleft
);
1270 #endif /* defined(DISCARD) */
1273 c
= eval_expr(ist
, operation
->data
.operand
[0],
1274 *inbytesleft
, *inbuf
, *outbytesleft
);
1275 TRACE_MESSAGE('o', ("ITM_OP_IF: %ld\n", c
));
1277 retval
= eval_op_tbl(ist
, operation
->data
.operand
[1],
1278 inbuf
, inbytesleft
, outbuf
, outbytesleft
);
1281 case ITM_OP_IF_ELSE
:
1282 c
= eval_expr(ist
, operation
->data
.operand
[0],
1283 *inbytesleft
, *inbuf
, *outbytesleft
);
1284 TRACE_MESSAGE('o', ("ITM_OP_IF_ELSE: %ld\n", c
));
1286 retval
= eval_op_tbl(ist
, operation
->data
.operand
[1],
1287 inbuf
, inbytesleft
, outbuf
, outbytesleft
);
1289 retval
= eval_op_tbl(ist
, operation
->data
.operand
[2],
1290 inbuf
, inbytesleft
, outbuf
, outbytesleft
);
1293 case ITM_OP_DIRECTION
:
1294 TRACE_MESSAGE('o', ("ITM_OP_DIRECTION: %p\n",
1295 operation
->data
.operand
[0].itm_ptr
));
1296 ist
->direc
= ADDR(operation
->data
.operand
[0]);
1297 return ((size_t)(-2));
1299 TRACE_MESSAGE('o', ("ITM_OP_MAP: %p\n",
1300 operation
->data
.operand
[0].itm_ptr
));
1302 if (0 != operation
->data
.operand
[1].itm_ptr
) {
1303 #if defined(EVAL_EXPR)
1305 #else /* !defined(EVAL_EXPR) */
1306 i
= eval_expr(ist
, operation
->data
.operand
[1],
1307 *inbytesleft
, *inbuf
, *outbytesleft
);
1308 #endif /* defined(EVAL_EXPR) */
1309 (*inbytesleft
) -= i
;
1314 * Based on what is the maptype, we call the corresponding
1317 h
= ADDR(operation
->data
.operand
[0]);
1320 case ITM_TBL_MAP_INDEX_FIXED
:
1321 case ITM_TBL_MAP_INDEX_FIXED_1_1
:
1322 retval
= map_i_f(h
, inbuf
, inbytesleft
,
1323 outbuf
, outbytesleft
, 1);
1325 case ITM_TBL_MAP_HASH
:
1326 retval
= map_h_l(h
, inbuf
, inbytesleft
,
1327 outbuf
, outbytesleft
, 1);
1329 case ITM_TBL_MAP_DENSE_ENC
:
1330 retval
= map_d_e_l(h
, inbuf
, inbytesleft
,
1331 outbuf
, outbytesleft
, 1);
1333 case ITM_TBL_MAP_LOOKUP
:
1334 retval
= map_l_f(h
, inbuf
, inbytesleft
,
1335 outbuf
, outbytesleft
, 1);
1339 * This should not be possible, but in case we
1340 * have an incorrect maptype, don't fall back to
1341 * map_i_f(). Instead, because it is an error, return
1342 * an error. See CR 6622765.
1345 TRACE_MESSAGE('e', ("eval_op:error=%d\n", errno
));
1346 retval
= (size_t)-1;
1350 if ((size_t)(-1) == retval
) {
1351 (*outbytesleft
) += i
;
1355 case ITM_OP_OPERATION
:
1356 TRACE_MESSAGE('o', ("ITM_OP_OPERATION: %p\n",
1357 operation
->data
.operand
[0].itm_ptr
));
1358 retval
= eval_op_tbl(ist
, operation
->data
.operand
[0],
1359 inbuf
, inbytesleft
, outbuf
, outbytesleft
);
1363 TRACE_MESSAGE('o', ("ITM_OP_INIT: %p\n",
1364 ist
->itm_hdr
->op_init_tbl
));
1365 if (0 != ist
->itm_hdr
->op_init_tbl
.itm_ptr
) {
1366 retval
= eval_op_tbl(ist
, ist
->itm_hdr
->op_init_tbl
,
1367 inbuf
, inbytesleft
, outbuf
, outbytesleft
);
1369 op_init_default(ist
);
1370 retval
= (size_t)-2;
1374 TRACE_MESSAGE('o', ("ITM_OP_RESET: %p\n",
1375 ist
->itm_hdr
->op_reset_tbl
));
1376 if (0 != ist
->itm_hdr
->op_reset_tbl
.itm_ptr
) {
1377 retval
= eval_op_tbl(ist
, ist
->itm_hdr
->op_reset_tbl
,
1378 inbuf
, inbytesleft
, outbuf
, outbytesleft
);
1380 op_reset_default(ist
);
1381 retval
= (size_t)-2;
1385 TRACE_MESSAGE('o', ("ITM_OP_BREAK\n"));
1388 TRACE_MESSAGE('o', ("ITM_OP_RETURN\n"));
1390 case ITM_OP_PRINTCHR
:
1391 c
= eval_expr(ist
, operation
->data
.operand
[0], *inbytesleft
,
1392 *inbuf
, *outbytesleft
);
1393 (void) fputc((uchar_t
)c
, stderr
);
1394 TRACE_MESSAGE('o', ("ITM_OP_PRINTCHR: %ld %ld\n",
1397 case ITM_OP_PRINTHD
:
1398 c
= eval_expr(ist
, operation
->data
.operand
[0], *inbytesleft
,
1399 *inbuf
, *outbytesleft
);
1400 (void) fprintf(stderr
, "%lx", c
);
1401 TRACE_MESSAGE('o', ("ITM_OP_PRINTHD: %ld %ld\n",
1404 case ITM_OP_PRINTINT
:
1405 c
= eval_expr(ist
, operation
->data
.operand
[0], *inbytesleft
,
1406 *inbuf
, *outbytesleft
);
1407 (void) fprintf(stderr
, "%ld", c
);
1408 TRACE_MESSAGE('o', ("ITM_OP_PRINTINT: %ld %ld\n",
1411 default: /* never */
1413 TRACE_MESSAGE('e', ("eval_op:error=%d\n", errno
));
1414 return (size_t)(-1);
1423 * Evaluate expression
1428 itm_place_t expr_place
,
1430 const unsigned char *inbuf
,
1431 size_t outbytesleft
)
1434 itm_expr_t
*expr_op
;
1442 #define EVAL_EXPR_E(n) (eval_expr(ist, expr->data.operand[(n)], \
1443 inbytesleft, inbuf, outbytesleft))
1444 #define EVAL_EXPR_D(n) ((itm_num_t)(expr->data.operand[(n)].itm_ptr))
1445 #define EVAL_EXPR_R(n) (REG((itm_num_t)(expr->data.operand[(n)].itm_ptr)))
1446 #define EVAL_EXPR_INVD(n) \
1447 ((num0 ## n) = ((itm_num_t)(expr->data.operand[(n)].itm_ptr)), \
1448 ((num0 ## n) < 0) ? \
1449 (((-1) == (num0 ## n)) ? inbytesleft : 0) : \
1450 (((num0 ## n) < inbytesleft) ? \
1451 (*(unsigned char *)(inbuf + (num0 ## n))) : 0))
1452 #define EVAL_EXPR(n) \
1453 (expr0 = ADDR(expr->data.operand[(n)]), \
1454 (itm_num_t)((expr0->type == ITM_EXPR_INT) ? \
1455 expr0->data.itm_exnum : \
1456 ((expr0->type == ITM_EXPR_REG) ? \
1457 REG(expr0->data.itm_exnum) : \
1458 ((expr0->type == ITM_EXPR_IN_VECTOR_D) ? \
1459 ((expr0->data.itm_exnum < 0) ? \
1460 (((-1) == expr0->data.itm_exnum) ? inbytesleft : 0) : \
1461 ((expr0->data.itm_exnum < inbytesleft) ? \
1462 (*(uchar_t *)(inbuf + expr0->data.itm_exnum)) : 0)) : \
1463 eval_expr(ist, expr->data.operand[(n)], \
1464 inbytesleft, inbuf, outbytesleft)))))
1466 #define EVAL_OP_BIN_PROTO(op, name, name0, name1) \
1467 case ITM_EXPR_##name##_##name0##_##name1: \
1468 return (EVAL_EXPR_##name0(0) op EVAL_EXPR_##name1(1));
1470 #define EVAL_OP_BIN1(op, name) \
1471 EVAL_OP_BIN_PROTO(op, name, E, E) \
1472 EVAL_OP_BIN_PROTO(op, name, E, D) \
1473 EVAL_OP_BIN_PROTO(op, name, E, R) \
1474 EVAL_OP_BIN_PROTO(op, name, E, INVD)
1476 #define EVAL_OP_BIN2(op, name) \
1477 EVAL_OP_BIN_PROTO(op, name, D, E) \
1478 EVAL_OP_BIN_PROTO(op, name, D, D) \
1479 EVAL_OP_BIN_PROTO(op, name, D, R) \
1480 EVAL_OP_BIN_PROTO(op, name, D, INVD)
1482 #define EVAL_OP_BIN3(op, name) \
1483 EVAL_OP_BIN_PROTO(op, name, R, E) \
1484 EVAL_OP_BIN_PROTO(op, name, R, D) \
1485 EVAL_OP_BIN_PROTO(op, name, R, R) \
1486 EVAL_OP_BIN_PROTO(op, name, R, INVD)
1488 #define EVAL_OP_BIN4(op, name) \
1489 EVAL_OP_BIN_PROTO(op, name, INVD, E) \
1490 EVAL_OP_BIN_PROTO(op, name, INVD, D) \
1491 EVAL_OP_BIN_PROTO(op, name, INVD, R) \
1492 EVAL_OP_BIN_PROTO(op, name, INVD, INVD)
1494 #define EVAL_OP_BIN_PROTECT_PROTO(op, name, name0, name1) \
1495 case ITM_EXPR_##name##_##name0##_##name1: \
1496 num = EVAL_EXPR_##name1(1); \
1498 return (EVAL_EXPR_##name0(0) op num); \
1503 #define EVAL_OP_BIN_PROTECT1(op, name) \
1504 EVAL_OP_BIN_PROTECT_PROTO(op, name, E, E) \
1505 EVAL_OP_BIN_PROTECT_PROTO(op, name, E, D) \
1506 EVAL_OP_BIN_PROTECT_PROTO(op, name, E, R) \
1507 EVAL_OP_BIN_PROTECT_PROTO(op, name, E, INVD)
1509 #define EVAL_OP_BIN_PROTECT2(op, name) \
1510 EVAL_OP_BIN_PROTECT_PROTO(op, name, D, E) \
1511 EVAL_OP_BIN_PROTECT_PROTO(op, name, D, D) \
1512 EVAL_OP_BIN_PROTECT_PROTO(op, name, D, R) \
1513 EVAL_OP_BIN_PROTECT_PROTO(op, name, D, INVD)
1515 #define EVAL_OP_BIN_PROTECT3(op, name) \
1516 EVAL_OP_BIN_PROTECT_PROTO(op, name, R, E) \
1517 EVAL_OP_BIN_PROTECT_PROTO(op, name, R, D) \
1518 EVAL_OP_BIN_PROTECT_PROTO(op, name, R, R) \
1519 EVAL_OP_BIN_PROTECT_PROTO(op, name, R, INVD)
1521 #define EVAL_OP_BIN_PROTECT4(op, name) \
1522 EVAL_OP_BIN_PROTECT_PROTO(op, name, INVD, E) \
1523 EVAL_OP_BIN_PROTECT_PROTO(op, name, INVD, D) \
1524 EVAL_OP_BIN_PROTECT_PROTO(op, name, INVD, R) \
1525 EVAL_OP_BIN_PROTECT_PROTO(op, name, INVD, INVD)
1527 expr
= ADDR(expr_place
);
1529 switch (expr
->type
) {
1530 case ITM_EXPR_NONE
: /* not used */
1532 case ITM_EXPR_NOP
: /* not used */
1534 case ITM_EXPR_NAME
: /* not used */
1536 case ITM_EXPR_INT
: /* integer */
1537 return (expr
->data
.itm_exnum
);
1538 case ITM_EXPR_SEQ
: /* byte sequence */
1539 if ((sizeof (itm_place_t
)) < expr
->data
.value
.size
) {
1540 p
= (unsigned char *)ADDR(expr
->data
.value
.place
);
1542 p
= (unsigned char *)&(expr
->data
.value
.place
);
1544 for (i
= 0, num
= 0; i
< expr
->data
.value
.size
; i
++, p
++) {
1545 num
= ((num
<< 8) | *p
);
1548 case ITM_EXPR_REG
: /* register */
1549 return (REG(expr
->data
.itm_exnum
));
1550 case ITM_EXPR_IN_VECTOR
: /* in[expr] */
1552 if ((0 <= num
) && (num
< inbytesleft
)) {
1553 return (*((unsigned char *)(inbuf
+ num
)));
1554 } else if ((-1) == num
) {
1555 return (inbytesleft
);
1559 case ITM_EXPR_IN_VECTOR_D
: /* in[DECIMAL] */
1560 num
= expr
->data
.itm_exnum
;
1561 if ((0 <= num
) && (num
< inbytesleft
)) {
1562 return (*((unsigned char *)(inbuf
+ num
)));
1563 } else if ((-1) == num
) {
1564 return (inbytesleft
);
1568 case ITM_EXPR_OUT
: /* out */
1569 return (outbytesleft
);
1570 case ITM_EXPR_TRUE
: /* true */
1572 case ITM_EXPR_FALSE
: /* false */
1574 case ITM_EXPR_UMINUS
: /* unary minus */
1575 return ((-1) * EVAL_EXPR(0));
1576 #define PLUS_FOR_CSTYLE_CLEAN +
1577 #define MINUS_FOR_CSTYLE_CLEAN -
1578 #define MUL_FOR_CSTYLE_CLEAN *
1579 #define DIV_FOR_CSTYLE_CLEAN /
1580 #define MOD_FOR_CSTYLE_CLEAN %
1581 #define SHIFT_L_FOR_CSTYLE_CLEAN <<
1582 #define SHIFT_R_FOR_CSTYLE_CLEAN >>
1583 #define OR_FOR_CSTYLE_CLEAN |
1584 #define XOR_FOR_CSTYLE_CLEAN ^
1585 #define AND_FOR_CSTYLE_CLEAN &
1586 #define EQ_FOR_CSTYLE_CLEAN ==
1587 #define NE_FOR_CSTYLE_CLEAN !=
1588 #define GT_FOR_CSTYLE_CLEAN >
1589 #define GE_FOR_CSTYLE_CLEAN >=
1590 #define LT_FOR_CSTYLE_CLEAN <
1591 #define LE_FOR_CSTYLE_CLEAN <=
1592 EVAL_OP_BIN1(PLUS_FOR_CSTYLE_CLEAN
, PLUS
) /* A + B */
1593 EVAL_OP_BIN2(PLUS_FOR_CSTYLE_CLEAN
, PLUS
) /* A + B */
1594 EVAL_OP_BIN3(PLUS_FOR_CSTYLE_CLEAN
, PLUS
) /* A + B */
1595 EVAL_OP_BIN4(PLUS_FOR_CSTYLE_CLEAN
, PLUS
) /* A + B */
1597 EVAL_OP_BIN1(MINUS_FOR_CSTYLE_CLEAN
, MINUS
) /* A - B */
1598 EVAL_OP_BIN2(MINUS_FOR_CSTYLE_CLEAN
, MINUS
) /* A - B */
1599 EVAL_OP_BIN3(MINUS_FOR_CSTYLE_CLEAN
, MINUS
) /* A - B */
1600 EVAL_OP_BIN4(MINUS_FOR_CSTYLE_CLEAN
, MINUS
) /* A - B */
1602 EVAL_OP_BIN1(MUL_FOR_CSTYLE_CLEAN
, MUL
) /* A * B */
1603 EVAL_OP_BIN2(MUL_FOR_CSTYLE_CLEAN
, MUL
) /* A * B */
1604 EVAL_OP_BIN3(MUL_FOR_CSTYLE_CLEAN
, MUL
) /* A * B */
1605 EVAL_OP_BIN4(MUL_FOR_CSTYLE_CLEAN
, MUL
) /* A * B */
1607 EVAL_OP_BIN_PROTECT1(DIV_FOR_CSTYLE_CLEAN
, DIV
) /* A / B */
1608 EVAL_OP_BIN_PROTECT2(DIV_FOR_CSTYLE_CLEAN
, DIV
) /* A / B */
1609 EVAL_OP_BIN_PROTECT3(DIV_FOR_CSTYLE_CLEAN
, DIV
) /* A / B */
1610 EVAL_OP_BIN_PROTECT4(DIV_FOR_CSTYLE_CLEAN
, DIV
) /* A / B */
1612 EVAL_OP_BIN_PROTECT1(MOD_FOR_CSTYLE_CLEAN
, MOD
) /* A % B */
1613 EVAL_OP_BIN_PROTECT2(MOD_FOR_CSTYLE_CLEAN
, MOD
) /* A % B */
1614 EVAL_OP_BIN_PROTECT3(MOD_FOR_CSTYLE_CLEAN
, MOD
) /* A % B */
1615 EVAL_OP_BIN_PROTECT4(MOD_FOR_CSTYLE_CLEAN
, MOD
) /* A % B */
1617 EVAL_OP_BIN1(SHIFT_L_FOR_CSTYLE_CLEAN
, SHIFT_L
) /* A << B */
1618 EVAL_OP_BIN2(SHIFT_L_FOR_CSTYLE_CLEAN
, SHIFT_L
) /* A << B */
1619 EVAL_OP_BIN3(SHIFT_L_FOR_CSTYLE_CLEAN
, SHIFT_L
) /* A << B */
1620 EVAL_OP_BIN4(SHIFT_L_FOR_CSTYLE_CLEAN
, SHIFT_L
) /* A << B */
1622 EVAL_OP_BIN1(SHIFT_R_FOR_CSTYLE_CLEAN
, SHIFT_R
) /* A >> B */
1623 EVAL_OP_BIN2(SHIFT_R_FOR_CSTYLE_CLEAN
, SHIFT_R
) /* A >> B */
1624 EVAL_OP_BIN3(SHIFT_R_FOR_CSTYLE_CLEAN
, SHIFT_R
) /* A >> B */
1625 EVAL_OP_BIN4(SHIFT_R_FOR_CSTYLE_CLEAN
, SHIFT_R
) /* A >> B */
1627 EVAL_OP_BIN1(OR_FOR_CSTYLE_CLEAN
, OR
) /* A | B */
1628 EVAL_OP_BIN2(OR_FOR_CSTYLE_CLEAN
, OR
) /* A | B */
1629 EVAL_OP_BIN3(OR_FOR_CSTYLE_CLEAN
, OR
) /* A | B */
1630 EVAL_OP_BIN4(OR_FOR_CSTYLE_CLEAN
, OR
) /* A | B */
1632 EVAL_OP_BIN1(XOR_FOR_CSTYLE_CLEAN
, XOR
) /* A ^ B */
1633 EVAL_OP_BIN2(XOR_FOR_CSTYLE_CLEAN
, XOR
) /* A ^ B */
1634 EVAL_OP_BIN3(XOR_FOR_CSTYLE_CLEAN
, XOR
) /* A ^ B */
1635 EVAL_OP_BIN4(XOR_FOR_CSTYLE_CLEAN
, XOR
) /* A ^ B */
1637 EVAL_OP_BIN1(AND_FOR_CSTYLE_CLEAN
, AND
) /* A & B */
1638 EVAL_OP_BIN2(AND_FOR_CSTYLE_CLEAN
, AND
) /* A & B */
1639 EVAL_OP_BIN3(AND_FOR_CSTYLE_CLEAN
, AND
) /* A & B */
1640 EVAL_OP_BIN4(AND_FOR_CSTYLE_CLEAN
, AND
) /* A & B */
1642 EVAL_OP_BIN1(EQ_FOR_CSTYLE_CLEAN
, EQ
) /* A == B */
1643 EVAL_OP_BIN2(EQ_FOR_CSTYLE_CLEAN
, EQ
) /* A == B */
1644 EVAL_OP_BIN3(EQ_FOR_CSTYLE_CLEAN
, EQ
) /* A == B */
1645 EVAL_OP_BIN4(EQ_FOR_CSTYLE_CLEAN
, EQ
) /* A == B */
1647 EVAL_OP_BIN1(NE_FOR_CSTYLE_CLEAN
, NE
) /* A != B */
1648 EVAL_OP_BIN2(NE_FOR_CSTYLE_CLEAN
, NE
) /* A != B */
1649 EVAL_OP_BIN3(NE_FOR_CSTYLE_CLEAN
, NE
) /* A != B */
1650 EVAL_OP_BIN4(NE_FOR_CSTYLE_CLEAN
, NE
) /* A != B */
1652 EVAL_OP_BIN1(GT_FOR_CSTYLE_CLEAN
, GT
) /* A > B */
1653 EVAL_OP_BIN2(GT_FOR_CSTYLE_CLEAN
, GT
) /* A > B */
1654 EVAL_OP_BIN3(GT_FOR_CSTYLE_CLEAN
, GT
) /* A > B */
1655 EVAL_OP_BIN4(GT_FOR_CSTYLE_CLEAN
, GT
) /* A > B */
1657 EVAL_OP_BIN1(GE_FOR_CSTYLE_CLEAN
, GE
) /* A >= B */
1658 EVAL_OP_BIN2(GE_FOR_CSTYLE_CLEAN
, GE
) /* A >= B */
1659 EVAL_OP_BIN3(GE_FOR_CSTYLE_CLEAN
, GE
) /* A >= B */
1660 EVAL_OP_BIN4(GE_FOR_CSTYLE_CLEAN
, GE
) /* A >= B */
1662 EVAL_OP_BIN1(LT_FOR_CSTYLE_CLEAN
, LT
) /* A < B */
1663 EVAL_OP_BIN2(LT_FOR_CSTYLE_CLEAN
, LT
) /* A < B */
1664 EVAL_OP_BIN3(LT_FOR_CSTYLE_CLEAN
, LT
) /* A < B */
1665 EVAL_OP_BIN4(LT_FOR_CSTYLE_CLEAN
, LT
) /* A < B */
1667 EVAL_OP_BIN1(LE_FOR_CSTYLE_CLEAN
, LE
) /* A <= B */
1668 EVAL_OP_BIN2(LE_FOR_CSTYLE_CLEAN
, LE
) /* A <= B */
1669 EVAL_OP_BIN3(LE_FOR_CSTYLE_CLEAN
, LE
) /* A <= B */
1670 EVAL_OP_BIN4(LE_FOR_CSTYLE_CLEAN
, LE
) /* A <= B */
1672 case ITM_EXPR_NOT
: /* !A */
1673 return (!(EVAL_EXPR(0)));
1674 case ITM_EXPR_NEG
: /* ~A */
1675 return (~(EVAL_EXPR(0)));
1676 case ITM_EXPR_LOR
: /* A || B */
1677 if (0 != (num
= EVAL_EXPR(0)))
1679 if (0 != (num
= EVAL_EXPR(1)))
1682 case ITM_EXPR_LAND
: /* A && B */
1683 if (0 == EVAL_EXPR(0))
1685 if (0 == (num
= EVAL_EXPR(1)))
1688 case ITM_EXPR_ASSIGN
: /* A = B */
1690 if (expr
->data
.operand
[0].itm_ptr
< ist
->itm_hdr
->reg_num
) {
1691 return (*(ist
->regs
+ expr
->data
.operand
[0].itm_ptr
)
1696 case ITM_EXPR_IN_EQ
: /* in == A */
1697 expr_op
= ADDR(expr
->data
.operand
[0]);
1698 switch (expr_op
->type
) {
1700 if (inbytesleft
< expr_op
->data
.value
.size
) {
1703 p
= DADDR(&(expr_op
->data
.value
));
1704 for (i
= 0; i
< expr_op
->data
.value
.size
; i
++, p
++) {
1705 if (*p
!= *(inbuf
+ i
)) {
1712 return (num
== *((unsigned char *)inbuf
));
1723 #undef EVAL_EXPR_INVD
1729 * maintain ITM reference information
1732 itm_ref_free(int fd
, void *ptr0
, void *ptr1
, void *ptr2
, size_t len
)
1742 (void) munmap(ptr2
, len
);
1748 itm_ref_inc(const char *itm
)
1755 fd
= open(itm
, O_RDONLY
, 0);
1757 itm_ref_free(-1, NULL
, NULL
, NULL
, 0);
1761 if (fstat(fd
, &st
) == -1) {
1762 itm_ref_free(fd
, NULL
, NULL
, NULL
, 0);
1765 hdr
= mmap(NULL
, st
.st_size
, PROT_READ
, MAP_SHARED
, fd
, 0);
1766 if (MAP_FAILED
== hdr
) {
1767 itm_ref_free(fd
, NULL
, NULL
, NULL
, 0);
1773 ref
= malloc(sizeof (itm_ref_t
));
1775 itm_ref_free(-1, NULL
, NULL
, hdr
, st
.st_size
);
1778 ref
->name
= malloc(strlen(itm
) + 1);
1779 if (NULL
== ref
->name
) {
1780 itm_ref_free(-1, ref
, NULL
, hdr
, st
.st_size
);
1783 (void) strcpy(ref
->name
, itm
);
1785 ref
->len
= st
.st_size
;
1787 if ((hdr
->ident
[0] != ITM_IDENT_0
) ||
1788 (hdr
->ident
[1] != ITM_IDENT_1
) ||
1789 (hdr
->ident
[2] != ITM_IDENT_2
) ||
1790 (hdr
->ident
[3] != ITM_IDENT_3
) ||
1791 (hdr
->spec
[0] != ITM_SPEC_0
) ||
1792 (hdr
->spec
[1] != ITM_SPEC_1
) ||
1793 (hdr
->spec
[2] != ITM_SPEC_2
) ||
1794 #if defined(_LITTLE_ENDIAN)
1796 ((hdr
->spec
[3] != ITM_SPEC_3_32_LITTLE_ENDIAN
) &&
1797 (hdr
->spec
[3] != ITM_SPEC_3_64_LITTLE_ENDIAN
)) ||
1799 (hdr
->spec
[3] != ITM_SPEC_3_32_LITTLE_ENDIAN
) ||
1803 ((hdr
->spec
[3] != ITM_SPEC_3_32_BIG_ENDIAN
) &&
1804 (hdr
->spec
[3] != ITM_SPEC_3_64_BIG_ENDIAN
)) ||
1806 (hdr
->spec
[3] != ITM_SPEC_3_32_BIG_ENDIAN
) ||
1809 (hdr
->version
[0] != ITM_VER_0
) ||
1810 (hdr
->version
[1] != ITM_VER_1
) ||
1811 (hdr
->version
[2] != ITM_VER_2
) ||
1812 (hdr
->version
[3] != ITM_VER_3
) ||
1813 (((size_t)(hdr
->itm_size
.itm_ptr
)) != st
.st_size
)) {
1814 itm_ref_free(-1, ref
, ref
->name
, ref
->hdr
, ref
->len
);
1816 TRACE_MESSAGE('e', ("itm_ref_inc:error=%d\n", errno
));
1825 itm_ref_dec(itm_ref_t
*ref
)
1827 (void) munmap((char *)(ref
->hdr
), ref
->len
);
1834 op_init_default(icv_state_t
*ist
)
1836 ist
->direc
= ADDR(ist
->itm_hdr
->direc_init_tbl
);
1842 op_reset_default(icv_state_t
*ist
)
1844 ist
->direc
= ADDR(ist
->itm_hdr
->direc_init_tbl
);
1850 regs_init(icv_state_t
*ist
)
1852 if (0 < ist
->itm_hdr
->reg_num
) {
1853 (void) memset(ist
->regs
, 0,
1854 (sizeof (itm_num_t
)) * ist
->itm_hdr
->reg_num
);
1866 env_val
= getenv("ITM_INT_TRACE");
1867 if (NULL
== env_val
)
1870 for (p
= env_val
; *p
; p
++) {
1871 trace_option
[(*p
) & 0x007f] = 1;
1876 trace_message(char *format
, ...)
1880 va_start(ap
, format
);
1882 (void) vfprintf(stderr
, format
, ap
);