xref: /illumos-gate/usr/src/cmd/geniconvtbl/itm_util.c (revision d48be21240dfd051b689384ce2b23479d757f2d8)
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
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 *
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 *
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
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
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 *
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 *
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 *
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 *
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 *
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
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 *
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 *
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 *
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 *
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
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 *
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 *
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
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
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
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
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 *
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 *
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 *
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 *
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 *
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 *
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 *
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 *
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 *
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 *
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 *
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 *
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 *
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 *
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 *
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
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
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
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