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