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