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