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 (c) 1999 by Sun Microsystems, Inc.
24 * All rights reserved.
25 * Copyright 2015 PALO, Richard.
26 */
27 #include <assert.h>
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <ctype.h>
31 #include <libintl.h>
32 #include <strings.h>
33 #include "iconv_tm.h"
34 #include "itmcomp.h"
35 #include "itm_util.h"
36 #include "hash.h"
37 #include "maptype.h"
38
39
40 static size_t map_table_resultlen(itmc_map_t *);
41 static int data_pair_compare(itmc_data_pair_t **, itmc_data_pair_t **);
42 static long data_to_long(itm_data_t *);
43
44 static itm_tbl_hdr_t *map_table_indexed_fixed(itmc_data_pair_t **,
45 itm_size_t, itm_data_t *, long, itm_num_t);
46 static itm_tbl_hdr_t *map_table_dense_encoding(itmc_data_pair_t **,
47 itm_size_t, itm_data_t *, unsigned long,
48 unsigned char *, unsigned char *, long,
49 itm_num_t);
50 static itm_tbl_hdr_t *map_table_lookup_fixed(itmc_data_pair_t **,
51 itm_size_t, itm_data_t *, long, itm_size_t);
52 static itm_tbl_hdr_t *map_table_hash(itmc_data_pair_t **, itm_size_t,
53 itm_data_t *, long, long, itm_size_t,
54 itm_num_t);
55 static itm_tbl_hdr_t *map_table_lookup_var();
56 static void put_dense_encoding_default(char *, unsigned char *,
57 unsigned char *, unsigned char *, long, long, long);
58 static size_t map_table_resultlen(itmc_map_t *);
59 static void map_range_adjust_byte_seq(unsigned char *,
60 unsigned char *, long, itmc_data_pair_t *);
61 static void map_range_make_result(char *, itm_size_t, itm_size_t,
62 char *, itm_size_t);
63 static size_t map_table_num_range(itmc_data_pair_t *);
64 static itmc_map_type_t check_map_type(itmc_map_attr_t *);
65
66
67 static itmc_name_t *name_lookup(itm_data_t *, itm_type_t);
68 static itmc_name_t *name_refer(itm_data_t *, itm_type_t, itmc_ref_t *);
69 static itmc_name_t *name_register(itm_data_t *, itm_type_t, itmc_ref_t *);
70 static void op_hirarchy(itm_tbl_hdr_t *, itmc_obj_t *);
71 static obj_array_t obj_list_to_array(itm_size_t, itmc_obj_t *, itm_size_t);
72
73
74 void
itm_def_process(itm_data_t * itm_name)75 itm_def_process(itm_data_t *itm_name)
76 {
77 itm_hdr_t *itm_hdr;
78 long len;
79
80 TRACE_MESSAGE('y', ("itm_def_process\n"));
81
82
83 itm_hdr = malloc_vital(sizeof (itm_hdr_t));
84 (void) memset(itm_hdr, 0, sizeof (itm_hdr_t));
85
86 if ((NULL != cmd_opt.interpreter) &&
87 (0 < (len = strlen(cmd_opt.interpreter)))) {
88 itm_hdr->interpreter = *(str_to_data(len, cmd_opt.interpreter));
89 }
90 if ((sizeof (itm_place_t)) < itm_hdr->interpreter.size) {
91 (void) obj_register(ITMC_OBJ_STRING, NULL,
92 (void *)itm_hdr->interpreter.place.itm_ptr,
93 itm_hdr->interpreter.size,
94 &(itm_hdr->interpreter.place),
95 OBJ_REG_HEAD);
96 }
97
98 itm_hdr->type_id = *itm_name;
99 if ((sizeof (itm_place_t)) < itm_hdr->type_id.size) {
100 (void) obj_register(ITMC_OBJ_STRING, NULL,
101 (void *)itm_hdr->type_id.place.itm_ptr,
102 itm_hdr->type_id.size,
103 &(itm_hdr->type_id.place),
104 OBJ_REG_HEAD);
105 }
106
107 (void) assemble(itm_hdr);
108 }
109
110
111
112 itmc_obj_t *
direction_unit(itmc_ref_t * cond,itm_data_t * cond_name,itmc_action_t * act,itm_data_t * act_name)113 direction_unit(
114 itmc_ref_t *cond,
115 itm_data_t *cond_name,
116 itmc_action_t *act,
117 itm_data_t *act_name)
118 {
119 itmc_obj_t *du;
120 itm_direc_t *direc;
121
122 du = malloc_vital(sizeof (itmc_obj_t));
123 du->type = ITMC_OBJ_DIREC;
124 du->name = NULL;
125 du->obj = direc = malloc_vital(sizeof (itm_direc_t));
126
127 if (NULL != cond) {
128 direc->condition.itm_ptr = (uintptr_t)NULL;
129 cond->referencer = &(direc->condition);
130 du->ref[0] = cond;
131 } else if (NULL != cond_name) {
132 direc->condition.itm_ptr = (itm_place2_t)(cond_name);
133 du->ref[0] = obj_register(ITMC_OBJ_COND, cond_name, NULL, 0,
134 &(direc->condition), OBJ_REG_TAIL);
135 } else {
136 direc->condition.itm_ptr = 0;
137 du->ref[0] = NULL;
138 }
139
140
141 if (NULL != act_name) {
142 direc->action.itm_ptr = (itm_place2_t)(act_name);
143 du->ref[1] = obj_register(ITMC_OBJ_ACTION, act_name, NULL, 0,
144 &(direc->action), OBJ_REG_TAIL);
145 } else if (NULL != act && act->tbl_hdr != NULL) {
146 direc->action.itm_ptr = (itm_place2_t)(act->tbl_hdr);
147 du->ref[1] = obj_register(act->type,
148 (itm_data_t *)(act->tbl_hdr->name.itm_ptr),
149 act->tbl_hdr, act->tbl_hdr->size,
150 &(direc->action), OBJ_REG_TAIL);
151 } else {
152 return (NULL);
153 }
154
155 du->ref[2] = NULL;
156 return (du);
157 }
158
159
160
161 itm_tbl_hdr_t *
obj_table(itm_type_t tbl_type,itm_data_t * name,itmc_obj_t * obj_list,itm_size_t obj_size)162 obj_table(itm_type_t tbl_type,
163 itm_data_t *name,
164 itmc_obj_t *obj_list,
165 itm_size_t obj_size)
166 {
167 itm_tbl_hdr_t *tbl;
168 obj_array_t obj_array;
169
170 obj_array = obj_list_to_array(sizeof (itm_tbl_hdr_t),
171 obj_list, obj_size);
172 tbl = obj_array.obj;
173
174 tbl->type = tbl_type;
175 if (name) {
176 #if !defined(_LP64)
177 tbl->name.itm_pad = 0;
178 #endif
179 tbl->name.itm_ptr = (itm_place2_t)name;
180 } else {
181 #if !defined(_LP64)
182 tbl->name.itm_pad = 0;
183 #endif
184 tbl->name.itm_ptr = (uintptr_t)NULL;
185 }
186 tbl->size = (sizeof (itm_tbl_hdr_t)) + (obj_array.num *obj_size);
187 tbl->number = obj_array.num;
188
189 if ((ITM_TBL_MASK&tbl->type) == ITM_TBL_OP) {
190 op_hirarchy(tbl, obj_list);
191 }
192 return (tbl);
193 }
194
195 /*
196 *
197 */
198 static obj_array_t
obj_list_to_array(itm_size_t hdr_size,itmc_obj_t * obj_list,itm_size_t size)199 obj_list_to_array(itm_size_t hdr_size, itmc_obj_t *obj_list,
200 itm_size_t size)
201 {
202 obj_array_t obj_array;
203 itm_size_t offset;
204 itmc_obj_t *ol;
205
206 for (obj_array.num = 0, ol = obj_list;
207 ol; obj_array.num += 1, ol = ol->next) {
208 /* NOP */;
209 }
210
211 obj_array.obj = malloc_vital(hdr_size + (size * obj_array.num));
212
213 if (obj_array.num == 0)
214 return (obj_array);
215
216 for (offset = hdr_size, ol = obj_list;
217 ol; offset += size, ol = ol->next) {
218 (void) memcpy((char *)(obj_array.obj) + offset, ol->obj, size);
219 if (ol->ref[0]) {
220 ol->ref[0]->referencer =
221 (void *)((char *)(ol->ref[0]->referencer) +
222 ((char *)(obj_array.obj) -
223 (char *)(ol->obj) + offset));
224 }
225 if (ol->ref[1]) {
226 ol->ref[1]->referencer =
227 (void *)((char *)(ol->ref[1]->referencer) +
228 ((char *)(obj_array.obj) -
229 (char *)(ol->obj) + offset));
230 }
231 if (ol->ref[2]) {
232 ol->ref[2]->referencer =
233 (void *)((char *)(ol->ref[2]->referencer) +
234 ((char *)(obj_array.obj) -
235 (char *)(ol->obj) + offset));
236 }
237 }
238
239 return (obj_array);
240 }
241
242 static void
op_hirarchy(itm_tbl_hdr_t * optbl,itmc_obj_t * obj_list)243 op_hirarchy(itm_tbl_hdr_t *optbl,
244 itmc_obj_t *obj_list)
245 {
246 itm_op_outer_t *o;
247 itm_op_inner_t *in;
248 itmc_obj_t *ol;
249
250 TRACE_MESSAGE('l', ("op_hirarchy (optbl=%x)\n", optbl));
251 o = malloc_vital(sizeof (itm_op_outer_t));
252 o->link = itm_op_outer;
253 itm_op_outer = o;
254 o->in = NULL;
255 o->optbl = optbl;
256
257 for (ol = obj_list; ol != NULL; ol = ol->next) {
258 if ((ol->type == ITMC_OBJ_OP) &&
259 (((itm_op_t *)ol->obj)->type == ITM_OP_OPERATION)) {
260 in = malloc_vital(sizeof (itm_op_inner_t));
261 in->in = o->in;
262 o->in = in;
263 TRACE_MESSAGE('L', ("o->in(%x) in->in(%x)\n",
264 o->in, in->in));
265 in->ref = ol->ref[0];
266 }
267 }
268
269 #ifdef ENABLE_TRACE
270 for (in = o->in; in != NULL; in = in->in) {
271 TRACE_MESSAGE('L', ("o=%x in=%x in->in=%x\n",
272 o, in, in->in));
273 TRACE_MESSAGE('L', ("o(table)%x->in(ref)=%x\n",
274 o->optbl, in->ref));
275 }
276 #endif
277
278 }
279
280 itmc_obj_t *
obj_list_append(itmc_obj_t * obj_list,itmc_obj_t * obj)281 obj_list_append(itmc_obj_t *obj_list, itmc_obj_t *obj)
282 {
283 if (0 == obj) {
284 return (obj_list);
285 }
286
287 obj->next = NULL;
288 obj->last = obj;
289
290 if (obj_list) {
291 obj_list->last->next = obj;
292 obj_list->last = obj;
293 return (obj_list);
294 } else {
295 return (obj);
296 }
297 }
298
299
300 itmc_ref_t *
obj_register(itm_type_t type,itm_data_t * name,void * obj,size_t size,itm_place_t * ref,itm_type_t reg_place)301 obj_register(itm_type_t type, itm_data_t *name,
302 void *obj, size_t size, itm_place_t *ref,
303 itm_type_t reg_place)
304 {
305 itmc_ref_t *refp;
306
307 TRACE_MESSAGE('O', ("obj_register: %6ld %08p %08p %08ld %08p %ld\n",
308 type, name, obj, size, ref, reg_place));
309
310 refp = malloc_vital(sizeof (itmc_ref_t));
311 refp->name = NULL;
312 refp->referencee = obj;
313 #if !defined(_LP64)
314 refp->reloc.itm_pad = 0;
315 #endif
316 refp->reloc.itm_ptr = 0;
317 refp->size = size;
318 refp->referencer = ref;
319 refp->next = NULL;
320
321 if (NULL == obj) { /* reference to named object */
322 if (NULL == name) {
323 if (0 == error_deferred) {
324 /* should never happen */
325 itm_error(
326 gettext("internal error: "
327 "obj_register: (NULL == obj) "
328 "&& (NULL == name)\n"));
329 exit(ITMC_STATUS_SYS2);
330 }
331 return (NULL);
332 }
333 refp->name = name_refer(name, type, refp);
334 return (refp);
335 } else if ((NULL != name) && (0 < name->size)) {
336 /* definition of named object */
337 refp->name = name_register(name, type, refp);
338 }
339
340 if ((ITMC_OBJ_FIRST <= type) && (type <= ITMC_OBJ_LAST)) {
341 switch (reg_place) {
342 case OBJ_REG_HEAD:
343 refp->next = ref_first[type];
344 ref_first[type] = refp;
345 if (NULL == ref_last[type]) {
346 ref_last[type] = refp;
347 }
348 break;
349 case OBJ_REG_TAIL:
350 if (ref_first[type]) {
351 ref_last[type]->next = refp;
352 } else {
353 ref_first[type] = refp;
354 }
355 ref_last[type] = refp;
356 break;
357 }
358 } else {
359 itm_error(gettext("obj_register: illegal object type\n"));
360 exit(ITMC_STATUS_SYS2);
361 }
362
363 return (refp);
364 }
365
366
367 itm_tbl_hdr_t *
range_table(itm_data_t * name,itmc_obj_t * obj_list)368 range_table(itm_data_t *name, itmc_obj_t *obj_list)
369 {
370 itm_num_t num;
371 itmc_obj_t *ol;
372 itmc_data_pair_t *rp;
373 itm_range_hdr_t *rh;
374 itm_tbl_hdr_t *table;
375 itm_size_t length = 0;
376 itm_num_t i;
377 char *p;
378 itm_size_t table_size;
379
380 /* count range, determine length */
381 for (num = 0, ol = obj_list; ol; ol = ol->next, num++) {
382 rp = (itmc_data_pair_t *)(ol->obj);
383 if (length == 0) {
384 if (rp->data0.size == 0) {
385 itm_error(gettext("between has null range\n"));
386 error_deferred += 1;
387 return (NULL);
388 }
389 length = rp->data0.size;
390 }
391 if ((rp->data0.size != length) ||
392 (rp->data1.size != length)) {
393 itm_error(gettext(
394 "length of source sequences must be the same\n"));
395 error_deferred += 1;
396 return (NULL);
397 }
398 }
399 if (num == 0) {
400 itm_error(gettext("between has no ranges\n"));
401 error_deferred += 1;
402 return (NULL);
403 }
404 table_size = ((sizeof (itm_tbl_hdr_t)) +
405 (sizeof (itm_range_hdr_t)) + (length * num) * 2);
406 table_size = ITMROUNDUP(table_size);
407
408 table = malloc_vital(table_size);
409 table->type = ITM_TBL_RANGE;
410 if (NULL != name)
411 table->name.itm_ptr = (itm_place2_t)name;
412 table->size = table_size;
413 table->number = num;
414
415 rh = (itm_range_hdr_t *)(table + 1);
416 rh->len = length;
417
418 p = (char *)(rh + 1);
419 for (ol = obj_list, i = 0; ol; ol = ol->next, i++) {
420 rp = (itmc_data_pair_t *)(ol->obj);
421 (void) memcpy(p, (NSPTR(&(rp->data0))), length);
422 p += length;
423 (void) memcpy(p, (NSPTR(&(rp->data1))), length);
424 p += length;
425 }
426
427 return (table);
428 }
429
430 /*
431 * escape sequence table for stateful code set sequence
432 */
433 itm_tbl_hdr_t *
escseq_table(itm_data_t * name,itmc_obj_t * obj_list)434 escseq_table(itm_data_t *name, itmc_obj_t *obj_list)
435 {
436 itm_num_t num;
437 itmc_obj_t *ol;
438 itm_data_t *ep;
439 itm_escapeseq_hdr_t *eh;
440 itm_tbl_hdr_t *table;
441 itm_size_t len_max = 0;
442 itm_size_t len_min;
443 itm_num_t i;
444 itm_size_t table_size;
445
446 ol = obj_list;
447 len_min = ((itm_data_t *)(ol->obj))->size;
448 for (num = 0; NULL != ol; ol = ol->next, num++) {
449 ep = (itm_data_t *)(ol->obj);
450 if (ep->size < len_min) len_min = ep->size;
451 if (ep->size > len_max) len_max = ep->size;
452 }
453 if (num == 0) {
454 itm_error(gettext
455 ("escape sequence is defined without sequence\n"));
456 error_deferred += 1;
457 return (NULL);
458 } else if (0 == len_min) {
459 itm_error(gettext("null sequence\n"));
460 error_deferred += 1;
461 return (NULL);
462 }
463
464 table_size = ((sizeof (itm_tbl_hdr_t)) +
465 (sizeof (itm_escapeseq_hdr_t)) +
466 (sizeof (itm_data_t) * num));
467 table_size = ITMROUNDUP(table_size);
468 table = malloc_vital(table_size);
469 table->type = ITM_TBL_ESCAPESEQ;
470 if (NULL != name)
471 table->name.itm_ptr = (itm_place2_t)name;
472 table->size = table_size;
473 table->number = num;
474
475 eh = (itm_escapeseq_hdr_t *)(table + 1);
476 eh->len_max = len_max;
477 eh->len_min = len_min;
478
479 for (ol = obj_list, ep = (itm_data_t *)(eh + 1);
480 ol != NULL;
481 ol = ol->next, ep++) {
482 *ep = *((itm_data_t *)(ol->obj));
483 if ((sizeof (itm_place_t)) < ep->size) {
484 (void) obj_register(ITMC_OBJ_DATA, NULL,
485 (void *)(ep->place.itm_ptr), ep->size,
486 &(ep->place), OBJ_REG_TAIL);
487 }
488 }
489 (void) qsort((itm_data_t *)(eh + 1), num, sizeof (itm_data_t),
490 (int (*)(const void *, const void *))data_compare);
491
492 for (i = 0, ep = (itm_data_t *)(eh + 1);
493 i < num - 1;
494 i++, ep++) {
495 if (0 <= data_compare(ep, (ep + 1))) {
496 itm_error(
497 gettext(
498 "same escape sequences are defined: "
499 "0x%1$s 0x%2$s\n"),
500 data_to_hexadecimal(ep),
501 data_to_hexadecimal(ep + 1));
502 error_deferred += 1;
503 return (NULL);
504 }
505 }
506 return (table);
507 }
508
509
510
511
512 itm_tbl_hdr_t *
map_table(itm_data_t * name,itmc_map_t * map_list,itmc_map_attr_t * attr)513 map_table(itm_data_t *name, itmc_map_t *map_list,
514 itmc_map_attr_t *attr)
515 {
516 itm_size_t num;
517 itm_size_t num2;
518 itmc_map_t *ml;
519 itmc_data_pair_t **tpp;
520 itm_tbl_hdr_t *table;
521 long source_len = 0;
522 long result_len = 0;
523 long source_fixed_len = 1;
524 long pass_through = 0;
525 long default_count = 0;
526 itm_data_t *default_data = NULL;
527 long error_deferred_local = 0;
528 unsigned long dense_encoded_map_ent;
529 unsigned long simple_indexed_map_ent;
530 itm_size_t source_start;
531 itm_size_t source_end;
532 unsigned long u;
533 unsigned char *byte_seq_min;
534 unsigned char *byte_seq_max;
535 unsigned char *p;
536 long i;
537 itmc_map_type_t map_type = ITMC_MAP_UNKNOWN;
538 itmc_map_name_type_t *map_name_type;
539 long hash_factor;
540 long result_len_specfied = 0;
541 size_t j;
542 long n;
543 itmc_data_pair_t **dp1;
544 itm_num_t error_count = 0;
545
546 if (attr != NULL) {
547 map_type = check_map_type(attr);
548 }
549 if (ITMC_MAP_UNKNOWN == map_type) {
550 map_type = ITMC_MAP_AUTOMATIC;
551 }
552 hash_factor = ((NULL != attr) && (attr->hash_factor != 0)) ?
553 attr->hash_factor :
554 200;
555
556 map_name_type = cmd_opt.map_name_type;
557 for (; map_name_type; map_name_type = map_name_type->next) {
558 if ('\0' == *(map_name_type->name)) {
559 map_type = map_name_type->type;
560 hash_factor = map_name_type->hash_factor;
561 break;
562 }
563 }
564 map_name_type = cmd_opt.map_name_type;
565 if ((NULL != name) && (NULL != cmd_opt.map_name_type)) {
566 p = NSPTR(name);
567 for (; map_name_type; map_name_type = map_name_type->next) {
568 if (0 == strcmp(map_name_type->name, (char *)p)) {
569 map_type = map_name_type->type;
570 hash_factor = map_name_type->hash_factor;
571 break;
572 }
573 }
574 }
575
576 if (NULL != attr) {
577 if (MAXSEQUENCE < attr->resultlen) {
578 itm_error(
579 gettext("output_byte_length must be less than %1$d\n"),
580 MAXSEQUENCE);
581 error_deferred += 1;
582 return (NULL);
583 }
584 result_len_specfied = attr->resultlen;
585 } else {
586 result_len_specfied = 0;
587 }
588
589 for (num = 0, ml = map_list; ml; ml = ml->next, num++) {
590
591 /* default */
592 if (0 == ml->data_pair.data0.size) {
593 if (0 == ml->data_pair.data1.size) {
594 pass_through += 1;
595 default_data = (itm_data_t *)(-1);
596 } else {
597 default_count += 1;
598 default_data = &(ml->data_pair.data1);
599 }
600 --num;
601
602
603 } else if (0 == ml->data_pair.data1.size) {
604 /* error source sequence */
605 continue;
606 }
607
608 /* fixed length */
609 if ((0 < source_len) &&
610 (0 < ml->data_pair.data0.size) &&
611 (source_len != ml->data_pair.data0.size)) {
612 source_fixed_len = 0;
613 }
614
615 /* maximum length */
616 if (source_len < ml->data_pair.data0.size) {
617 source_len = ml->data_pair.data0.size;
618 }
619 if (result_len < ml->data_pair.data1.size) {
620 result_len = ml->data_pair.data1.size;
621 }
622
623 /* map source has range */
624 if (0 < ml->data_pair.range.size) {
625 if (ml->data_pair.range.size !=
626 ml->data_pair.data0.size) {
627 itm_error(
628 gettext("length of source range must be "
629 "the same: 0x%1$s 0x%2$s\n"),
630 data_to_hexadecimal(&(ml->data_pair.data0)),
631 data_to_hexadecimal(
632 &(ml->data_pair.range)));
633 error_deferred += 1;
634 return (NULL);
635 }
636 if (0 <= data_compare(&(ml->data_pair.data0),
637 &((ml->data_pair.range)))) {
638 itm_error(
639 gettext("source range error: 0x%1$s 0x%2$s\n"),
640 data_to_hexadecimal(
641 &(ml->data_pair.data0)),
642 data_to_hexadecimal(
643 &(ml->data_pair.range)));
644 error_deferred += 1;
645 return (NULL);
646 }
647 j = map_table_resultlen(ml);
648 if (result_len < j) {
649 result_len = j;
650 }
651 }
652 }
653 if (num == 0) {
654 itm_error(
655 gettext("no mapping pair\n"));
656 error_deferred += 1;
657 return (NULL);
658 }
659
660 if (0 != result_len_specfied) {
661 if (result_len > result_len_specfied) {
662 itm_error(
663 gettext("result value length is "
664 "over specifed output_byte_length(%1$ld)\n"),
665 result_len_specfied);
666 error_deferred += 1;
667 return (NULL);
668 }
669 result_len = result_len_specfied;
670 }
671 byte_seq_min = malloc_vital((sizeof (unsigned char)) * source_len);
672 byte_seq_max = malloc_vital((sizeof (unsigned char)) * source_len);
673 for (num = 0, ml = map_list; ml; ml = ml->next, num++) {
674 if (0 == ml->data_pair.data0.size) {
675 continue;
676 }
677
678 p = (unsigned char *)(NSPTR(&((ml->data_pair).data0)));
679 for (i = 0; i < source_len; i++) {
680 *(byte_seq_min + i) = *(p + i);
681 *(byte_seq_max + i) = *(p + i);
682 }
683 break;
684 }
685 for (num = 0, ml = map_list; ml; ml = ml->next, num++) {
686 if (0 == ml->data_pair.data0.size) {
687 num--;
688 continue;
689 }
690 if (ml->data_pair.range.size > 0) {
691 map_range_adjust_byte_seq(byte_seq_min, byte_seq_max,
692 source_len, &(ml->data_pair));
693 } else {
694 p = (unsigned char *)(NSPTR(&((ml->data_pair).data0)));
695 for (i = 0; i < source_len; i++) {
696 if (*(p + i) < *(byte_seq_min + i)) {
697 *(byte_seq_min + i) = *(p + i);
698 }
699 if (*(byte_seq_max + i) < *(p + i)) {
700 *(byte_seq_max + i) = *(p + i);
701 }
702 }
703 }
704 }
705 for (dense_encoded_map_ent = 1, i = 0; i < source_len; i++) {
706 u = dense_encoded_map_ent;
707 dense_encoded_map_ent *=
708 (*(byte_seq_max + i) - *(byte_seq_min + i) + 1);
709 if (dense_encoded_map_ent < u) {
710 dense_encoded_map_ent = (ulong_t)(~0);
711 break;
712 }
713 }
714 #if defined(DEBUG)
715 if (TRACE('m')) {
716 int i;
717 TRACE_MESSAGE('m', ("map_table: ent=%lu num=%lu ",
718 dense_encoded_map_ent, num));
719 TRACE_MESSAGE('m', ("byte_seq_min=0x"));
720 for (i = 0; i < source_len; i++) {
721 TRACE_MESSAGE('m', ("%02x", *(byte_seq_min + i)));
722 }
723 TRACE_MESSAGE('m', (" byte_seq_max=0x"));
724 for (i = 0; i < source_len; i++) {
725 TRACE_MESSAGE('m', ("%02x", *(byte_seq_max + i)));
726 }
727 TRACE_MESSAGE('m', ("\n"));
728 }
729 #endif /* DEBUG */
730
731 tpp = malloc_vital((sizeof (itmc_data_pair_t *)) * num);
732 for (num = 0, num2 = 0, ml = map_list; ml; ml = ml->next) {
733 if (0 < ml->data_pair.data0.size) {
734 itm_num_t range_num;
735 *(tpp + num) = &(ml->data_pair);
736 num++;
737 range_num = 1;
738 if (ml->data_pair.range.size > 0) {
739 range_num +=
740 map_table_num_range(&(ml->data_pair));
741 }
742 num2 += range_num;
743 if (0 == ml->data_pair.data1.size) {
744 /* specified error sequence */
745 error_count += range_num;
746 }
747 }
748 }
749 (void) qsort(tpp, num, sizeof (itmc_data_pair_t *),
750 (int (*)(const void *, const void *))data_pair_compare);
751
752 /* check if map_pair range and next map_pair are overrapped */
753 for (n = 0, dp1 = tpp; n < (num-1); n++, dp1++) {
754 if (((*(dp1+0))->range.size != 0) &&
755 (0 <= data_compare(&((*(dp1+0))->range),
756 &((*(dp1+1))->data0)))) {
757 itm_error(
758 gettext("ranges of source sequences "
759 "overrapped: %1$s %2$s\n"),
760 data_to_hexadecimal(&((*(dp1+0))->range)),
761 data_to_hexadecimal(&((*(dp1+1))->data0)));
762 error_deferred += 1;
763 return (NULL);
764 }
765 }
766
767 if (1 < default_count) {
768 itm_error(
769 gettext("default is specified %1$d times in a map\n"),
770 default_count);
771 error_deferred_local += 1;
772 }
773 if ((1 == default_count) && (!source_fixed_len)) {
774 itm_error(
775 gettext("default is specified,"
776 " but length of source data is not fixed\n"));
777 error_deferred_local += 1;
778 }
779 if ((1 <= pass_through) && (source_len != result_len)) {
780 itm_error(
781 gettext("\"default no_change_copy\" is "
782 "specified, but size does not match\n"));
783 error_deferred_local += 1;
784 }
785
786 if (error_deferred_local) {
787 error_deferred += error_deferred_local;
788 return (NULL);
789 }
790
791 if (source_fixed_len) {
792 source_start = data_to_long(&((*(tpp + 0))->data0));
793 source_end = data_to_long(&((*(tpp + num - 1))->data0));
794 if (0 < (*(tpp + num - 1))->range.size) {
795 source_end = data_to_long(&((*(tpp + num - 1))->range));
796 }
797
798 simple_indexed_map_ent = source_end - source_start + 1;
799
800 TRACE_MESSAGE('m', ("map_table: simple_indexed_map_ent=%lu\n",
801 simple_indexed_map_ent));
802
803 switch (map_type) {
804 case ITMC_MAP_AUTOMATIC:
805 if ((source_len <= 2) &&
806 (((ulong_t)(~0) == dense_encoded_map_ent) ||
807 (simple_indexed_map_ent <
808 (dense_encoded_map_ent * 2)))) {
809 /*
810 * for small source sequence,
811 * if dense table is not so large
812 * compared with simple table,
813 * use simple.
814 */
815 map_type = ITMC_MAP_SIMPLE_INDEX;
816 } else if (cmd_opt.large_table) {
817 if ((sizeof (long)) < source_len) {
818 itm_error(
819 gettext("length of source is too long "
820 "for large table: %ld\n"),
821 source_len);
822 error_deferred += 1;
823 return (NULL);
824 }
825 map_type = ITMC_MAP_SIMPLE_INDEX;
826 } else if (((ulong_t)(~0) == dense_encoded_map_ent) ||
827 ((0xffff < dense_encoded_map_ent) &&
828 ((num2 * 8) < dense_encoded_map_ent))) {
829 /*
830 * if dense can be used and not too large
831 * ( less than (hash table entry * 8),
832 * use dense.
833 */
834 map_type = ITMC_MAP_SIMPLE_HASH;
835 } else {
836 map_type = ITMC_MAP_DENSE_ENCODING;
837 }
838 break;
839 case ITMC_MAP_SIMPLE_INDEX:
840 if ((sizeof (long)) < source_len) {
841 itm_error(
842 gettext("length of source is too long "
843 "for index lookup: %ld\n"),
844 source_len);
845 error_deferred += 1;
846 return (NULL);
847 }
848 break;
849 case ITMC_MAP_SIMPLE_HASH:
850 for (i = 2, u = 256; i < (sizeof (long)); i++) {
851 u *= 256;
852 }
853 if (u < num2) {
854 itm_error(
855 gettext("map is too large for hashing: %lu\n"),
856 num2);
857 error_deferred += 1;
858 return (NULL);
859 }
860 break;
861 case ITMC_MAP_DENSE_ENCODING:
862 for (i = 2, u = 256; i < (sizeof (long)); i++) {
863 u *= 256;
864 }
865 if (u < dense_encoded_map_ent) {
866 itm_error(
867 gettext(
868 "map is too large for dense encoding: "
869 "%lu\n"),
870 dense_encoded_map_ent);
871 error_deferred += 1;
872 return (NULL);
873 }
874 break;
875 case ITMC_MAP_BINARY_SEARCH:
876 for (i = 2, u = 256; i < (sizeof (long)); i++) {
877 u *= 256;
878 }
879 if (u < num2) {
880 itm_error(
881 gettext("length of source is too long for "
882 "binary search: %ld\n"),
883 source_len);
884 error_deferred += 1;
885 return (NULL);
886 }
887 break;
888 default:
889 break;
890 }
891 switch (map_type) {
892 case ITMC_MAP_SIMPLE_INDEX:
893 table = map_table_indexed_fixed(
894 tpp, num, default_data,
895 result_len, error_count);
896 break;
897 case ITMC_MAP_SIMPLE_HASH:
898 table = map_table_hash(tpp, num, default_data,
899 hash_factor, result_len, num2,
900 error_count);
901 break;
902 case ITMC_MAP_DENSE_ENCODING:
903 table = map_table_dense_encoding(tpp, num,
904 default_data,
905 dense_encoded_map_ent,
906 byte_seq_min, byte_seq_max,
907 result_len, error_count);
908 break;
909 case ITMC_MAP_BINARY_SEARCH:
910 table = map_table_lookup_fixed(tpp, num,
911 default_data,
912 result_len, num2);
913 break;
914 }
915 } else {
916 table = map_table_lookup_var();
917 }
918
919 if ((NULL != name) && (NULL != table)) {
920 table->name.itm_ptr = (itm_place2_t)name;
921 }
922
923 return (table);
924 }
925
926
927 static itmc_map_type_t
check_map_type(itmc_map_attr_t * attr)928 check_map_type(itmc_map_attr_t *attr)
929 {
930 int i;
931
932 if (NULL == attr->type) {
933 return (0);
934 }
935 for (i = 0; NULL != map_type_name[i].name; i++) {
936 if (0 == strncmp(((char *)&(attr->type->place)),
937 map_type_name[i].name, attr->type->size)) {
938 return (map_type_name[i].type);
939 }
940 }
941 return (0);
942 }
943
944
945 static itm_tbl_hdr_t *
map_table_indexed_fixed(itmc_data_pair_t ** tpp,itm_size_t num,itm_data_t * default_data,long resultlen,itm_num_t error_count)946 map_table_indexed_fixed(
947 itmc_data_pair_t **tpp,
948 itm_size_t num,
949 itm_data_t *default_data,
950 long resultlen,
951 itm_num_t error_count)
952 {
953 itm_tbl_hdr_t *header;
954 itm_map_idx_fix_hdr_t *sub_hdr;
955 char *table;
956 char *error_table;
957 itm_size_t source_start;
958 itm_size_t source_end;
959 itm_size_t entry_num;
960 itm_size_t table_size;
961 itm_size_t j;
962 itm_size_t i;
963 itm_size_t k;
964 char *p;
965 itm_data_t *source;
966
967 TRACE_MESSAGE('m', ("map_table_range : %ld\n", num));
968
969 source = &((*(tpp + 0))->data0);
970 assert((sizeof (itm_place_t)) >= source->size);
971
972 if ((1 == source->size) &&
973 (1 == resultlen)) {
974 source_start = 0;
975 source_end = 255;
976 } else {
977 source_start = data_to_long(&((*(tpp + 0))->data0));
978 source_end = data_to_long(&((*(tpp + num - 1))->data0));
979 if (0 < (*(tpp + num - 1))->range.size)
980 source_end = data_to_long(&((*(tpp + num - 1))->range));
981 }
982
983 entry_num = source_end - source_start + 1;
984
985 table_size = ((sizeof (itm_tbl_hdr_t)) +
986 (sizeof (itm_map_idx_fix_hdr_t)) +
987 (resultlen * entry_num));
988 if (0 < error_count) {
989 table_size += entry_num;
990 }
991 if (NULL == default_data) {
992 if ((num < entry_num) ||
993 (error_count <= 0)) {
994 table_size += entry_num;
995 }
996 } else if ((itm_data_t *)(-1) != default_data) {
997 table_size += resultlen;
998 }
999
1000 table_size = ITMROUNDUP(table_size);
1001 header = malloc_vital(table_size);
1002 sub_hdr = (itm_map_idx_fix_hdr_t *)(header + 1);
1003 table = (char *)(sub_hdr + 1);
1004
1005 if ((1 == (*tpp)->data0.size) &&
1006 (1 == (*tpp)->data1.size)) {
1007 header->type = ITM_TBL_MAP_INDEX_FIXED_1_1;
1008 } else {
1009 header->type = ITM_TBL_MAP_INDEX_FIXED;
1010 }
1011 header->name.itm_ptr = 0;
1012 header->size = table_size;
1013 header->number = entry_num;
1014
1015 sub_hdr->source_len = (*tpp)->data0.size;
1016 sub_hdr->result_len = resultlen;
1017 sub_hdr->start.itm_ptr = source_start;
1018 sub_hdr->end.itm_ptr = source_end;
1019 sub_hdr->error_num = error_count; /* > 0; so pad4 = 0 */
1020
1021 if (NULL != default_data) {
1022 if ((itm_data_t *)(-1) == default_data) {
1023 sub_hdr->default_error = -1;
1024 #if !defined(_LP64)
1025 sub_hdr->pad3_num = (pad_t)(~0);
1026 #endif
1027 } else {
1028 sub_hdr->default_error = 0;
1029 }
1030 } else {
1031 if (num < entry_num) {
1032 sub_hdr->default_error = 1;
1033 } else {
1034 sub_hdr->default_error = 2;
1035 }
1036 }
1037
1038 error_table = (table + (resultlen * entry_num));
1039 if (-1 == sub_hdr->default_error) {
1040 if (source->size != resultlen) {
1041 itm_error(
1042 gettext("\"default no_change_copy\" is "
1043 "specified, but size does not match\n"));
1044 exit(ITMC_STATUS_BT);
1045 }
1046
1047 for (i = 0, j = 0;
1048 i < (entry_num);
1049 i++, j += resultlen) {
1050 for (k = 0; k < resultlen; k++) {
1051 *(table + j + k) =
1052 (((source_start + i) >>
1053 ((resultlen - k - 1) * 8)) &
1054 0x00ff);
1055 }
1056 }
1057 } else if (0 == sub_hdr->default_error) {
1058 error_table += resultlen;
1059 if (default_data->size <= (sizeof (itm_place_t))) {
1060 for (i = 0, j = 0;
1061 i < (entry_num + 1); /* last one is for default */
1062 i++, j += resultlen) {
1063 (void) memcpy(table + j +
1064 (resultlen - default_data->size),
1065 (void *)(&(default_data->place.itm_64d)),
1066 default_data->size);
1067 }
1068 } else {
1069 for (i = 0, j = 0;
1070 i < (entry_num + 1); /* last one is for default */
1071 i++, j += resultlen) {
1072 (void) memcpy(table + j +
1073 (resultlen - default_data->size),
1074 (void *)(default_data->place.itm_ptr),
1075 default_data->size);
1076 }
1077 }
1078 }
1079 if (1 == sub_hdr->default_error) {
1080 (void) memset(error_table, 1, entry_num);
1081 for (i = 0; i < num; i++) {
1082 if (0 == (*(tpp + i))->data1.size) {
1083 continue; /* error sequence */
1084 }
1085 j = data_to_long(&((*(tpp + i))->data0)) -
1086 source_start;
1087 k = ((*(tpp + i))->range.size) == 0 ? j :
1088 data_to_long(&((*(tpp + i))->range)) -
1089 source_start;
1090 for (; j <= k; j++) {
1091 *(error_table + j) = 0;
1092 }
1093 }
1094 } else if (0 < error_count) {
1095 (void) memset(error_table, 0, entry_num);
1096 for (i = 0; i < num; i++) {
1097 if (0 == (*(tpp + i))->data1.size) {
1098 /* error sequence */
1099 j = data_to_long(&((*(tpp + i))->data0)) -
1100 source_start;
1101 k = ((*(tpp + i))->range.size) == 0 ? j :
1102 data_to_long(&((*(tpp + i))->range)) -
1103 source_start;
1104 for (; j <= k; j++) {
1105 *(error_table + j) = 1;
1106 }
1107 }
1108 }
1109 }
1110
1111 p = malloc_vital(sizeof (uchar_t *) * resultlen);
1112 for (i = 0; i < num; i++) {
1113 j = data_to_long(&((*(tpp + i))->data0)) - source_start;
1114 if (0 != (*(tpp + i))->range.size)
1115 k = data_to_long(&((*(tpp + i))->range)) -
1116 source_start;
1117 else
1118 k = j;
1119 (void) memset(p, 0, sizeof (uchar_t *) * resultlen);
1120 (void) memcpy(p + (resultlen - (*(tpp + i))->data1.size),
1121 ((caddr_t)NSPTR(&((*(tpp + i))->data1))),
1122 (*(tpp + i))->data1.size);
1123 map_range_make_result(table, j, k, p, resultlen);
1124 }
1125 free(p);
1126
1127 return (header);
1128 }
1129
1130
1131
1132
1133 static itm_tbl_hdr_t *
map_table_lookup_fixed(itmc_data_pair_t ** tpp,itm_size_t num,itm_data_t * default_data,long resultlen,itm_size_t num2)1134 map_table_lookup_fixed(
1135 itmc_data_pair_t **tpp,
1136 itm_size_t num,
1137 itm_data_t *default_data,
1138 long resultlen,
1139 itm_size_t num2)
1140 {
1141 itm_tbl_hdr_t *header;
1142 itm_map_lookup_hdr_t *sub_hdr;
1143 char *table;
1144 itm_size_t table_size;
1145 itm_size_t j;
1146 itm_size_t i;
1147 itm_size_t k;
1148 itm_size_t h;
1149 itm_data_t *source;
1150 uchar_t *source_data;
1151 uchar_t *result_data;
1152
1153 TRACE_MESSAGE('m', ("map_table_lookup_fixed : %ld(%ld) 0x%lx\n",
1154 num, num2, default_data));
1155
1156 source = &((*(tpp + 0))->data0);
1157
1158 table_size = ((sizeof (itm_tbl_hdr_t)) +
1159 (sizeof (itm_map_idx_fix_hdr_t)) +
1160 ((source->size + 1 + resultlen) * num2));
1161 if ((NULL != default_data) &&
1162 (((itm_data_t *)(-1)) != default_data)) {
1163 table_size += (source->size + 1 + resultlen);
1164 }
1165 table_size = ITMROUNDUP(table_size);
1166 header = malloc_vital(table_size);
1167 sub_hdr = (itm_map_lookup_hdr_t *)(header + 1);
1168 table = (char *)(sub_hdr + 1);
1169
1170 header->type = ITM_TBL_MAP_LOOKUP;
1171 header->name.itm_ptr = 0;
1172 header->size = table_size;
1173 header->number = num2;
1174 if (NULL != default_data) {
1175 if ((itm_data_t *)(-1) == default_data) {
1176 #if !defined(_LP64)
1177 sub_hdr->pad3_num = (pad_t)(~0);
1178 #endif
1179 sub_hdr->default_error = -1;
1180 } else {
1181 sub_hdr->default_error = 0;
1182 }
1183 } else {
1184 sub_hdr->default_error = 2;
1185 }
1186
1187 sub_hdr->source_len = source->size;
1188 sub_hdr->result_len = resultlen;
1189
1190 /* specified map */
1191 source_data = malloc_vital(source->size);
1192 result_data = malloc_vital(resultlen);
1193 for (i = 0, j = 0; i < num; i++) {
1194 (void) memcpy(table + j,
1195 NSPTR(&((*(tpp + i))->data0)), source->size);
1196 j += source->size;
1197 if (0 == (*(tpp + i))->data1.size) {
1198 *(table + j) = 1; /* specified error */
1199 j += 1;
1200 } else {
1201 /* *(table + j) = 0; ** valid */
1202 j += 1;
1203 (void) memcpy(table + j +
1204 (resultlen - (*(tpp + i))->data1.size),
1205 NSPTR(&((*(tpp + i))->data1)),
1206 (*(tpp + i))->data1.size);
1207 }
1208 j += resultlen;
1209
1210 if ((*(tpp + i))->range.size != 0) {
1211 (void) memcpy(source_data,
1212 NSPTR(&((*(tpp + i))->data0)),
1213 source->size);
1214 (void) memset(result_data, 0, resultlen);
1215 (void) memcpy(result_data +
1216 (resultlen - (*(tpp + i))->data1.size),
1217 NSPTR(&((*(tpp + i))->data1)),
1218 (*(tpp + i))->data1.size);
1219 h = map_table_num_range((*(tpp + i)));
1220 for (k = 0; k < h; k++) {
1221 uchar_t *dp;
1222 itm_size_t m;
1223
1224 for (m = 0,
1225 dp = (uchar_t *)
1226 (source_data + source->size - 1);
1227 m < source->size;
1228 m++, dp--) {
1229 if (0xff != *dp) {
1230 (*dp) += (char)1;
1231 for (++dp; m > 0; m--, dp++) {
1232 (*dp) = 0x00;
1233 }
1234 break;
1235 }
1236 }
1237 (void) memcpy(table + j,
1238 source_data, source->size);
1239 j += source->size;
1240
1241 if (0 == (*(tpp + i))->data1.size) {
1242 *(table + j) = 1; /* specified error */
1243 j += 1;
1244 } else {
1245 /* *(table + j) = 0; ** valid */
1246 j += 1;
1247 for (m = 0, dp = (uchar_t *)
1248 (result_data + resultlen - 1);
1249 m < resultlen;
1250 m++, dp--) {
1251 if (0xff != *dp) {
1252 (*dp) += 1;
1253 for (++dp;
1254 m > 0;
1255 m--, dp++) {
1256 (*dp) = 0x00;
1257 }
1258 break;
1259 }
1260 }
1261 (void) memcpy(table + j, result_data,
1262 resultlen);
1263 }
1264 j += resultlen;
1265 }
1266 }
1267 }
1268 free(source_data);
1269 free(result_data);
1270
1271 /* default */
1272 if ((NULL != default_data) &&
1273 (((itm_data_t *)(-1)) != default_data)) {
1274 (void) memset(table + j, 0, source->size + 1 + resultlen);
1275 (void) memcpy(table + j + source->size + 1 +
1276 (resultlen - default_data->size),
1277 NSPTR(default_data), default_data->size);
1278 }
1279 return (header);
1280 }
1281
1282
1283
1284
1285 static itm_tbl_hdr_t *
map_table_hash(itmc_data_pair_t ** tpp,itm_size_t num,itm_data_t * default_data,long hash_factor,long resultlen,itm_size_t num2,itm_num_t error_count)1286 map_table_hash(
1287 itmc_data_pair_t **tpp,
1288 itm_size_t num,
1289 itm_data_t *default_data,
1290 long hash_factor,
1291 long resultlen,
1292 itm_size_t num2,
1293 itm_num_t error_count)
1294 {
1295 itm_tbl_hdr_t *header;
1296 itm_map_hash_hdr_t *sub_hdr;
1297 itm_size_t table_size;
1298 char *error_table;
1299 char *hash_table;
1300 itm_size_t hash_table_num;
1301 char *of_table;
1302 itm_size_t of_table_num;
1303 itm_size_t pair_size;
1304 itm_size_t i;
1305 itm_size_t j;
1306 itm_size_t k;
1307 char *p;
1308 itm_data_t *source;
1309 long hash_value;
1310 #if defined(DEBUG)
1311 long hash_none;
1312 long hash_one;
1313 long hash_conflict;
1314 #endif /* DEBUG */
1315 uchar_t *source_data;
1316 uchar_t *result_data;
1317 uchar_t *dp;
1318 itm_size_t m;
1319 itm_size_t n;
1320 itm_size_t h;
1321
1322 TRACE_MESSAGE('m', ("map_table_hash : %ld(%ld) 0x%lx\n",
1323 num, num2, default_data));
1324 source = &((*(tpp + 0))->data0);
1325 pair_size = (source->size + 1 + resultlen);
1326
1327 if (100 <= hash_factor) {
1328 hash_table_num = (num2 * (hash_factor / 100.0));
1329 } else {
1330 hash_table_num = (num2 * 2);
1331 }
1332 if (hash_table_num < 256) {
1333 hash_table_num = 256;
1334 }
1335 source_data = malloc_vital(source->size);
1336 result_data = malloc_vital(resultlen);
1337
1338 hash_table = malloc_vital(hash_table_num);
1339 for (i = 0, of_table_num = 0; i < num; i++) {
1340 hash_value = hash(NSPTR(&((*(tpp + i))->data0)),
1341 (*(tpp + i))->data0.size,
1342 hash_table_num);
1343 if (0 == *(hash_table + hash_value)) {
1344 *(hash_table + hash_value) = 1;
1345 } else {
1346 *(hash_table + hash_value) = 2;
1347 of_table_num += 1;
1348 }
1349
1350 if ((*(tpp + i))->range.size != 0) {
1351 (void) memcpy(source_data,
1352 NSPTR(&((*(tpp + i))->data0)),
1353 source->size);
1354 h = map_table_num_range((*(tpp + i)));
1355 for (n = 0; n < h; n++) {
1356 for (m = 0,
1357 dp = (uchar_t *)
1358 (source_data + source->size - 1);
1359 m < source->size;
1360 m++, dp--) {
1361 if (0xff != *dp) {
1362 (*dp) += 1;
1363 for (++dp; m > 0; m--, dp++) {
1364 (*dp) = 0x00;
1365 }
1366 break;
1367 }
1368 }
1369 hash_value = hash((char *)source_data,
1370 source->size,
1371 hash_table_num);
1372
1373 if (0 == *(hash_table + hash_value)) {
1374 *(hash_table + hash_value) = 1;
1375 } else {
1376 *(hash_table + hash_value) = 2;
1377 of_table_num += 1;
1378 }
1379 }
1380 }
1381 }
1382
1383 #if defined(DEBUG)
1384 if (TRACE('s')) {
1385 hash_none = 0;
1386 hash_one = 0;
1387 hash_conflict = 0;
1388 j = 0;
1389 for (i = 0; i < hash_table_num; i++) {
1390 if (2 == *(hash_table + i)) {
1391 (void) putchar('2');
1392 hash_conflict += 1;
1393 } else if (1 == *(hash_table + i)) {
1394 (void) putchar('1');
1395 hash_one += 1;
1396 } else if (0 == *(hash_table + i)) {
1397 (void) putchar('-');
1398 hash_none += 1;
1399 } else {
1400 (void) putchar('*');
1401 }
1402 if (63 <= j) {
1403 j = 0;
1404 (void) putchar('\n');
1405 } else {
1406 j += 1;
1407 }
1408 }
1409 (void) putchar('\n');
1410 (void) printf("null=%ld one=%ld conflict=%ld\n",
1411 hash_none, hash_one, hash_conflict);
1412 }
1413 #endif /* DEBUG */
1414
1415 free(hash_table);
1416 table_size = ((sizeof (itm_tbl_hdr_t)) +
1417 (sizeof (itm_map_hash_hdr_t)) +
1418 (hash_table_num) +
1419 (pair_size * hash_table_num) +
1420 (pair_size * of_table_num));
1421 if ((NULL != default_data) &&
1422 (((itm_data_t *)(-1)) != default_data)) {
1423 table_size += pair_size;
1424 }
1425 table_size = ITMROUNDUP(table_size);
1426 header = malloc_vital(table_size);
1427 sub_hdr = (itm_map_hash_hdr_t *)(header + 1);
1428 error_table = (char *)(sub_hdr + 1);
1429 hash_table = error_table + hash_table_num;
1430 of_table = hash_table + (pair_size * hash_table_num);
1431
1432 header->type = ITM_TBL_MAP_HASH;
1433 header->name.itm_ptr = 0;
1434 header->size = table_size;
1435 header->number = num2;
1436 if (NULL != default_data) {
1437 if ((itm_data_t *)(-1) == default_data) {
1438 sub_hdr->default_error = -1;
1439 #if !defined(_LP64)
1440 sub_hdr->pad7_num = (pad_t)(~0);
1441 #endif
1442 } else {
1443 sub_hdr->default_error = 0;
1444 }
1445 } else {
1446 sub_hdr->default_error = 2;
1447 }
1448
1449 sub_hdr->source_len = source->size;
1450 sub_hdr->result_len = resultlen;
1451 sub_hdr->hash_tbl_size = (pair_size * hash_table_num);
1452 sub_hdr->hash_tbl_num = hash_table_num;
1453 sub_hdr->hash_of_size =
1454 (pair_size * of_table_num);
1455 sub_hdr->hash_of_num = of_table_num;
1456 sub_hdr->error_num = error_count; /* > 0; so pad4 = 0 */
1457
1458 /* specified map */
1459 for (i = 0, j = 0, k = 0; i < num; i++) {
1460 hash_value = hash(NSPTR(&((*(tpp + i))->data0)),
1461 (*(tpp + i))->data0.size,
1462 hash_table_num);
1463 p = error_table + hash_value;
1464 if (*p) { /* conflict */
1465 if (*p < 63) {
1466 *p += 1;
1467 }
1468 p = of_table + k;
1469 k += pair_size;
1470 } else {
1471 *p = 1;
1472 p = hash_table + (pair_size * hash_value);
1473 }
1474
1475 (void) memcpy(p, NSPTR(&((*(tpp + i))->data0)), source->size);
1476 p += source->size;
1477 if (0 == (*(tpp + i))->data1.size) {
1478 (*p) = 1; /* specified error */
1479 p++;
1480 } else {
1481 /* (*p) = 0; ** valid */
1482 p++;
1483 (void) memset(p, 0,
1484 (resultlen - (*(tpp + i))->data1.size));
1485 (void) memcpy(p +
1486 (resultlen - (*(tpp + i))->data1.size),
1487 NSPTR(&((*(tpp + i))->data1)),
1488 (*(tpp + i))->data1.size);
1489 }
1490
1491 if ((*(tpp + i))->range.size != 0) {
1492 (void) memcpy(source_data,
1493 NSPTR(&((*(tpp + i))->data0)),
1494 source->size);
1495 (void) memset(result_data, 0,
1496 (resultlen - (*(tpp + i))->data1.size));
1497 (void) memcpy(result_data +
1498 (resultlen - (*(tpp + i))->data1.size),
1499 NSPTR(&((*(tpp + i))->data1)),
1500 (*(tpp + i))->data1.size);
1501 h = map_table_num_range((*(tpp + i)));
1502 for (n = 0; n < h; n++) {
1503 for (m = 0,
1504 dp = (uchar_t *)
1505 (source_data + source->size - 1);
1506 m < source->size;
1507 m++, dp--) {
1508 if (0xff != *dp) {
1509 (*dp) += 1;
1510 for (++dp; m > 0; m--, dp++) {
1511 (*dp) = 0x00;
1512 }
1513 break;
1514 }
1515 }
1516
1517 hash_value = hash((char *)source_data,
1518 source->size,
1519 hash_table_num);
1520 p = error_table + hash_value;
1521 if (*p) { /* conflict */
1522 if (*p < 63) {
1523 *p += 1;
1524 }
1525 p = of_table + k;
1526 k += pair_size;
1527 } else {
1528 *p = 1;
1529 p = hash_table +
1530 (pair_size * hash_value);
1531 }
1532 (void) memcpy(p, source_data, source->size);
1533 p += source->size;
1534
1535 if (0 == (*(tpp + i))->data1.size) {
1536 (*p) = 1; /* specified error */
1537 p += 1;
1538 } else {
1539 /* (*p) = 0; ** valid */
1540 p += 1;
1541 for (m = 0, dp = (uchar_t *)
1542 (result_data + resultlen - 1);
1543 m < resultlen;
1544 m++, dp--) {
1545 if (0xff != *dp) {
1546 (*dp) += 1;
1547 for (++dp; m > 0;
1548 m--, dp++) {
1549 (*dp) = 0x00;
1550 }
1551 break;
1552 }
1553 }
1554 (void) memcpy(p,
1555 result_data, resultlen);
1556 }
1557 }
1558 }
1559 }
1560 free(source_data);
1561 free(result_data);
1562
1563 /* default */
1564 if ((NULL != default_data) &&
1565 (((itm_data_t *)(-1)) != default_data)) {
1566 j = ((pair_size * hash_table_num) +
1567 (pair_size * of_table_num));
1568 (void) memcpy(hash_table + j + (resultlen - default_data->size),
1569 NSPTR(default_data), default_data->size);
1570 }
1571 #if defined(ENABLE_TRACE)
1572 for (i = 0, p = of_table; i < of_table_num; i++, p += 5) {
1573 (void) printf("0x%02x%02x%02x%02x 0x%02x\n",
1574 ((unsigned char)(*(p + 0))),
1575 ((unsigned char)(*(p + 1))),
1576 ((unsigned char)(*(p + 2))),
1577 ((unsigned char)(*(p + 3))),
1578 ((unsigned char)(*(p + 4))));
1579 }
1580 #endif
1581 return (header);
1582 }
1583
1584
1585
1586
1587 static itm_tbl_hdr_t *
map_table_dense_encoding(itmc_data_pair_t ** tpp,itm_size_t num,itm_data_t * default_data,unsigned long entry_num,unsigned char * byte_seq_min,unsigned char * byte_seq_max,long resultlen,itm_num_t error_count)1588 map_table_dense_encoding(
1589 itmc_data_pair_t **tpp,
1590 itm_size_t num,
1591 itm_data_t *default_data,
1592 unsigned long entry_num,
1593 unsigned char *byte_seq_min,
1594 unsigned char *byte_seq_max,
1595 long resultlen,
1596 itm_num_t error_count)
1597 {
1598
1599 itm_tbl_hdr_t *header;
1600 itm_map_dense_enc_hdr_t *sub_hdr;
1601 char *table;
1602 char *error_table;
1603 itm_size_t table_size;
1604 itm_size_t j;
1605 itm_size_t i;
1606 itm_size_t k;
1607 char *p;
1608 itm_data_t *source;
1609 unsigned char *byte_seq_def;
1610
1611 TRACE_MESSAGE('m', ("map_table_dense_encoding : %ld\n", num));
1612
1613 source = &((*(tpp + 0))->data0);
1614
1615
1616 table_size = ((sizeof (itm_tbl_hdr_t)) +
1617 (sizeof (itm_map_dense_enc_hdr_t)) +
1618 (source->size + source->size) +
1619 (resultlen * entry_num));
1620 if (0 < error_count) {
1621 table_size += entry_num;
1622 }
1623 if (NULL == default_data) {
1624 if ((num < entry_num) ||
1625 (error_count <= 0)) {
1626 table_size += entry_num;
1627 }
1628 } else if ((itm_data_t *)(-1) != default_data) {
1629 table_size += resultlen;
1630 }
1631
1632 table_size = ITMROUNDUP(table_size);
1633 header = malloc_vital(table_size);
1634 sub_hdr = (itm_map_dense_enc_hdr_t *)(header + 1);
1635 table = (char *)(sub_hdr + 1) + source->size + source->size;
1636
1637 header->type = ITM_TBL_MAP_DENSE_ENC;
1638 header->name.itm_ptr = 0;
1639 header->size = table_size;
1640 header->number = entry_num;
1641
1642 sub_hdr->source_len = (*tpp)->data0.size;
1643 sub_hdr->result_len = resultlen;
1644 sub_hdr->error_num = error_count; /* > 0; so pad4 = 0 */
1645
1646 if (NULL != default_data) {
1647 if ((itm_data_t *)(-1) == default_data) {
1648 sub_hdr->default_error = -1;
1649 #if !defined(_LP64)
1650 sub_hdr->pad3_num = (pad_t)(~0);
1651 #endif
1652
1653 } else {
1654 sub_hdr->default_error = 0;
1655 }
1656 } else {
1657 if (num < entry_num) {
1658 sub_hdr->default_error = 1;
1659 } else {
1660 sub_hdr->default_error = 2;
1661 }
1662 }
1663
1664 (void) memcpy((char *)(sub_hdr + 1), byte_seq_min, source->size);
1665 (void) memcpy((char *)(sub_hdr + 1) + source->size,
1666 byte_seq_max, source->size);
1667
1668 if (-1 == sub_hdr->default_error) {
1669 byte_seq_def = malloc_vital((sizeof (unsigned char *)) *
1670 resultlen);
1671 if (source->size != resultlen) {
1672 itm_error(
1673 gettext("\"default no_change_copy\" is "
1674 "specified, but size does not match\n"));
1675 exit(ITMC_STATUS_BT);
1676 }
1677 put_dense_encoding_default(
1678 table, byte_seq_min, byte_seq_max, byte_seq_def,
1679 resultlen - 1, 0, 0);
1680 free(byte_seq_def);
1681 } else if (0 == sub_hdr->default_error) {
1682 if (default_data->size <= (sizeof (itm_place_t))) {
1683 for (i = 0, j = 0;
1684 i < (entry_num + 1); /* 1:default data */
1685 i++, j += resultlen) {
1686 (void) memcpy(table + j +
1687 (resultlen - default_data->size),
1688 (void *)(&(default_data->place.itm_64d)),
1689 default_data->size);
1690 }
1691 } else {
1692 for (i = 0, j = 0;
1693 i < (entry_num + 1); /* 1:default data */
1694 i++, j += resultlen) {
1695 (void) memcpy(table + j +
1696 (resultlen - default_data->size),
1697 (void *)(default_data->place.itm_ptr),
1698 default_data->size);
1699 }
1700 }
1701 }
1702 if (1 == sub_hdr->default_error) {
1703 (void) memset(table + (resultlen * entry_num), 1, entry_num);
1704 error_table = (table + (resultlen * entry_num));
1705 for (i = 0; i < num; i++) {
1706 if (0 == (*(tpp + i))->data1.size) {
1707 continue; /* error sequence */
1708 }
1709 j = hash_dense_encoding(NSPTR(&((*(tpp + i))->data0)),
1710 (*(tpp + i))->data0.size,
1711 byte_seq_min, byte_seq_max);
1712 k = ((*(tpp + i))->range.size) == 0 ? j :
1713 hash_dense_encoding(NSPTR(&((*(tpp + i))->range)),
1714 (*(tpp + i))->data0.size,
1715 byte_seq_min, byte_seq_max);
1716 for (; j <= k; j++) {
1717 *(error_table + j) = 0;
1718 }
1719 }
1720 } else if (0 < error_count) {
1721 error_table = (table + (resultlen * entry_num));
1722 if (0 == sub_hdr->default_error) {
1723 error_table += resultlen;
1724 }
1725 (void) memset(error_table, 0, entry_num);
1726 for (i = 0; i < num; i++) {
1727 if (0 == (*(tpp + i))->data1.size) {
1728 j = hash_dense_encoding(
1729 NSPTR(&((*(tpp + i))->data0)),
1730 (*(tpp + i))->data0.size,
1731 byte_seq_min, byte_seq_max);
1732 k = ((*(tpp + i))->range.size) == 0 ? j :
1733 hash_dense_encoding(
1734 NSPTR(&((*(tpp + i))->range)),
1735 (*(tpp + i))->data0.size,
1736 byte_seq_min, byte_seq_max);
1737 for (; j <= k; j++) {
1738 *(error_table + j) = 1; /* specified */
1739 }
1740 }
1741 }
1742 }
1743
1744
1745 p = malloc_vital(resultlen);
1746 for (i = 0; i < num; i++) {
1747 j = hash_dense_encoding(NSPTR(&((*(tpp + i))->data0)),
1748 (*(tpp + i))->data0.size,
1749 byte_seq_min, byte_seq_max);
1750
1751 if (0 != (*(tpp + i))->range.size)
1752 k = hash_dense_encoding(
1753 NSPTR(&((*(tpp + i))->range)),
1754 (*(tpp + i))->range.size,
1755 byte_seq_min, byte_seq_max);
1756 else
1757 k = j;
1758 (void) memset(p, 0, (resultlen - (*(tpp + i))->data1.size));
1759 (void) memcpy(p + (resultlen - (*(tpp + i))->data1.size),
1760 ((caddr_t)NSPTR(&((*(tpp + i))->data1))),
1761 (*(tpp + i))->data1.size);
1762 map_range_make_result(table, j, k, p, resultlen);
1763 }
1764 free(p);
1765
1766 return (header);
1767 }
1768
1769
1770 static void
put_dense_encoding_default(char * table,unsigned char * byte_seq_min,unsigned char * byte_seq_max,unsigned char * byte_seq_def,long pos_max,long position,long dense_encoded_value)1771 put_dense_encoding_default(
1772 char *table,
1773 unsigned char *byte_seq_min,
1774 unsigned char *byte_seq_max,
1775 unsigned char *byte_seq_def,
1776 long pos_max,
1777 long position,
1778 long dense_encoded_value)
1779 {
1780 uchar_t i;
1781
1782 if (position < pos_max) {
1783 for (i = *(byte_seq_min + position);
1784 i <= *(byte_seq_max + position); i++) {
1785 *(byte_seq_def + position) = i;
1786 put_dense_encoding_default(
1787 table,
1788 byte_seq_min, byte_seq_max,
1789 byte_seq_def,
1790 pos_max, position + 1,
1791 ((dense_encoded_value + i) *
1792 (*(byte_seq_max + position) -
1793 *(byte_seq_min + position) + 1)));
1794 }
1795 return;
1796 }
1797
1798 for (i = *(byte_seq_min + position);
1799 i <= *(byte_seq_max + position); i++) {
1800 *(byte_seq_def + position) = i;
1801 (void) memcpy(table +
1802 ((pos_max + 1) * (dense_encoded_value + i - 1)),
1803 byte_seq_def, pos_max + 1);
1804 }
1805 }
1806
1807
1808 char *
dense_enc_index_to_byte_seq(long value,long length,unsigned char * byte_seq_min,unsigned char * byte_seq_max)1809 dense_enc_index_to_byte_seq(
1810 long value,
1811 long length,
1812 unsigned char *byte_seq_min,
1813 unsigned char *byte_seq_max)
1814 {
1815 static char *buf;
1816 static long buf_len;
1817 char *p;
1818 int i;
1819 int l;
1820 int residue;
1821
1822 if (buf_len < (2 + (length * 2) + 1)) {
1823 free(buf);
1824 buf_len = (2 + (length * 2) + 1) + 16;
1825 buf = malloc_vital(buf_len);
1826 }
1827
1828 *(buf + (length * 2)) = '\0';
1829 *(buf + 0) = '0';
1830 *(buf + 1) = 'x';
1831 p = buf + 2;
1832 for (i = length - 1; 0 <= i; --i) {
1833 residue = value % (*(byte_seq_max + i) -
1834 *(byte_seq_min + i) + 1);
1835 value /= (*(byte_seq_max + i) -
1836 *(byte_seq_min + i) + 1);
1837
1838 residue += *(byte_seq_min + i);
1839 l = ((0xf0 & residue) >> 4);
1840 if (l < 10) {
1841 *(p + (i * 2)) = ('0' + l);
1842 } else {
1843 *(p + (i * 2)) = ('a' + l - 10);
1844 }
1845 l = (0x0f & residue);
1846 if (l < 10) {
1847 *(p + (i * 2) + 1) = ('0' + l);
1848 } else {
1849 *(p + (i * 2) + 1) = ('a' + l - 10);
1850 }
1851 }
1852 return (buf);
1853 }
1854
1855
1856 itm_tbl_hdr_t *
map_table_lookup_var()1857 map_table_lookup_var()
1858 {
1859 itm_error(gettext(
1860 "length of all source sequences must be the same\n"));
1861 error_deferred += 1;
1862 return (NULL);
1863 }
1864
1865
1866
1867 static void
map_range_adjust_byte_seq(unsigned char * byte_seq_min,unsigned char * byte_seq_max,long source_len,itmc_data_pair_t * pair)1868 map_range_adjust_byte_seq(
1869 unsigned char *byte_seq_min,
1870 unsigned char *byte_seq_max,
1871 long source_len,
1872 itmc_data_pair_t *pair)
1873 {
1874 unsigned char *p, *p2;
1875 int i;
1876 int flag;
1877
1878 p = (unsigned char *)(NSPTR(&((pair)->data0)));
1879 p2 = (unsigned char *)(NSPTR(&((pair)->range)));
1880 flag = 0;
1881 for (i = 0; i < source_len; i++) {
1882 if (flag != 0) {
1883 break;
1884 }
1885 if (*(p + i) != *(p2 + i))
1886 flag = 1;
1887 if (*(p + i) < *(byte_seq_min + i)) {
1888 *(byte_seq_min + i) = *(p + i);
1889 }
1890 if (*(byte_seq_max + i) < *(p2 + i)) {
1891 *(byte_seq_max + i) = *(p2 + i);
1892 }
1893 }
1894 for (; i < source_len; i++) {
1895 *(byte_seq_min + i) = 0x00;
1896 *(byte_seq_max + i) = 0xff;
1897 }
1898 }
1899
1900 /*
1901 * result value + (source range value - source base value)
1902 * and just caluculate its length
1903 */
1904 static size_t
map_table_resultlen(itmc_map_t * ml)1905 map_table_resultlen(itmc_map_t *ml)
1906 {
1907 size_t j;
1908 size_t len;
1909 int m;
1910 uchar_t *c1;
1911 uchar_t *c2;
1912 uchar_t *c3;
1913
1914 j = ml->data_pair.data0.size;
1915 if (j < ml->data_pair.data1.size) j = ml->data_pair.data1.size;
1916 if (j < ml->data_pair.range.size) j = ml->data_pair.range.size;
1917 c1 = (uchar_t *)(NSPTR(&((ml->data_pair).data0))) +
1918 ml->data_pair.data0.size - 1;
1919 c2 = (uchar_t *)(NSPTR(&((ml->data_pair).data1))) +
1920 ml->data_pair.data1.size - 1;
1921 c3 = (uchar_t *)(NSPTR(&((ml->data_pair.range)))) +
1922 ml->data_pair.range.size - 1;
1923 m = 0;
1924 for (len = 0; len < j; len++, c1--, c2--, c3--) {
1925 if (len < ml->data_pair.data0.size) m -= *c1;
1926 if (len < ml->data_pair.data1.size) m += *c2;
1927 if (len < ml->data_pair.range.size) m += *c3;
1928 m >>= 8;
1929 }
1930 if (m > 0) {
1931 len += 1;
1932 }
1933 TRACE_MESSAGE('g', ("map_table_resutlen: source(0x%s..0x%s), "
1934 "result(0x%s.... len= %ld)\n",
1935 data_to_hexadecimal(&(ml->data_pair.data0)),
1936 data_to_hexadecimal(&(ml->data_pair.range)),
1937 data_to_hexadecimal(&(ml->data_pair.data1)),
1938 len));
1939 return (len);
1940 }
1941
1942 /*
1943 *
1944 */
1945 static void
map_range_make_result(char * table,itm_size_t range_start,itm_size_t range_end,char * result_data,itm_size_t result_size)1946 map_range_make_result(
1947 char *table,
1948 itm_size_t range_start,
1949 itm_size_t range_end,
1950 char *result_data,
1951 itm_size_t result_size)
1952 {
1953 itm_size_t i;
1954 itm_size_t j;
1955 itm_size_t p;
1956 uchar_t *dp; /* unsigned for ++ operation */
1957
1958 for (i = range_start, p = i * result_size;
1959 i <= range_end; i++, p += result_size) {
1960 (void) memcpy(table + p, result_data, result_size);
1961 for (j = 0, dp = (uchar_t *)(result_data + result_size - 1);
1962 j < result_size;
1963 j++, dp--) {
1964 if (0xff != *dp) {
1965 (*dp) += 1;
1966 for (++dp; j > 0; j--, dp++) {
1967 (*dp) = 0x00;
1968 }
1969 break;
1970 }
1971 }
1972 }
1973 }
1974
1975 /*
1976 *
1977 */
1978 static size_t
map_table_num_range(itmc_data_pair_t * pair)1979 map_table_num_range(itmc_data_pair_t *pair)
1980 {
1981 size_t i, j;
1982 itm_num_t num;
1983 itm_num_t num2;
1984 uchar_t *c1;
1985 uchar_t *c2;
1986
1987 assert(0 < pair->range.size);
1988 j = pair->data0.size;
1989 if (j < pair->range.size)
1990 j = pair->range.size;
1991 c1 = ((uchar_t *)(NSPTR(&(pair->data0)))) + pair->data0.size - 1;
1992 c2 = ((uchar_t *)(NSPTR(&(pair->range)))) + pair->range.size - 1;
1993 num = 0;
1994 for (i = 0; i < j; i++, c1--, c2--) {
1995 if (i < pair->range.size) num2 = *c2;
1996 if (i < pair->data0.size) num2 -= *c1;
1997 TRACE_MESSAGE('G', (" num += %d(=%d-%d)\n ",
1998 *c2 - *c1, *c2, *c1));
1999 num2 <<= (i*8);
2000 num += num2;
2001 }
2002 TRACE_MESSAGE('g', ("map_table_num_range: source(0x%s..0x%s), "
2003 "num= %ld\n",
2004 data_to_hexadecimal(&(pair->data0)),
2005 data_to_hexadecimal(&(pair->range)),
2006 num));
2007 return (num);
2008 }
2009
2010 /*
2011 *
2012 */
2013 itmc_map_t *
map_list_append(itmc_map_t * map_list,itmc_map_t * map_pair)2014 map_list_append(itmc_map_t *map_list, itmc_map_t *map_pair)
2015 {
2016 if (0 == map_pair) {
2017 return (map_list);
2018 }
2019
2020 map_pair->next = NULL;
2021 map_pair->last = map_pair;
2022
2023 if (map_list) {
2024 map_list->last->next = map_pair;
2025 map_list->last = map_pair;
2026 return (map_list);
2027 } else {
2028 return (map_pair);
2029 }
2030 }
2031
2032
2033
2034 itmc_obj_t *
op_self(itm_op_type_t type)2035 op_self(itm_op_type_t type)
2036 {
2037 return (op_unit(type, NULL, 0, NULL, 0, NULL, 0));
2038 }
2039
2040
2041 itmc_obj_t *
op_unary(itm_op_type_t type,void * data,size_t data_size)2042 op_unary(itm_op_type_t type, void *data, size_t data_size)
2043 {
2044 return (op_unit(type, data, data_size, NULL, 0, NULL, 0));
2045 }
2046
2047 itmc_obj_t *
op_unit(itm_op_type_t type,void * data0,size_t data0_size,void * data1,size_t data1_size,void * data2,size_t data2_size)2048 op_unit(itm_op_type_t type,
2049 void *data0, size_t data0_size,
2050 void *data1, size_t data1_size,
2051 void *data2, size_t data2_size)
2052 {
2053 itm_op_t *op;
2054 itmc_obj_t *obj;
2055
2056 op = malloc_vital(sizeof (itm_op_t));
2057 op->type = type;
2058 op->data.operand[0].itm_ptr = (itm_place2_t)(data0);
2059 op->data.operand[1].itm_ptr = (itm_place2_t)(data1);
2060 op->data.operand[2].itm_ptr = (itm_place2_t)(data2);
2061
2062 obj = malloc_vital(sizeof (itmc_obj_t));
2063 obj->type = ITMC_OBJ_OP;
2064 obj->name = NULL;
2065 obj->obj = op;
2066 obj->ref[0] = obj->ref[1] = obj->ref[2] = NULL;
2067 if (NULL != data0) {
2068 obj->ref[0] = obj_register(ITMC_OBJ_EXPR, NULL,
2069 data0, data0_size,
2070 &(op->data.operand[0]),
2071 OBJ_REG_TAIL);
2072 }
2073 if (NULL != data1) {
2074 obj->ref[1] = obj_register(ITMC_OBJ_EXPR, NULL,
2075 data1, data1_size,
2076 &(op->data.operand[1]),
2077 OBJ_REG_TAIL);
2078 }
2079 if (NULL != data2) {
2080 obj->ref[2] = obj_register(ITMC_OBJ_EXPR, NULL,
2081 data2, data2_size,
2082 &(op->data.operand[2]),
2083 OBJ_REG_TAIL);
2084 }
2085 obj->next = NULL;
2086 obj->last = NULL;
2087
2088 return (obj);
2089 }
2090
2091
2092 itmc_obj_t *
op_self_num(itm_op_type_t type,itm_num_t data)2093 op_self_num(itm_op_type_t type, itm_num_t data)
2094 {
2095 itm_op_t *op;
2096 itmc_obj_t *obj;
2097
2098 op = malloc_vital(sizeof (itm_op_t));
2099 op->type = type;
2100 op->data.itm_opnum = data;
2101 #if !defined(_LP64)
2102 op->data.itm_oppad = (data < 0) ? (pad_t)(~0) : 0;
2103 #endif
2104 obj = malloc_vital(sizeof (itmc_obj_t));
2105 obj->type = ITMC_OBJ_OP;
2106 obj->name = NULL;
2107 obj->obj = op;
2108 obj->ref[0] = obj->ref[1] = obj->ref[2] = NULL;
2109
2110 return (obj);
2111 }
2112
2113
2114 itm_expr_t *
expr_self_num(itm_expr_type_t type,itm_num_t data)2115 expr_self_num(itm_expr_type_t type, itm_num_t data)
2116 {
2117 itm_expr_t *expr;
2118
2119 expr = malloc_vital(sizeof (itm_expr_t));
2120 expr->type = type;
2121 expr->data.itm_exnum = data;
2122 #if !defined(_LP64)
2123 expr->data.itm_expad = (data < 0) ? (pad_t)(~0) : 0;
2124 #endif
2125 return (expr);
2126 }
2127
2128
2129 itm_expr_t *
expr_self(itm_expr_type_t type,itm_data_t * data)2130 expr_self(itm_expr_type_t type, itm_data_t *data)
2131 {
2132 itm_expr_t *expr;
2133 itmc_name_t *name;
2134
2135 expr = malloc_vital(sizeof (itm_expr_t));
2136 expr->type = type;
2137 if (NULL == data) {
2138 expr->data.value.size = 0;
2139 expr->data.value.place.itm_ptr = 0;
2140 } else {
2141 expr->data.value = *(data);
2142 }
2143
2144 switch (type) {
2145 case ITM_EXPR_NAME: /* register */
2146 name = name_lookup(data, ITMC_OBJ_REGISTER);
2147 if (&name_lookup_error == name) {
2148 return (NULL);
2149 } else if (NULL == name) {
2150 if (reg_id >= MAXREGID) {
2151 itm_error(
2152 gettext(
2153 "more than %d variables are used\n"),
2154 MAXREGID);
2155 exit(ITMC_STATUS_BT2);
2156 }
2157 name = name_register(data, ITMC_OBJ_REGISTER, NULL);
2158 name->reg_id = (reg_id++);
2159 }
2160 expr->type = ITM_EXPR_REG;
2161 expr->data.itm_exnum = name->reg_id;
2162 #if !defined(_LP64)
2163 expr->data.itm_expad =
2164 (expr->data.itm_exnum < 0) ? (pad_t)(~0) : 0;
2165 #endif
2166 break;
2167 case ITM_EXPR_SEQ:
2168 if ((sizeof (itm_place_t)) < data->size) {
2169 (void) obj_register(ITMC_OBJ_DATA, NULL,
2170 (void *)(data->place.itm_ptr), data->size,
2171 &(expr->data.value.place), OBJ_REG_TAIL);
2172 }
2173 break;
2174 }
2175 return (expr);
2176 }
2177
2178
2179 itm_expr_t *
expr_unary(itm_expr_type_t type,itm_expr_t * data0)2180 expr_unary(itm_expr_type_t type, itm_expr_t *data0)
2181 {
2182 itm_expr_t *expr;
2183
2184 expr = malloc_vital(sizeof (itm_expr_t));
2185 expr->type = type;
2186 expr->data.operand[0].itm_ptr = (itm_place2_t)(data0);
2187 (void) obj_register(ITMC_OBJ_EXPR, NULL,
2188 data0, sizeof (itm_expr_t),
2189 &(expr->data.operand[0]), OBJ_REG_TAIL);
2190
2191 return (expr);
2192 }
2193
2194
2195 itm_expr_t *
expr_binary(itm_expr_type_t type,itm_expr_t * data0,itm_expr_t * data1)2196 expr_binary(itm_expr_type_t type,
2197 itm_expr_t *data0, itm_expr_t *data1)
2198 {
2199 itm_expr_t *expr;
2200 itm_num_t num;
2201 unsigned char *p;
2202 int i;
2203
2204 expr = malloc_vital(sizeof (itm_expr_t));
2205 expr->type = type;
2206
2207 if (ITM_EXPR_SEQ == data0->type) {
2208 p = (unsigned char *)NSPTR(&(data0->data.value));
2209 for (i = 0, num = 0; i < data0->data.value.size; i++, p++) {
2210 num = ((num << 8) | *p);
2211 }
2212 data0 = expr_self_num(ITM_EXPR_INT, num);
2213 }
2214 if (ITM_EXPR_SEQ == data1->type) {
2215 p = (unsigned char *)NSPTR(&(data1->data.value));
2216 for (i = 0, num = 0; i < data1->data.value.size; i++, p++) {
2217 num = ((num << 8) | *p);
2218 }
2219 data1 = expr_self_num(ITM_EXPR_INT, num);
2220 }
2221
2222 expr->data.operand[0].itm_ptr = (itm_place2_t)(data0);
2223 expr->data.operand[1].itm_ptr = (itm_place2_t)(data1);
2224
2225 (void) obj_register(ITMC_OBJ_EXPR, NULL,
2226 data0, sizeof (itm_expr_t),
2227 &(expr->data.operand[0]), OBJ_REG_TAIL);
2228 (void) obj_register(ITMC_OBJ_EXPR, NULL,
2229 data1, sizeof (itm_expr_t),
2230 &(expr->data.operand[1]), OBJ_REG_TAIL);
2231
2232 return (expr);
2233 }
2234
2235
2236 itm_expr_t *
expr_binary2(itm_expr_type_t type,itm_expr_t * data0,itm_expr_t * data1)2237 expr_binary2(itm_expr_type_t type,
2238 itm_expr_t *data0, itm_expr_t *data1)
2239 {
2240 itm_expr_t *expr;
2241 itm_num_t num;
2242 unsigned char *p;
2243 int i;
2244
2245 if ((NULL == data0) || (NULL == data1)) {
2246 return (NULL);
2247 }
2248 expr = malloc_vital(sizeof (itm_expr_t));
2249 expr->type = type;
2250
2251 switch (data0->type) {
2252 case ITM_EXPR_SEQ:
2253 p = (unsigned char *)NSPTR(&(data0->data.value));
2254 for (i = 0, num = 0; i < data0->data.value.size; i++, p++) {
2255 num = ((num << 8) | *p);
2256 }
2257 data0 = expr_self_num(ITM_EXPR_INT, num);
2258 expr->data.operand[0].itm_ptr = (itm_place2_t)(data0);
2259 (void) obj_register(ITMC_OBJ_EXPR, NULL,
2260 data0, sizeof (itm_expr_t),
2261 &(expr->data.operand[0]), OBJ_REG_TAIL);
2262 break;
2263 case ITM_EXPR_INT:
2264 case ITM_EXPR_REG:
2265 case ITM_EXPR_IN_VECTOR_D:
2266 expr->data.operand[0] = data0->data.operand[0];
2267 break;
2268 default:
2269 expr->data.operand[0].itm_ptr = (itm_place2_t)(data0);
2270 (void) obj_register(ITMC_OBJ_EXPR, NULL,
2271 data0, sizeof (itm_expr_t),
2272 &(expr->data.operand[0]), OBJ_REG_TAIL);
2273 break;
2274 }
2275
2276 switch (data1->type) {
2277 case ITM_EXPR_SEQ:
2278 p = (unsigned char *)NSPTR(&(data1->data.value));
2279 for (i = 0, num = 0; i < data1->data.value.size; i++, p++) {
2280 num = ((num << 8) | *p);
2281 }
2282 data1 = expr_self_num(ITM_EXPR_INT, num);
2283 expr->data.operand[1].itm_ptr = (itm_place2_t)(data1);
2284 (void) obj_register(ITMC_OBJ_EXPR, NULL,
2285 data1, sizeof (itm_expr_t),
2286 &(expr->data.operand[1]), OBJ_REG_TAIL);
2287 break;
2288 case ITM_EXPR_INT:
2289 case ITM_EXPR_REG:
2290 case ITM_EXPR_IN_VECTOR_D:
2291 expr->data.operand[1] = data1->data.operand[0];
2292 break;
2293 default:
2294 expr->data.operand[1].itm_ptr = (itm_place2_t)(data1);
2295 (void) obj_register(ITMC_OBJ_EXPR, NULL,
2296 data1, sizeof (itm_expr_t),
2297 &(expr->data.operand[1]), OBJ_REG_TAIL);
2298 break;
2299 }
2300 return (expr);
2301 }
2302
2303
2304 itm_expr_t *
expr_assign(itm_expr_type_t type,itm_data_t * data0,itm_expr_t * data1)2305 expr_assign(itm_expr_type_t type,
2306 itm_data_t *data0, itm_expr_t *data1)
2307 {
2308 itm_expr_t *expr;
2309 itmc_name_t *name;
2310
2311 expr = malloc_vital(sizeof (itm_expr_t));
2312 expr->type = type;
2313 expr->data.operand[1].itm_ptr = (itm_place2_t)(data1);
2314
2315 name = name_lookup(data0, ITMC_OBJ_REGISTER);
2316 if (&name_lookup_error == name) {
2317 free(expr);
2318 exit(ITMC_STATUS_BT);
2319 } else if (NULL == name) {
2320 name = name_register(data0, ITMC_OBJ_REGISTER, NULL);
2321 name->reg_id = (reg_id++);
2322 }
2323 expr->data.operand[0].itm_ptr = name->reg_id;
2324
2325 (void) obj_register(ITMC_OBJ_EXPR, NULL,
2326 data1, sizeof (itm_expr_t),
2327 &(expr->data.operand[1]), OBJ_REG_TAIL);
2328 return (expr);
2329 }
2330
2331
2332 itm_expr_t *
expr_seq_to_int(itm_expr_t * expr)2333 expr_seq_to_int(itm_expr_t *expr)
2334 {
2335 itm_num_t num;
2336 unsigned char *p;
2337 int i;
2338
2339 if (ITM_EXPR_SEQ == expr->type) {
2340 if ((sizeof (itm_place_t)) < expr->data.value.size) {
2341 p = (unsigned char *)(expr->data.value.place.itm_ptr);
2342 } else {
2343 p = (unsigned char *)&(expr->data.value.place.itm_64d);
2344 }
2345 for (i = 0, num = 0;
2346 i < expr->data.value.size;
2347 i++, p++) {
2348 num = ((num << 8) | *p);
2349 }
2350 free(expr);
2351 expr = expr_self_num(ITM_EXPR_INT, num);
2352 }
2353 return (expr);
2354 }
2355
2356
2357 itmc_name_t *
name_lookup(itm_data_t * name,itm_type_t type)2358 name_lookup(itm_data_t *name, itm_type_t type)
2359 {
2360 itmc_name_t *p;
2361
2362 TRACE_MESSAGE('N', ("name_lookup\t: \"%-16s\" %2ld %2ld %2ld\n",
2363 name_to_str(name), name->size, type, name_id));
2364
2365 if (0 == name->size)
2366 return (NULL);
2367 for (p = name_first; p; p = p->next) {
2368 if ((name->size != p->name.size) ||
2369 (memcmp(NSPTR(name), NSPTR(&(p->name)), name->size))) {
2370 continue;
2371 }
2372 if ((type != p->type) &&
2373 (((ITMC_OBJ_ACTION != type) &&
2374 (ITMC_OBJ_ACTION != p->type)) ||
2375 ((ITMC_OBJ_ACTION == type) &&
2376 (ITMC_OBJ_DIREC != p->type) &&
2377 (ITMC_OBJ_OP != p->type) &&
2378 (ITMC_OBJ_MAP != p->type)) ||
2379 ((ITMC_OBJ_ACTION == p->type) &&
2380 (ITMC_OBJ_DIREC != type) &&
2381 (ITMC_OBJ_OP != type) &&
2382 (ITMC_OBJ_MAP != type)))) {
2383 itm_error(
2384 gettext("name type conflict: \"%1$s\" "
2385 "%2$s %3$s\n"),
2386 name_to_str(name),
2387 itm_name_type_name[type],
2388 itm_name_type_name[p->type]);
2389 error_deferred += 1;
2390 return (&name_lookup_error);
2391 } else {
2392 return (p);
2393 }
2394 }
2395 return (NULL);
2396 }
2397
2398
2399 itmc_name_t *
name_refer(itm_data_t * name,itm_type_t type,itmc_ref_t * refp)2400 name_refer(itm_data_t *name, itm_type_t type, itmc_ref_t *refp)
2401 {
2402 itmc_name_t *p;
2403 itmc_ref_link_t *rl;
2404
2405 p = name_lookup(name, type);
2406
2407 TRACE_MESSAGE('N', ("name_refer\t: \"%-16s\" %2ld %2ld %08p %2d %08p\n",
2408 name_to_str(name), name->size, type, refp, name_id, p));
2409
2410 if (&name_lookup_error == p) {
2411 return (NULL);
2412 }
2413
2414 rl = malloc_vital(sizeof (itmc_ref_link_t));
2415
2416 rl->ref = refp;
2417 rl->next = NULL;
2418
2419 if (NULL != p) {
2420 if (p->ref_last) {
2421 p->ref_last->next = rl;
2422 } else {
2423 p->ref_first = rl;
2424 }
2425 p->ref_last = rl;
2426 } else {
2427 p = malloc_vital(sizeof (itmc_name_t));
2428 p->id = (name_id++);
2429 p->reg_id = 0;
2430 p->name = *name;
2431 p->type = type;
2432 #if !defined(_LP64)
2433 p->reloc.itm_pad = 0;
2434 #endif
2435 p->reloc.itm_ptr = 0;
2436 p->ref_first = rl;
2437 p->ref_last = rl;
2438 p->next = NULL;
2439
2440 if (name_last) {
2441 name_last->next = p;
2442 } else {
2443 name_first = p;
2444 }
2445 name_last = p;
2446 }
2447 return (p);
2448 }
2449
2450
2451 itmc_name_t *
name_register(itm_data_t * name,itm_type_t type,itmc_ref_t * refp)2452 name_register(itm_data_t *name, itm_type_t type, itmc_ref_t *refp)
2453 {
2454 itmc_name_t *p;
2455
2456 TRACE_MESSAGE('N', ("name_register\t: \"%-16s\" %2ld %2ld %08p %2ld\n",
2457 name_to_str(name), name->size, type, refp, name_id));
2458
2459
2460 p = name_lookup(name, type);
2461 if (&name_lookup_error == p) {
2462 return (NULL);
2463 }
2464 if (NULL != p) {
2465 if (NULL != p->object) {
2466 itm_error(gettext(
2467 "same names are specified: %1$s\n"),
2468 name_to_str(name));
2469 error_deferred += 1;
2470 return (NULL);
2471 }
2472 p->object = refp;
2473 } else {
2474 p = malloc_vital(sizeof (itmc_name_t));
2475 p->id = (name_id++);
2476 p->reg_id = 0;
2477 p->name = *name;
2478 p->type = type;
2479 p->object = refp;
2480 p->reloc.itm_ptr = 0;
2481 #if !defined(_LP64)
2482 p->reloc.itm_pad = 0;
2483 #endif
2484 p->ref_first = NULL;
2485 p->ref_last = NULL;
2486 p->next = NULL;
2487
2488 if (name_last) {
2489 name_last->next = p;
2490 } else {
2491 name_first = p;
2492 }
2493 name_last = p;
2494 }
2495
2496 return (p);
2497 }
2498
2499
2500 int
data_compare(const itm_data_t * d0,const itm_data_t * d1)2501 data_compare(const itm_data_t *d0, const itm_data_t *d1)
2502 {
2503 if (d0->size < d1->size) {
2504 if (memcmp(NSPTR(d0), NSPTR(d1), d0->size) < 0) {
2505 return (-1);
2506 } else {
2507 return (1);
2508 }
2509 } else if (d0->size == d1->size) {
2510 return (memcmp(NSPTR(d0), NSPTR(d1), d0->size));
2511 } else /* (d0->size > d1->size) */ {
2512 if (memcmp(NSPTR(d0), NSPTR(d1), d1->size) <= 0) {
2513 return (-1);
2514 } else {
2515 return (1);
2516 }
2517 }
2518 }
2519
2520 int
data_pair_compare(itmc_data_pair_t ** p0,itmc_data_pair_t ** p1)2521 data_pair_compare(itmc_data_pair_t **p0, itmc_data_pair_t **p1)
2522 {
2523 int r;
2524 itm_data_t *d0;
2525 itm_data_t *d1;
2526 uchar_t *c0;
2527 uchar_t *c1;
2528 size_t s;
2529 int i;
2530
2531 d0 = &((*p0)->data0);
2532 d1 = &((*p1)->data0);
2533 c0 = NSPTR(d0);
2534 c1 = NSPTR(d1);
2535 if (d0->size == d1->size) {
2536 s = d0->size;
2537 } else if (d0->size < d1->size) {
2538 s = d1->size - d0->size;
2539 for (i = 0; i < s; i++, c1++) {
2540 if (0x00 != *c1) {
2541 return (-1);
2542 }
2543 }
2544 s = d0->size;
2545 } else {
2546 assert(d0->size > d1->size);
2547 s = d0->size - d1->size;
2548 for (i = 0; i < s; i++, c0++) {
2549 if (0x00 != *c0) {
2550 return (1);
2551 }
2552 }
2553 s = d1->size;
2554 }
2555 r = memcmp(c0, c1, s);
2556 if (0 == r) {
2557 itm_data_t *d;
2558 if (c0 == NSPTR(d0)) {
2559 d = d0;
2560 } else {
2561 assert(c1 == NSPTR(d0));
2562 d = d1;
2563 }
2564 itm_error(gettext(
2565 "distinct source values are specified: 0x%1$s\n"),
2566 data_to_hexadecimal(d));
2567 error_deferred += 1;
2568 }
2569 return (r);
2570 }
2571
2572
2573 static long
data_to_long(itm_data_t * data)2574 data_to_long(itm_data_t *data)
2575 {
2576 long l;
2577 int i;
2578 unsigned char *p;
2579
2580 if ((sizeof (itm_place_t)) < data->size) {
2581 return (0);
2582 }
2583 for (l = 0, i = 0, p = (unsigned char *)&(data->place);
2584 i < data->size;
2585 i++, p++) {
2586 l <<= 8;
2587 l |= *p;
2588 }
2589 return (l);
2590 }
2591