# # CDDL HEADER START # # The contents of this file are subject to the terms of the # Common Development and Distribution License (the "License"). # You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. # See the License for the specific language governing permissions # and limitations under the License. # # When distributing Covered Code, include this CDDL HEADER in each # file and include the License file at usr/src/OPENSOLARIS.LICENSE. # If applicable, add the following below this CDDL HEADER, with the # fields enclosed by brackets "[]" replaced with your own identifying # information: Portions Copyright [yyyy] [name of copyright owner] # # CDDL HEADER END # # Copyright 2006 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # cmd/geniconvtbl/Makefile include ../Makefile.cmd # Hammerhead: amd64-only SUBDIRS= $(MACH64) # Hammerhead: Removed samples (demo conversion tables, OOM-killed during build) SAMPLES = all : TARGET = all install : TARGET = install clean : TARGET = clean clobber : TARGET = clobber _msg : TARGET = _msg .KEEP_STATE: .PARALLEL: $(SUBDIRS) all clean clobber install: $(SUBDIRS) .WAIT $(SAMPLES) # Hammerhead: amd64-only, use $(SUBDIRS) not $(MACH) (i386) _msg: $(SUBDIRS) $(SUBDIRS) $(SAMPLES): FRC @cd $@; pwd; $(MAKE) $(TARGET) FRC: # # CDDL HEADER START # # The contents of this file are subject to the terms of the # Common Development and Distribution License (the "License"). # You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. # See the License for the specific language governing permissions # and limitations under the License. # # When distributing Covered Code, include this CDDL HEADER in each # file and include the License file at usr/src/OPENSOLARIS.LICENSE. # If applicable, add the following below this CDDL HEADER, with the # fields enclosed by brackets "[]" replaced with your own identifying # information: Portions Copyright [yyyy] [name of copyright owner] # # CDDL HEADER END # # Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # Copyright (c) 2019, Joyent, Inc. # LIB = geniconvtbl.so PROG = geniconvtbl SRCDIR = $(SRC)/cmd/geniconvtbl MAPFILE = $(SRCDIR)/mapfile OBJS = itmcomp.o assemble.o disassemble.o itm_util.o y.tab.o lex.yy.o MSGFILES = itmcomp.i assemble.i disassemble.i itm_util.i y.tab.i lex.yy.i geniconvtbl.i include $(SRC)/cmd/Makefile.cmd POFILE = geniconvtbl_.po ROOTDIRS32= $(ROOTLIB)/iconv # Hammerhead: flattened — no amd64 subdir ROOTDIRS64= $(ROOTLIB)/iconv ROOTLIB32 = $(ROOTDIRS32)/$(LIB) ROOTLIB64 = $(ROOTDIRS64)/$(LIB) CLOBBERFILES= $(LIB) CLEANFILES = $(OBJS) y.tab.c y.tab.h lex.yy.c \ $(POFILE) CPPFLAGS += -I. -I$(SRCDIR) CERRWARN += $(CNOWARN_UNINIT) CERRWARN += -Wno-switch CERRWARN += -Wno-unused-variable CERRWARN += -Wno-implicit-function-declaration YFLAGS += -d CFLAGS += -D_FILE_OFFSET_BITS=64 # because of labels from yacc lex.yy.o : CERRWARN += -Wno-unused-label y.tab.o : CERRWARN += -Wno-unused-label # dump_expr() is too hairy SMATCH=off $(LIB) : LDFLAGS += $(GSHARED) -Wl,-h$@ $(ZTEXT) $(ZDEFS) $(BDIRECT) \ $(C_PICFLAGS) $(MAPFILE:%=-Wl,-M%) \ $(MAPFILE.PGA:%=-Wl,-M%) $(MAPFILE.NED:%=-Wl,-M%) $(LIB) : CPPFLAGS += -D_REENTRANT $(LIB) : LDLIBS += -lc $(PROG) : LDLIBS += -lgen .KEEP_STATE: .PARALLEL: $(LIB) $(OBJS) $(PROG): $(OBJS) $(LINK.c) $(OBJS) -o $@ $(LDLIBS) $(POST_PROCESS) $(LIB): $(SRCDIR)/geniconvtbl.c $(LINK.c) -o $@ $(SRCDIR)/geniconvtbl.c $(LDLIBS) $(POST_PROCESS_SO) # Hammerhead: GNU Make grouped target (was dmake +) y.tab.c y.tab.h &: $(SRCDIR)/itm_comp.y $(YACC) $(YFLAGS) $(SRCDIR)/itm_comp.y @ $(MV) y.tab.c y.tab.c~ @ $(SED) -f $(SRCDIR)/yacc.sed y.tab.c~ > y.tab.c @ $(RM) y.tab.c~ lex.yy.c: $(SRCDIR)/itm_comp.l y.tab.h $(LEX) -t $(SRCDIR)/itm_comp.l | $(SED) -f $(SRCDIR)/lex.sed > $(@) clean: $(RM) $(CLEANFILES) $(POFILE): $(MSGFILES) $(BUILDPO.msgfiles) %.o: %.c $(COMPILE.c) $< %.o: $(SRCDIR)/%.c $(COMPILE.c) $< %.i: $(SRCDIR)/%.c $(CPPFORPO) $< > $@ # install rule # Hammerhead: order-only prerequisite so $< is the file, not the directory $(ROOTDIRS32)/%: % | $(ROOTDIRS32) $(INS.file) # Hammerhead: order-only prerequisite so $< is the file, not the directory $(ROOTDIRS64)/%: % | $(ROOTDIRS64) $(INS.file) # Hammerhead: ROOTDIRS64 = ROOTDIRS32 (flattened), single rule $(ROOTDIRS32): $(ROOTLIB) $(INS.dir) include $(SRC)/cmd/Makefile.targ include $(SRC)/Makefile.msg.targ # # CDDL HEADER START # # The contents of this file are subject to the terms of the # Common Development and Distribution License, Version 1.0 only # (the "License"). You may not use this file except in compliance # with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. # See the License for the specific language governing permissions # and limitations under the License. # # When distributing Covered Code, include this CDDL HEADER in each # file and include the License file at usr/src/OPENSOLARIS.LICENSE. # If applicable, add the following below this CDDL HEADER, with the # fields enclosed by brackets "[]" replaced with your own identifying # information: Portions Copyright [yyyy] [name of copyright owner] # # CDDL HEADER END # # # Copyright 2004 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # .KEEP_STATE: include ../Makefile.com include ../../Makefile.cmd.64 all: $(LIB) install: all $(ROOTLIB64) $(ROOTLINKS64) /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright (c) 1999 by Sun Microsystems, Inc. * All rights reserved. */ #include #include #include #include #include #include #include #include #include #include #include #include "itmcomp.h" struct itm_opt_outer *itm_op_outer = NULL; #if defined(ENABLE_TRACE) static char *itmc_obj_names[] = { "ITMC_OBJ_NONE(0)", "ITMC_OBJ_ITM(1)", "ITMC_OBJ_STRING(2)", "ITMC_OBJ_DIREC(3)", "ITMC_OBJ_COND(4)", "ITMC_OBJ_MAP(5)", "ITMC_OBJ_OP(6)", "ITMC_OBJ_EXPR(7)", "ITMC_OBJ_DATA(8)", "ITMC_OBJ_ACTION(9)", "ITMC_OBJ_RANGE(10)", "ITMC_OBJ_RAGISTER(11)", "ITMC_OBJ_ESCAPESEQ(12)" }; #endif #define TRACE_FMT(comment) \ comment ## " size=%4ld(0x%4lx); 64d=0x%16" PRIx64 "; ptr=%4p(%c...)\n" #define TRACE_DT(data, refer) \ data.size, data.size, data.place.itm_64d, \ data.place.itm_ptr,\ (((refer) == 0) ? (not_refer): \ (((sizeof (itm_place_t) < data.size))? \ *((char *)(((char *)itm_header) + data.place.itm_ptr)): \ (not_refer))) enum { NOREFER = 0, REFER = 1 }; #define NAMETRACE(comment) \ { itmc_name_t *name;\ TRACE_MESSAGE('p', (#comment "\n")); \ for (name = name_first; name; name = name->next) {\ TRACE_MESSAGE('p', \ (TRACE_FMT(" "),\ TRACE_DT(name->name, NOREFER)));\ }\ } /* static int not_refer = (~0); */ static void relocation_I(itm_hdr_t *, itm_info_hdr_t *); static void relocation_II(itm_hdr_t *, itm_info_hdr_t *); static void fix_itmc_ref_reloc(itmc_ref_t *, itm_place2_t); static void analysis(itm_info_hdr_t *); static void analysis2(void); static void output(itm_hdr_t *, itm_info_hdr_t *); /* * Assemble main function */ int assemble(itm_hdr_t *itm_header) { int i; int j; itmc_ref_t *ref; itm_info_hdr_t *info_header; union { long longval; char charval[8]; } mach_spec; if (0 < error_deferred) { itm_error(gettext("number of deferred error: %d\n"), error_deferred); exit(ITMC_STATUS_BT); } itm_header->ident[0] = ITM_IDENT_0; itm_header->ident[1] = ITM_IDENT_1; itm_header->ident[2] = ITM_IDENT_2; itm_header->ident[3] = ITM_IDENT_3; itm_header->spec[0] = ITM_SPEC_0; itm_header->spec[1] = ITM_SPEC_1; itm_header->spec[2] = ITM_SPEC_2; mach_spec.longval = 1; switch (sizeof (long)) { case 4: if (0 == mach_spec.charval[0]) { itm_header->spec[3] = ITM_SPEC_3_32_BIG_ENDIAN; } else { itm_header->spec[3] = ITM_SPEC_3_32_LITTLE_ENDIAN; } break; case 8: if (0 == mach_spec.charval[0]) { itm_header->spec[3] = ITM_SPEC_3_64_BIG_ENDIAN; } else { itm_header->spec[3] = ITM_SPEC_3_64_LITTLE_ENDIAN; } break; } itm_header->version[0] = ITM_VER_0; itm_header->version[1] = ITM_VER_1; itm_header->version[2] = ITM_VER_2; itm_header->version[3] = ITM_VER_3; itm_header->itm_size.itm_ptr = 0; itm_header->reg_num = reg_id; itm_header->itm_hdr_size = (sizeof (itm_hdr_t)); info_header = malloc_vital(sizeof (itm_info_hdr_t)); (void) memset(info_header, 0, sizeof (itm_info_hdr_t)); relocation_I(itm_header, info_header); relocation_II(itm_header, info_header); TRACE_MESSAGE('r', (" ref name referencee reloc(10)" "size(10) referencer next\n")); for (i = ITMC_OBJ_FIRST; i <= ITMC_OBJ_LAST; i++) { TRACE_MESSAGE('r', ("%s\n", itmc_obj_names[i])); for (ref = ref_first[i], j = 0; ref; ref = ref->next, j++) { TRACE_MESSAGE('r', (" %2d:%08p:%08p:%08p:%8p:%8ld:%08p:%08p\n", j, ref, ref->name, ref->referencee, ref->reloc.itm_ptr, ref->size, ref->referencer, ref->next)); } } analysis(info_header); analysis2(); if (0 < error_deferred) { itm_error(gettext("number of deferred error: %d\n"), error_deferred); exit(ITMC_STATUS_BT); } output(itm_header, info_header); return (0); } /* * Fix reloc of itmc_ref_t, and fix reloc of itmc_name_t */ static void relocation_I(itm_hdr_t *itm_header, itm_info_hdr_t *info_header) { itmc_ref_t *ref; itmc_name_t *name; itm_num_t sec_num; itm_num_t sec_num2; itm_size_t sec_size; /* * determin section size */ /* string section */ for (sec_num = 0, sec_size = 0, ref = ref_first[ITMC_OBJ_STRING]; ref; sec_num += 1, sec_size += ref->size, ref = ref->next) {} sec_size = ITMROUNDUP(sec_size); info_header->str_plc_tbl.size = ((sizeof (itm_data_t)) * sec_num); info_header->str_plc_tbl.number = sec_num; info_header->str_sec.size = sec_size; info_header->str_sec.number = sec_num; /* direction */ for (sec_num = 0, sec_size = 0, ref = ref_first[ITMC_OBJ_DIREC]; ref; sec_num += 1, sec_size += ref->size, ref = ref->next) {} sec_size = ITMROUNDUP(sec_size); info_header->direc_plc_tbl.size = sec_num * (sizeof (itm_place_t)); info_header->direc_plc_tbl.number = sec_num; info_header->direc_tbl_sec.size = sec_size; info_header->direc_tbl_sec.number = sec_num; /* condition */ for (sec_num = 0, sec_size = 0, ref = ref_first[ITMC_OBJ_COND]; ref; sec_num += 1, sec_size += ref->size, ref = ref->next) {} sec_size = ITMROUNDUP(sec_size); info_header->cond_plc_tbl.size = sec_num * (sizeof (itm_place_t)); info_header->cond_plc_tbl.number = sec_num; info_header->cond_tbl_sec.size = sec_size; info_header->cond_tbl_sec.number = sec_num; /* map */ for (sec_num = 0, sec_size = 0, ref = ref_first[ITMC_OBJ_MAP]; ref; sec_num += 1, sec_size += ref->size, ref = ref->next) { } sec_size = ITMROUNDUP(sec_size); info_header->map_plc_tbl.size = sec_num * (sizeof (itm_place_t)); info_header->map_plc_tbl.number = sec_num; info_header->map_tbl_sec.size = sec_size; info_header->map_tbl_sec.number = sec_num; /* operation */ for (sec_num = 0, sec_size = 0, ref = ref_first[ITMC_OBJ_OP]; ref; sec_num += 1, sec_size += ref->size, ref = ref->next) { } sec_size = ITMROUNDUP(sec_size); info_header->op_plc_tbl.size = sec_num * (sizeof (itm_place_t)); info_header->op_plc_tbl.number = sec_num; info_header->op_tbl_sec.size = sec_size; info_header->op_tbl_sec.number = sec_num; /* range section */ for (sec_num = 0, sec_size = 0, ref = ref_first[ITMC_OBJ_RANGE]; ref; sec_num += 1, sec_size += ref->size, ref = ref->next) {} sec_size = ITMROUNDUP(sec_size); info_header->range_plc_tbl.size = sec_num * (sizeof (itm_place_t)); info_header->range_plc_tbl.number = sec_num; info_header->range_tbl_sec.size = sec_size; info_header->range_tbl_sec.number = sec_num; /* escapeseq section */ for (sec_num = 0, sec_size = 0, ref = ref_first[ITMC_OBJ_ESCAPESEQ]; ref; sec_num += 1, sec_size += ref->size, ref = ref->next) {} sec_size = ITMROUNDUP(sec_size); info_header->escapeseq_plc_tbl.size = sec_num * (sizeof (itm_place_t)); info_header->escapeseq_plc_tbl.number = sec_num; info_header->escapeseq_tbl_sec.size = sec_size; info_header->escapeseq_tbl_sec.number = sec_num; /* data section */ for (sec_num = 0, sec_size = 0, ref = ref_first[ITMC_OBJ_DATA]; ref; sec_num += 1, sec_size += ref->size, ref = ref->next) {} for (ref = ref_first[ITMC_OBJ_EXPR]; ref; sec_num += 1, sec_size += ref->size, ref = ref->next) {} sec_size = ITMROUNDUP(sec_size); info_header->data_plc_tbl.size = ((sizeof (itm_place_t)) * sec_num); info_header->data_plc_tbl.number = sec_num; info_header->data_sec.size = sec_size; info_header->data_sec.number = sec_num; /* name section */ sec_num2 = 0; for (sec_num = 0, sec_size = 0, name = name_first; name; name = name->next) { if ((ITMC_OBJ_REGISTER != name->type) && (0 != name->name.size)) { if ((sizeof (itm_place_t)) < name->name.size) { sec_size += name->name.size; sec_num2 += 1; } sec_num += 1; } } info_header->name_plc_tbl.size = ((sizeof (itm_data_t)) * sec_num); info_header->name_plc_tbl.number = sec_num; for (sec_num = 0, name = name_first; name; name = name->next) { if ((ITMC_OBJ_REGISTER == name->type) && (0 != name->name.size)) { if ((sizeof (itm_place_t)) < name->name.size) { sec_size += name->name.size; sec_num2 += 1; } sec_num += 1; } } sec_size = ITMROUNDUP(sec_size); info_header->reg_plc_tbl.size = ((sizeof (itm_data_t)) * (itm_header->reg_num)); info_header->reg_plc_tbl.number = itm_header->reg_num; info_header->name_sec.size = sec_size; info_header->name_sec.number = sec_num2; /* * adjust place */ info_header->str_sec.place.itm_ptr = 0 + (sizeof (itm_hdr_t)); info_header->direc_tbl_sec.place.itm_ptr = info_header->str_sec.place.itm_ptr + info_header->str_sec.size; info_header->cond_tbl_sec.place.itm_ptr = info_header->direc_tbl_sec.place.itm_ptr + info_header->direc_tbl_sec.size; info_header->map_tbl_sec.place.itm_ptr = info_header->cond_tbl_sec.place.itm_ptr + info_header->cond_tbl_sec.size; info_header->op_tbl_sec.place.itm_ptr = info_header->map_tbl_sec.place.itm_ptr + info_header->map_tbl_sec.size; info_header->range_tbl_sec.place.itm_ptr = info_header->op_tbl_sec.place.itm_ptr + info_header->op_tbl_sec.size; info_header->escapeseq_tbl_sec.place.itm_ptr = info_header->range_tbl_sec.place.itm_ptr + info_header->range_tbl_sec.size; info_header->data_sec.place.itm_ptr = info_header->escapeseq_tbl_sec.place.itm_ptr + info_header->escapeseq_tbl_sec.size; /* * adjust place: optional */ if (0 == cmd_opt.strip) { itm_header->info_hdr.itm_ptr = info_header->data_sec.place.itm_ptr + info_header->data_sec.size; info_header->direc_plc_tbl.place.itm_ptr = itm_header->info_hdr.itm_ptr + (sizeof (itm_info_hdr_t)); info_header->cond_plc_tbl.place.itm_ptr = info_header->direc_plc_tbl.place.itm_ptr + info_header->direc_plc_tbl.size; info_header->map_plc_tbl.place.itm_ptr = info_header->cond_plc_tbl.place.itm_ptr + info_header->cond_plc_tbl.size; info_header->op_plc_tbl.place.itm_ptr = info_header->map_plc_tbl.place.itm_ptr + info_header->map_plc_tbl.size; info_header->str_plc_tbl.place.itm_ptr = info_header->op_plc_tbl.place.itm_ptr + info_header->op_plc_tbl.size; info_header->range_plc_tbl.place.itm_ptr = info_header->str_plc_tbl.place.itm_ptr + info_header->str_plc_tbl.size; info_header->escapeseq_plc_tbl.place.itm_ptr = info_header->range_plc_tbl.place.itm_ptr + info_header->range_plc_tbl.size; info_header->data_plc_tbl.place.itm_ptr = info_header->escapeseq_plc_tbl.place.itm_ptr + info_header->escapeseq_plc_tbl.size; info_header->name_plc_tbl.place.itm_ptr = info_header->data_plc_tbl.place.itm_ptr + info_header->data_plc_tbl.size; info_header->reg_plc_tbl.place.itm_ptr = info_header->name_plc_tbl.place.itm_ptr + info_header->name_plc_tbl.size; /* name SECTION */ info_header->name_sec.place.itm_ptr = info_header->reg_plc_tbl.place.itm_ptr + info_header->reg_plc_tbl.size; } /* * size of ITM */ if (0 == cmd_opt.strip) { itm_header->itm_size.itm_ptr = info_header->name_sec.place.itm_ptr + info_header->name_sec.size; } else { itm_header->itm_size.itm_ptr = info_header->data_sec.place.itm_ptr + info_header->data_sec.size; } /* * trace */ #if defined(ENABLE_TRACE) dump_itm_header(itm_header, info_header); #endif } /* * Fix referencer of itmc_ref_t */ static void relocation_II(itm_hdr_t *itm_header, itm_info_hdr_t *info_header) { itmc_ref_t *ref; itmc_name_t *name; itmc_ref_link_t *rl; itm_place2_t place; itm_place2_t n_plc; /* * reloc */ /* string section */ TRACE_MESSAGE('3', ("string section\n")); place = info_header->str_sec.place.itm_ptr; for (ref = ref_first[ITMC_OBJ_STRING]; ref; place += ref->size, ref = ref->next) { fix_itmc_ref_reloc(ref, place); } /* direction */ TRACE_MESSAGE('3', ("direction\n")); place = info_header->direc_tbl_sec.place.itm_ptr; for (ref = ref_first[ITMC_OBJ_DIREC]; ref; place += ref->size, ref = ref->next) { fix_itmc_ref_reloc(ref, place); } /* condition */ TRACE_MESSAGE('3', ("condition\n")); place = info_header->cond_tbl_sec.place.itm_ptr; for (ref = ref_first[ITMC_OBJ_COND]; ref; place += ref->size, ref = ref->next) { fix_itmc_ref_reloc(ref, place); } /* map */ TRACE_MESSAGE('3', ("map\n")); place = info_header->map_tbl_sec.place.itm_ptr; for (ref = ref_first[ITMC_OBJ_MAP]; ref; place += ref->size, ref = ref->next) { fix_itmc_ref_reloc(ref, place); } /* operation */ TRACE_MESSAGE('3', ("operation\n")); place = info_header->op_tbl_sec.place.itm_ptr; for (ref = ref_first[ITMC_OBJ_OP]; ref; place += ref->size, ref = ref->next) { fix_itmc_ref_reloc(ref, place); } /* range */ place = info_header->range_tbl_sec.place.itm_ptr; for (ref = ref_first[ITMC_OBJ_RANGE]; ref; place += ref->size, ref = ref->next) { fix_itmc_ref_reloc(ref, place); } /* escape sequence */ place = info_header->escapeseq_tbl_sec.place.itm_ptr; for (ref = ref_first[ITMC_OBJ_ESCAPESEQ]; ref; place += ref->size, ref = ref->next) { fix_itmc_ref_reloc(ref, place); } /* data section */ TRACE_MESSAGE('3', ("data section\n")); place = info_header->data_sec.place.itm_ptr; for (ref = ref_first[ITMC_OBJ_DATA]; ref; place += ref->size, ref = ref->next) { fix_itmc_ref_reloc(ref, place); } for (ref = ref_first[ITMC_OBJ_EXPR]; ref; place += ref->size, ref = ref->next) { fix_itmc_ref_reloc(ref, place); } /* name section */ TRACE_MESSAGE('3', ("name section\n")); place = info_header->name_plc_tbl.place.itm_ptr; n_plc = info_header->name_sec.place.itm_ptr; for (name = name_first; name; name = name->next) { if ((NULL == name->object) || (ITMC_OBJ_REGISTER == name->type) || (0 == name->name.size)) { continue; } if ((sizeof (itm_place_t)) < name->name.size) { name->reloc.itm_ptr = n_plc; n_plc += name->name.size; } if (name->object->referencee) { ((itm_tbl_hdr_t *)(name->object->referencee))-> name.itm_ptr = place; } place += (intptr_t)(sizeof (itm_data_t)); } place = info_header->reg_plc_tbl.place.itm_ptr; for (name = name_first; name; name = name->next) { if ((ITMC_OBJ_REGISTER != name->type) || (0 == name->name.size)) { continue; } if ((sizeof (itm_place_t)) < name->name.size) { #if !defined(_LP64) name->reloc.itm_pad = 0; #endif name->reloc.itm_ptr = n_plc; n_plc += name->name.size; } place += (sizeof (itm_data_t)); } for (name = name_first; name; name = name->next) { if (ITMC_OBJ_REGISTER == name->type) { assert(NULL == name->object); continue; } if (NULL == name->object) { itm_error( gettext( "reference to %1$s \"%2$s\" is not resolved\n"), itm_name_type_name[name->type], name_to_str(&(name->name))); error_deferred += 1; continue; } /* else */ assert(0 != name->name.size); for (rl = name->ref_first; rl; rl = rl->next) { fix_itmc_ref_reloc(rl->ref, name->object->reloc.itm_ptr); } if (NULL == name->object->referencee) { itm_error( gettext( "reference to %1$s \"%2$s\" is not resolved\n"), itm_name_type_name[name->type], name_to_str(&(name->name))); error_deferred += 1; } if (((ITMC_OBJ_REGISTER != name->type) && (ITMC_OBJ_DIREC != name->type) && ((ITMC_OBJ_MAP != name->type) || (NULL != ref_first[ITMC_OBJ_DIREC]))) && (NULL == name->ref_first)) { itm_error( gettext( "%1$s \"%2$s\" is defined, but not referred\n"), itm_name_type_name[name->type], name_to_str(&(name->name))); error_deferred += 1; } } /* * initial direction table */ TRACE_MESSAGE('3', ("initial direction table\n")); if (NULL != ref_first[ITMC_OBJ_DIREC]) { itm_header->direc_init_tbl = ref_first[ITMC_OBJ_DIREC]->reloc; } else if (NULL != ref_first[ITMC_OBJ_MAP]) { itm_header->direc_init_tbl = ref_first[ITMC_OBJ_MAP]->reloc; } else { itm_error(gettext("No direction nor map\n")); exit(ITMC_STATUS_BT); } /* * init operation and reset operation */ for (ref = ref_first[ITMC_OBJ_OP]; ref; place += ref->size, ref = ref->next) { switch (((itm_tbl_hdr_t *)(ref->referencee))->type) { case ITM_TBL_OP_INIT: itm_header->op_init_tbl = ref->reloc; break; case ITM_TBL_OP_RESET: itm_header->op_reset_tbl = ref->reloc; break; default: break; } } } /* * Fix reloc and referencer */ static void fix_itmc_ref_reloc(itmc_ref_t *ref, itm_place2_t place) { itmc_ref_link_t *rl; ref->reloc.itm_ptr = place; #if !defined(_LP64) ref->reloc.itm_pad = 0; #endif if (NULL != ref->referencer) { ref->referencer->itm_ptr = place; } TRACE_MESSAGE('f', ("fix_itmc_ref_reloc: 0x%08p 0x%08p %p\n", ref, ref->referencer, place)); TRACE_MESSAGE('F', ("fix_itmc_ref_reloc: \"%s\"\n", name_to_str(ref->name ? &(ref->name->name) : NULL))); if (NULL != ref->name) { for (rl = ref->name->ref_first; rl; rl = rl->next) { if ((NULL != rl->ref) && (NULL != rl->ref->referencer)) { rl->ref->referencer->itm_ptr = place; TRACE_MESSAGE('f', ("fix_itmc_ref_reloc: " "0x%08p 0x%08p\n", rl->ref, rl->ref->referencer)); TRACE_MESSAGE('F', ("fix_itmc_ref_reloc: \"%s\"\n", name_to_str(ref->name ? &(ref->name->name) : NULL))); } } } } /* * Analysis */ static void analysis(itm_info_hdr_t *info_header) { itmc_ref_t *ref; itm_place2_t place; itm_type_t obj_type; enum { ONEMAP, ZEROMAP} onemap = ZEROMAP; TRACE_MESSAGE('4', ("Analysis\n")); place = info_header->str_sec.place.itm_ptr; for (obj_type = ITMC_OBJ_FIRST; obj_type <= ITMC_OBJ_LAST; obj_type++) { if (ITMC_OBJ_DIREC == obj_type) { continue; } for (ref = ref_first[obj_type]; ref; place += ref->size, ref = ref->next) { if ((NULL == ref->name) && (NULL == ref->referencer)) { itm_tbl_hdr_t *tbl_hdr; char *tbl_type; tbl_hdr = (itm_tbl_hdr_t *)(ref->referencee); if ((ITM_TBL_OP_RESET == tbl_hdr->type) || (ITM_TBL_OP_INIT == tbl_hdr->type)) { continue; } else if ((ITM_TBL_MAP == (ITM_TBL_MASK & tbl_hdr->type)) && (NULL == ref_first[ITMC_OBJ_DIREC])) { if (ZEROMAP == onemap) { onemap = ONEMAP; continue; } else { itm_error( gettext("multiple unamed map's " "defined\n")); error_deferred += 1; continue; } } switch (ITM_TBL_MASK & tbl_hdr->type) { case ITM_TBL_ITM: tbl_type = itm_name_type_name[ITMC_OBJ_ITM]; break; case ITM_TBL_DIREC: tbl_type = itm_name_type_name[ITMC_OBJ_DIREC]; break; case ITM_TBL_COND: tbl_type = itm_name_type_name[ITMC_OBJ_COND]; break; case ITM_TBL_OP: tbl_type = itm_name_type_name[ITMC_OBJ_OP]; break; case ITM_TBL_MAP: tbl_type = itm_name_type_name[ITMC_OBJ_MAP]; break; case ITM_TBL_RANGE: tbl_type = itm_name_type_name[ITMC_OBJ_RANGE]; break; case ITM_TBL_ESCAPESEQ: tbl_type = itm_name_type_name[ITMC_OBJ_ESCAPESEQ]; break; default: tbl_type = itm_name_type_name[ITMC_OBJ_NONE]; break; } itm_error( gettext("unnamed %1$s-type object is " "defined, but not referenced\n"), tbl_type); error_deferred += 1; } } } } /* * Analysis2 (check #nest of operation) */ #define NIL -1 static void analysis2(void) { int i, j, k, n_op; itmc_ref_t *ref; itm_op_outer_t *o, *o_prev; itm_op_inner_t *in, *in_prev; int indegree_zero; struct op_nest_vertex { itmc_ref_t *ref; /* corresponding object's ref */ int indegree; /* indegree */ struct op_nest_edge *e; /* link of edge list */ int z_link; /* index of indegree zero */ int n_nest; }; struct op_nest_edge { struct op_nest_edge *e; /* link of edge list */ int index; /* index of edge */ }; struct op_nest_vertex *vertexes; struct op_nest_edge *e, *e_prev; TRACE_MESSAGE('5', ("Analysis2\n")); #ifdef ENABLE_TRACE for (o = itm_op_outer; o != NULL; o = o->link) { TRACE_MESSAGE('L', ("op(table)%x\n", o->optbl)); } #endif i = 0; for (o = itm_op_outer; o != NULL; o = o->link) { for (ref = ref_first[ITMC_OBJ_OP]; ref != NULL; ref = ref->next) { if (o->optbl == ref->referencee) { if (ref->name != NULL) { o->ref = ref->name->object; } else { o->ref = ref; } TRACE_MESSAGE('l', ("op(table)%x<-ref(%x)\n", o->optbl, o->ref)); o->ref->vertex_index = i; i++; break; } } } n_op = i; if (n_op == 0) return; vertexes = (struct op_nest_vertex *)(malloc_vital( sizeof (struct op_nest_vertex) * n_op)); for (o = itm_op_outer; o != NULL; o = o->link) { if (o->ref == NULL) { continue; } vertexes[o->ref->vertex_index].ref = o->ref; vertexes[o->ref->vertex_index].e = NULL; } for (o = itm_op_outer; o != NULL; o_prev = o, o = o->link, free(o_prev)) { if (o->ref == NULL) { continue; } TRACE_MESSAGE('l', ("vertexes[%d].ref=%x (optbl=%x(%s))\n", o->ref->vertex_index, o->ref, o->ref->referencee, name_to_str(o->ref->name == NULL ? NULL : &(o->ref->name->name)))); for (in = o->in; in != NULL; in_prev = in, in = in->in, free(in_prev)) { /* make edge */ i = o->ref->vertex_index; j = in->ref->name->object->vertex_index; e = malloc_vital(sizeof (struct op_nest_edge)); e->index = j; e->e = vertexes[i].e; vertexes[i].e = e; vertexes[j].indegree++; TRACE_MESSAGE('l', (" edge: vertexes[%d]:(%s) ->vertex[%d]:(%s)\n", i, name_to_str( (vertexes[i].ref->name == NULL) ? NULL : &(vertexes[i].ref->name->name)), j, name_to_str( (vertexes[j].ref->name == NULL) ? NULL : &(vertexes[j].ref->name->name)))); } } indegree_zero = NIL; for (i = 0; i < n_op; i++) { if (vertexes[i].indegree == 0) { vertexes[i].z_link = indegree_zero; indegree_zero = i; } } for (i = 0; i < n_op; i++) { if (indegree_zero == NIL) { itm_error( gettext("operation loop detected\n")); exit(ITMC_STATUS_BT2); } k = indegree_zero; indegree_zero = vertexes[indegree_zero].z_link; if (vertexes[k].n_nest > MAXOPNEST) { itm_error( gettext("operation nested more than %d\n"), MAXOPNEST); exit(ITMC_STATUS_BT2); } TRACE_MESSAGE('l', ("take out first vertex: vertexes[%d] (i.e.%s) " "#depth=%d\n", k, name_to_str( (vertexes[k].ref->name == NULL) ? NULL : &(vertexes[k].ref->name->name)), vertexes[k].n_nest)); for (e = vertexes[k].e; e != NULL; e_prev = e, e = e->e, free(e_prev)) { j = e->index; if (vertexes[j].n_nest < vertexes[k].n_nest + 1) { vertexes[j].n_nest = vertexes[k].n_nest + 1; } TRACE_MESSAGE('l', (" +->vertexes[%d]:(%s) " "(#indegree=%d,#depth = %d)\n", j, name_to_str(&(vertexes[j].ref->name->name)), vertexes[j].indegree, vertexes[j].n_nest)); vertexes[j].indegree--; if (vertexes[j].indegree == 0) { vertexes[j].z_link = indegree_zero; indegree_zero = j; } } } free(vertexes); } #undef NIL /* * Output ITM compiled data */ void output(itm_hdr_t *itm_header, itm_info_hdr_t *info_header) { itmc_ref_t *ref; itmc_name_t *name; itm_size_t sec_size; struct stat st_buf; int fd; FILE *fp; if (cmd_opt.no_output) { return; } else if (NULL == itm_output_file) { fd = 1; TRACE_MESSAGE('o', ("file=(stdout)\n")); } else { TRACE_MESSAGE('o', ("file=%s\n", itm_output_file)); switch (stat(itm_output_file, &st_buf)) { case 0: if (0 == cmd_opt.force_overwrite) { itm_error( gettext("target file exists\n")); exit(ITMC_STATUS_CMD2); } break; case -1: if (ENOENT != errno) { PERROR(gettext("stat")); exit(ITMC_STATUS_CMD2); } break; default: PERROR(gettext("stat")); exit(ITMC_STATUS_SYS); break; } fd = open(itm_output_file, O_CREAT|O_WRONLY|O_TRUNC, 0666); if (fd == -1) { PERROR(gettext("open")); exit(ITMC_STATUS_SYS); } } fp = fdopen(fd, "w"); if (NULL == fp) { PERROR(gettext("fdopen")); exit(ITMC_STATUS_SYS); } if (1 == cmd_opt.strip) { itm_header->info_hdr.itm_ptr = 0; } /* ITM header */ (void) fseek(fp, 0, SEEK_SET); (void) fwrite(itm_header, sizeof (itm_hdr_t), 1, fp); /* string section */ (void) fseek(fp, info_header->str_sec.place.itm_ptr, SEEK_SET); TRACE_MESSAGE('P', ("str_sec.place.place=%p:\n", info_header->str_sec.place.itm_ptr)); for (ref = ref_first[ITMC_OBJ_STRING]; ref; ref = ref->next) { (void) fwrite((void *)(ref->referencee), 1, ref->size, fp); } /* direction */ (void) fseek(fp, info_header->direc_tbl_sec.place.itm_ptr, SEEK_SET); TRACE_MESSAGE('P', ("direc_tbl_sec.place=%p:\n", info_header->direc_tbl_sec.place.itm_ptr)); for (ref = ref_first[ITMC_OBJ_DIREC]; ref; ref = ref->next) { (void) fwrite((void *)(ref->referencee), ref->size, 1, fp); } /* condition */ (void) fseek(fp, info_header->cond_tbl_sec.place.itm_ptr, SEEK_SET); TRACE_MESSAGE('P', ("cond_tbl_sec.place=%p:\n", info_header->cond_tbl_sec.place.itm_ptr)); for (ref = ref_first[ITMC_OBJ_COND]; ref; ref = ref->next) { (void) fwrite((void *)(ref->referencee), ref->size, 1, fp); } /* map */ (void) fseek(fp, info_header->map_tbl_sec.place.itm_ptr, SEEK_SET); TRACE_MESSAGE('P', ("map_tbl_sec.place=%p:\n", info_header->map_tbl_sec.place.itm_ptr)); for (ref = ref_first[ITMC_OBJ_MAP]; ref; ref = ref->next) { (void) fwrite((void *)(ref->referencee), ref->size, 1, fp); } /* operation */ (void) fseek(fp, info_header->op_tbl_sec.place.itm_ptr, SEEK_SET); TRACE_MESSAGE('P', ("op_tbl_sec.place=%p:\n", info_header->op_tbl_sec.place.itm_ptr)); for (ref = ref_first[ITMC_OBJ_OP]; ref; ref = ref->next) { (void) fwrite((void *)(ref->referencee), ref->size, 1, fp); } /* range */ (void) fseek(fp, info_header->range_tbl_sec.place.itm_ptr, SEEK_SET); TRACE_MESSAGE('P', ("range_tbl_sec.place=%p:\n", info_header->range_tbl_sec.place.itm_ptr)); for (ref = ref_first[ITMC_OBJ_RANGE]; ref; ref = ref->next) { (void) fwrite((void *)(ref->referencee), ref->size, 1, fp); } /* escape sequence */ (void) fseek(fp, info_header->escapeseq_tbl_sec.place.itm_ptr, SEEK_SET); TRACE_MESSAGE('P', ("escapeseq_tbl_sec.place=%p:\n", info_header->escapeseq_tbl_sec.place.itm_ptr)); for (ref = ref_first[ITMC_OBJ_ESCAPESEQ]; ref; ref = ref->next) { (void) fwrite((void *)(ref->referencee), ref->size, 1, fp); } /* data section */ sec_size = 0; (void) fseek(fp, info_header->data_sec.place.itm_ptr, SEEK_SET); TRACE_MESSAGE('P', ("data_sec.place=%p:\n", info_header->data_sec.place.itm_ptr)); for (ref = ref_first[ITMC_OBJ_DATA]; ref; ref = ref->next) { (void) fwrite((void *)(ref->referencee), ref->size, 1, fp); sec_size += ref->size; } for (ref = ref_first[ITMC_OBJ_EXPR]; ref; ref = ref->next) { (void) fwrite((void *)(ref->referencee), ref->size, 1, fp); sec_size += ref->size; } if (0 != cmd_opt.strip) { if (sec_size < info_header->data_sec.size) { (void) fwrite("\0\0\0\0", 1, info_header->data_sec.size - sec_size, fp); } } else { /* ITM Info header */ (void) fseek(fp, itm_header->info_hdr.itm_ptr, SEEK_SET); TRACE_MESSAGE('P', ("info_hdr=%p:\n", itm_header->info_hdr.itm_ptr)); (void) fwrite(info_header, sizeof (itm_info_hdr_t), 1, fp); (void) fseek(fp, info_header->direc_plc_tbl.place.itm_ptr, SEEK_SET); TRACE_MESSAGE('P', ("direc_plc_tbl.place=%p:\n", info_header->direc_plc_tbl.place.itm_ptr)); for (ref = ref_first[ITMC_OBJ_DIREC]; ref; ref = ref->next) { (void) fwrite(&(ref->reloc), sizeof (itm_place_t), 1, fp); } (void) fseek(fp, info_header->cond_plc_tbl.place.itm_ptr, SEEK_SET); TRACE_MESSAGE('P', ("cond_plc_tbl.place=%p:\n", info_header->cond_plc_tbl.place.itm_ptr)); for (ref = ref_first[ITMC_OBJ_COND]; ref; ref = ref->next) { (void) fwrite(&(ref->reloc), sizeof (itm_place_t), 1, fp); } (void) fseek(fp, info_header->map_plc_tbl.place.itm_ptr, SEEK_SET); TRACE_MESSAGE('P', ("map_plc_tbl.place=%p:\n", info_header->map_plc_tbl.place.itm_ptr)); for (ref = ref_first[ITMC_OBJ_MAP]; ref; ref = ref->next) { (void) fwrite(&(ref->reloc), sizeof (itm_place_t), 1, fp); } (void) fseek(fp, info_header->op_plc_tbl.place.itm_ptr, SEEK_SET); TRACE_MESSAGE('P', ("op_plc_tbl.place=%p:\n", info_header->op_plc_tbl.place.itm_ptr)); for (ref = ref_first[ITMC_OBJ_OP]; ref; ref = ref->next) { (void) fwrite(&(ref->reloc), sizeof (itm_place_t), 1, fp); } (void) fseek(fp, info_header->str_plc_tbl.place.itm_ptr, SEEK_SET); TRACE_MESSAGE('P', ("str_plc_tbl.place=%p:\n", info_header->str_plc_tbl.place.itm_ptr)); for (ref = ref_first[ITMC_OBJ_STRING]; ref; ref = ref->next) { itm_data_t data; #if !defined(_LP64) data.place.itm_pad = 0; data.pad = 0; #endif data.place = ref->reloc; data.size = ref->size; (void) fwrite(&data, sizeof (itm_data_t), 1, fp); } (void) fseek(fp, info_header->range_plc_tbl.place.itm_ptr, SEEK_SET); TRACE_MESSAGE('P', ("range_plc_tbl.place=%p:\n", info_header->range_plc_tbl.place.itm_ptr)); for (ref = ref_first[ITMC_OBJ_RANGE]; ref; ref = ref->next) { (void) fwrite(&(ref->reloc), sizeof (itm_place_t), 1, fp); } (void) fseek(fp, info_header->escapeseq_plc_tbl.place.itm_ptr, SEEK_SET); TRACE_MESSAGE('P', ("escapeseq_plc_tbl.place=%p:\n", info_header->escapeseq_plc_tbl.place.itm_ptr)); for (ref = ref_first[ITMC_OBJ_ESCAPESEQ]; ref; ref = ref->next) { (void) fwrite(&(ref->reloc), sizeof (itm_place_t), 1, fp); } (void) fseek(fp, info_header->data_plc_tbl.place.itm_ptr, SEEK_SET); TRACE_MESSAGE('P', ("data_plc_tbl.place=%p:\n", info_header->data_plc_tbl.place.itm_ptr)); for (ref = ref_first[ITMC_OBJ_DATA]; ref; ref = ref->next) { (void) fwrite(&(ref->reloc), sizeof (itm_place_t), 1, fp); } for (ref = ref_first[ITMC_OBJ_EXPR]; ref; ref = ref->next) { (void) fwrite(&(ref->reloc), sizeof (itm_place_t), 1, fp); } (void) fseek(fp, info_header->name_plc_tbl.place.itm_ptr, SEEK_SET); TRACE_MESSAGE('P', ("name_plc_tbl.place=%p:\n", info_header->name_plc_tbl.place.itm_ptr)); for (name = name_first, sec_size = 0; name; name = name->next) { itm_data_t data; if ((ITMC_OBJ_REGISTER == name->type) || (0 == name->name.size)) { continue; } data.size = name->name.size; #if !defined(_LP64) data.pad = 0; #endif if ((sizeof (itm_place_t)) < data.size) { #if !defined(_LP64) data.place.itm_pad = 0; #endif data.place.itm_ptr = name->reloc.itm_ptr; } else { data.place = name->name.place; } (void) fwrite(&data, sizeof (itm_data_t), 1, fp); } (void) fseek(fp, info_header->reg_plc_tbl.place.itm_ptr, SEEK_SET); TRACE_MESSAGE('P', ("reg_plc_tbl.place=%p:\n", info_header->reg_plc_tbl.place.itm_ptr)); for (name = name_first; name; name = name->next) { itm_data_t data; if ((ITMC_OBJ_REGISTER != name->type) || (0 == name->name.size)) { continue; } #if !defined(_LP64) data.pad = 0; #endif data.size = name->name.size; if ((sizeof (itm_place_t)) < data.size) { #if !defined(_LP64) data.place.itm_pad = 0; #endif data.place.itm_ptr = name->reloc.itm_ptr; } else { data.place = name->name.place; } (void) fwrite(&data, sizeof (itm_data_t), 1, fp); } /* Name section */ (void) fseek(fp, info_header->name_sec.place.itm_ptr, SEEK_SET); TRACE_MESSAGE('P', ("name_sec.place=%p:\n", info_header->name_sec.place.itm_ptr)); for (name = name_first, sec_size = 0; name; name = name->next) { if ((ITMC_OBJ_REGISTER == name->type) || (name->name.size <= (sizeof (itm_place_t)))) { continue; } (void) fwrite(NSPTR(&(name->name)), 1, name->name.size, fp); sec_size += name->name.size; } for (name = name_first; name; name = name->next) { if ((ITMC_OBJ_REGISTER != name->type) || (name->name.size <= (sizeof (itm_place_t)))) { continue; } (void) fwrite(NSPTR(&(name->name)), 1, name->name.size, fp); sec_size += name->name.size; } if (sec_size < info_header->name_sec.size) { (void) fwrite("\0\0\0\0", 1, info_header->name_sec.size - sec_size, fp); } } (void) fclose(fp); } /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright (c) 1999 by Sun Microsystems, Inc. * All rights reserved. */ #include #include #include #include #include #include #include #include #include #include #include #include #include "iconv_tm.h" #include "itm_util.h" /* * function prototype */ static itm_hdr_t *itm_attach(const char *); static void dump_tables(itm_hdr_t *, itm_info_hdr_t *); static void dump_direc_tbl(itm_hdr_t *, itm_place_t); static void dump_map(itm_hdr_t *, itm_place_t, int); static void dump_map_i_f(itm_hdr_t *, itm_place_t, int); static void dump_map_l_f(itm_hdr_t *, itm_place_t, int); static void dump_map_hash(itm_hdr_t *, itm_place_t, int); static void dump_map_dense_enc(itm_hdr_t *, itm_place_t, int); static void dump_cond_tbl(itm_hdr_t *, itm_place_t, int); static void dump_op_tbl(itm_hdr_t *, itm_place_t, int); static void dump_op(itm_hdr_t *, itm_place2_t); static void dump_expr(itm_hdr_t *, itm_place_t); static void dump_range(itm_hdr_t *, itm_place_t); static void dump_escapeseq(itm_hdr_t *, itm_place_t); static char *tbl_name(itm_hdr_t *, itm_tbl_hdr_t *); static char *reg_name(itm_hdr_t *itm_hdr, itm_place_t op); static void printi(int, char *, ...); /* * macro definition */ #define ADDR(place) ((void *)(((char *)(itm_hdr)) + \ ((itm_place2_t)((place).itm_ptr)))) #define DADDR(n) (((n)->size <= (sizeof ((n)->place))) ? \ ((char *)(&((n)->place))) :\ ((char *)(ADDR((n)->place)))) #define ADDR2(place2) ((void *)(((char *)(itm_hdr)) + \ ((itm_place2_t)(place2)))) #define INFO_HDR(pa) ((void *)(((char *)pa) + \ ((itm_hdr_t *)(pa))->info_hdr.itm_ptr)) #if defined(RESERVED_NAME_PREFIX) #define RNPREF RESERVED_NAME_PREFIX #else /* !defined(RESERVED_NAME_PREFIX) */ #define RNPREF /* null strings */ #endif /* !defined(RESERVED_NAME_PREFIX) */ void disassemble(char *file) { itm_hdr_t *itm_hdr; itm_info_hdr_t *info_hdr; itm_data_t type_id; TRACE_MESSAGE('d', ("disassemble %s\n", file)); itm_hdr = itm_attach(file); if (NULL == itm_hdr) { exit(3); } if (0 == itm_hdr->info_hdr.itm_ptr) { itm_error(gettext("binarytable is stripped\n")); exit(4); } if (0 == itm_hdr->info_hdr.itm_ptr) { info_hdr = malloc_vital(sizeof (itm_info_hdr_t)); (void) memset(info_hdr, 0, sizeof (itm_info_hdr_t)); } else { info_hdr = INFO_HDR(itm_hdr); } #if defined(ENABLE_TRACE) dump_itm_header(itm_hdr, info_hdr); #endif printi(0, "//\n", file); printi(0, "// %s\n", file); printi(0, "//\n", file); type_id = itm_hdr->type_id; if ((NULL != cmd_opt.disassemble) && ((sizeof (itm_place_t)) < type_id.size)) { type_id.place.itm_ptr += (itm_place2_t)itm_hdr; } printi(1, "%s {\n", name_to_str(&type_id)); dump_tables(itm_hdr, info_hdr); printi(-1, "}\n"); } #if defined(ENABLE_TRACE) void dump_itm_header(itm_hdr_t *itm_header, itm_info_hdr_t *info_header) { char *str_type_id; char *str_interpreter; itm_data_t type_id; itm_data_t interpreter; type_id = itm_header->type_id; str_type_id = malloc_vital(itm_header->type_id.size + 1); if ((NULL != cmd_opt.disassemble) && ((sizeof (itm_place_t)) < type_id.size)) { type_id.place.itm_ptr += (itm_place2_t)itm_header; } (void) memcpy(str_type_id, name_to_str(&type_id), type_id.size + 1); interpreter = itm_header->interpreter; str_interpreter = malloc_vital(itm_header->interpreter.size + 1); if ((NULL != cmd_opt.disassemble) && ((sizeof (itm_place_t)) < interpreter.size)) { interpreter.place.itm_ptr += (itm_place2_t)itm_header; } (void) memcpy(str_interpreter, name_to_str(&interpreter), interpreter.size + 1); TRACE_MESSAGE('D', ("\n" "------\n" "Sizeof Data Structures \n" " sizeof(int) = %ld\n" " sizeof(long) = %ld\n" " sizeof(uintptr_t) = %ld\n" " sizeof(struct itm_place_t) = %ld\n" " sizeof(struct itm_data_t) = %ld\n" " sizeof(struct itm_hdr_t) = %ld\n" " sizeof(struct itm_place_tbl_info_t) = %ld\n" " sizeof(struct itm_section_info_t) = %ld\n" " sizeof(struct itm_action_type_t) = %ld\n" " sizeof(struct itm_direct_t) = %ld\n" " sizeof(struct itm_cond_t) = %ld\n" " sizeof(struct itm_range_hdr_t) = %ld\n" " sizeof(struct itm_escapeseq_hdr_t) = %ld\n" " sizeof(struct itm_map_idx_fix_hdr_t) = %ld\n" " sizeof(struct itm_map_lookup_hdr_t) = %ld\n" " sizeof(struct itm_map_hash_hdr_t) = %ld\n" " sizeof(struct itm_map_dense_enc_hdr_t) = %ld\n" " sizeof(struct itm_expr_t) = %ld\n" " sizeof(enum itm_op_type_t) = %ld\n" " sizeof(struct itm_op_t) u= %ld\n" " sizeof(enum itm_expr_type_t)= %ld\n" "\n", sizeof (int), sizeof (long), sizeof (uintptr_t), sizeof (itm_place_t), sizeof (itm_data_t), sizeof (itm_hdr_t), sizeof (itm_place_tbl_info_t), sizeof (itm_section_info_t), sizeof (itm_action_type_t), sizeof (itm_direc_t), sizeof (itm_cond_t), sizeof (itm_range_hdr_t), sizeof (itm_escapeseq_hdr_t), sizeof (itm_map_idx_fix_hdr_t), sizeof (itm_map_lookup_hdr_t), sizeof (itm_map_hash_hdr_t), sizeof (itm_map_dense_enc_hdr_t), sizeof (itm_expr_t), sizeof (itm_op_type_t), sizeof (itm_op_t), sizeof (itm_expr_type_t))); TRACE_MESSAGE('H', ("ident = %c%c%c\n" "spec = %02x%02x%02x%02x\n" "version = %02x%02x%02x%02x\n" "itm_size = %ld\n" "type_id = %s\n" "interpreter = %s\n" "op_init_tbl = %ld\n" "op_reset_tbl = %ld\n" "direc_init_tbl = %ld\n" "reg_num = %ld\n" "itm_hdr_size = %ld\n" "info_hdr = %ld\n" "info_hdr_size = %ld\n", itm_header->ident[0], itm_header->ident[1], itm_header->ident[2], /* itm_header->ident[3], */ itm_header->spec[0], itm_header->spec[1], itm_header->spec[2], itm_header->spec[3], itm_header->version[0], itm_header->version[1], itm_header->version[2], itm_header->version[3], itm_header->itm_size.itm_ptr, str_type_id, str_interpreter, itm_header->op_init_tbl.itm_ptr, itm_header->op_reset_tbl.itm_ptr, itm_header->direc_init_tbl.itm_ptr, itm_header->reg_num, itm_header->itm_hdr_size, itm_header->info_hdr.itm_ptr, (sizeof (itm_info_hdr_t)))); TRACE_MESSAGE('H', (" str_sec = (%4ld %4ld %4ld) " " str_plc_tbl = (%4ld %4ld %4ld)\n" "direc_sec_tbl = (%4ld %4ld %4ld) " "direc_plc_tbl = (%4ld %4ld %4ld)\n" " cond_sec_tbl = (%4ld %4ld %4ld) " " cond_plc_tbl = (%4ld %4ld %4ld)\n" " map_sec_tbl = (%4ld %4ld %4ld) " " map_plc_tbl = (%4ld %4ld %4ld)\n" " op_sec_tbl = (%4ld %4ld %4ld) " " op_plc_tbl = (%4ld %4ld %4ld)\n" "range_sec_tbl = (%4ld %4ld %4ld) " "range_plc_tbl = (%4ld %4ld %4ld)\n" "escsq_sec_tbl = (%4ld %4ld %4ld) " "escsq_plc_tbl = (%4ld %4ld %4ld)\n" " data_sec = (%4ld %4ld %4ld) " " data_plc_tbl = (%4ld %4ld %4ld)\n" " name_sec = (%4ld %4ld %4ld) " " name_plc_tbl = (%4ld %4ld %4ld)\n" " " " reg_plc_tbl = (%4ld %4ld %4ld)\n" "%s\n", info_header->str_sec.place.itm_ptr, info_header->str_sec.size, info_header->str_sec.number, info_header->str_plc_tbl.place.itm_ptr, info_header->str_plc_tbl.size, info_header->str_plc_tbl.number, info_header->direc_tbl_sec.place.itm_ptr, info_header->direc_tbl_sec.size, info_header->direc_tbl_sec.number, info_header->direc_plc_tbl.place.itm_ptr, info_header->direc_plc_tbl.size, info_header->direc_plc_tbl.number, info_header->cond_tbl_sec.place.itm_ptr, info_header->cond_tbl_sec.size, info_header->cond_tbl_sec.number, info_header->cond_plc_tbl.place.itm_ptr, info_header->cond_plc_tbl.size, info_header->cond_plc_tbl.number, info_header->map_tbl_sec.place.itm_ptr, info_header->map_tbl_sec.size, info_header->map_tbl_sec.number, info_header->map_plc_tbl.place.itm_ptr, info_header->map_plc_tbl.size, info_header->map_plc_tbl.number, info_header->op_tbl_sec.place.itm_ptr, info_header->op_tbl_sec.size, info_header->op_tbl_sec.number, info_header->op_plc_tbl.place.itm_ptr, info_header->op_plc_tbl.size, info_header->op_plc_tbl.number, info_header->range_tbl_sec.place.itm_ptr, info_header->range_tbl_sec.size, info_header->range_tbl_sec.number, info_header->range_plc_tbl.place.itm_ptr, info_header->range_plc_tbl.size, info_header->range_plc_tbl.number, info_header->escapeseq_tbl_sec.place.itm_ptr, info_header->escapeseq_tbl_sec.size, info_header->escapeseq_tbl_sec.number, info_header->escapeseq_plc_tbl.place.itm_ptr, info_header->escapeseq_plc_tbl.size, info_header->escapeseq_plc_tbl.number, info_header->data_sec.place.itm_ptr, info_header->data_sec.size, info_header->data_sec.number, info_header->data_plc_tbl.place.itm_ptr, info_header->data_plc_tbl.size, info_header->data_plc_tbl.number, info_header->name_sec.place.itm_ptr, info_header->name_sec.size, info_header->name_sec.number, info_header->name_plc_tbl.place.itm_ptr, info_header->name_plc_tbl.size, info_header->name_plc_tbl.number, info_header->reg_plc_tbl.place.itm_ptr, info_header->reg_plc_tbl.size, info_header->reg_plc_tbl.number, "--------")); } #endif /* * Dump tables */ static void dump_tables(itm_hdr_t *itm_hdr, itm_info_hdr_t *info_hdr) { itm_num_t n; itm_data_t *data; itm_place_t *place; itm_place2_t place2; itm_data_t d; data = (itm_data_t *)(ADDR(info_hdr->reg_plc_tbl.place)); for (n = 0; n < info_hdr->reg_plc_tbl.number; n++, data += 1) { d = *(data); if ((sizeof (itm_place_t)) < d.size) { d.place.itm_ptr = (itm_place2_t)ADDR(d.place); } printi(0, "// register: %s\n", name_to_str(&d)); } data = (itm_data_t *)(ADDR(info_hdr->name_plc_tbl.place)); for (n = 0, place2 = info_hdr->name_plc_tbl.place.itm_ptr; n < info_hdr->name_plc_tbl.number; n++, data += 1, place2 += sizeof (itm_data_t)) { d = *(data); if ((sizeof (itm_place_t)) < d.size) { d.place.itm_ptr = (itm_place2_t)ADDR(d.place); } TRACE_MESSAGE('p', ("(*)name=%ld", ((sizeof (itm_place_t)) < d.size) ? d.place.itm_ptr: (place2 + offsetof(itm_data_t, place)))); printi(0, "// name: %s\n", name_to_str(&d)); } place = (itm_place_t *)(ADDR(info_hdr->cond_plc_tbl.place)); for (n = 0; n < info_hdr->cond_plc_tbl.number; n++, place += 1) { dump_cond_tbl(itm_hdr, *place, 1); } place = (itm_place_t *)(ADDR(info_hdr->map_plc_tbl.place)); for (n = 0; n < info_hdr->map_plc_tbl.number; n++, place += 1) { dump_map(itm_hdr, *place, 1); } place = (itm_place_t *)(ADDR(info_hdr->op_plc_tbl.place)); for (n = 0; n < info_hdr->op_plc_tbl.number; n++, place += 1) { dump_op_tbl(itm_hdr, *place, 1); } place = (itm_place_t *)(ADDR(info_hdr->direc_plc_tbl.place)); for (n = 0; n < info_hdr->direc_plc_tbl.number; n++, place += 1) { dump_direc_tbl(itm_hdr, *place); } } /* * Dump direction */ static void dump_direc_tbl(itm_hdr_t *itm_hdr, itm_place_t direc_place) { itm_tbl_hdr_t *direc_hdr; itm_direc_t *direc; itm_type_t type; long i; char *name; direc_hdr = (itm_tbl_hdr_t *)ADDR(direc_place); direc = (itm_direc_t *)(direc_hdr + 1); TRACE_MESSAGE('p', ("(&)direc=%ld ", direc_place.itm_ptr)); printi(1, RNPREF "direction"); if (0 != direc_hdr->name.itm_ptr) { name = tbl_name(itm_hdr, direc_hdr); if (NULL != name) { printi(0, " %s", name); } } printi(0, " {\n"); for (i = 0; i < direc_hdr->number; i++, direc++) { dump_cond_tbl(itm_hdr, direc->condition, 0); printi(0, "\t"); type = (ITM_TBL_MASK & (((itm_tbl_hdr_t *)(ADDR(direc->action)))->type)); if (ITM_TBL_OP == type) { dump_op_tbl(itm_hdr, direc->action, 0); } else if (ITM_TBL_DIREC == type) { printi(0, "direction: action: %ld\n", direc->action.itm_ptr); } else if (ITM_TBL_MAP == type) { dump_map(itm_hdr, direc->action, 0); } else { printi(0, RNPREF "error ELIBBAD // unknown operation (%lx)\n", type); } } printi(-1, "};\n"); } static void dump_map(itm_hdr_t *itm_hdr, itm_place_t map_place, int standalone) { itm_tbl_hdr_t *tbl_hdr; tbl_hdr = (itm_tbl_hdr_t *)ADDR(map_place); switch (tbl_hdr->type) { case ITM_TBL_MAP_INDEX_FIXED_1_1: case ITM_TBL_MAP_INDEX_FIXED: dump_map_i_f(itm_hdr, map_place, standalone); break; case ITM_TBL_MAP_LOOKUP: dump_map_l_f(itm_hdr, map_place, standalone); break; case ITM_TBL_MAP_HASH: dump_map_hash(itm_hdr, map_place, standalone); break; case ITM_TBL_MAP_DENSE_ENC: dump_map_dense_enc(itm_hdr, map_place, standalone); break; default: break; } } /* * Dump map-indexed-fixed */ static void dump_map_i_f(itm_hdr_t *itm_hdr, itm_place_t map_place, int standalone) { itm_tbl_hdr_t *tbl_hdr; itm_map_idx_fix_hdr_t *map_hdr; itm_num_t i; itm_num_t j; unsigned char *p; unsigned char *map_error; char *name; int error_flag; TRACE_MESSAGE('d', ("dump_map_i_f\n")); tbl_hdr = (itm_tbl_hdr_t *)ADDR(map_place); map_hdr = (itm_map_idx_fix_hdr_t *)(tbl_hdr + 1); if (0 < map_hdr->error_num) { p = (unsigned char *)(map_hdr + 1); map_error = p + (map_hdr->result_len * (tbl_hdr->number)); if (0 == map_hdr->default_error) { map_error += map_hdr->result_len; } } else if (1 == map_hdr->default_error) { p = (unsigned char *)(map_hdr + 1); map_error = p + (map_hdr->result_len * (tbl_hdr->number)); } else { map_error = NULL; } if ((standalone) && (0 == tbl_hdr->name.itm_ptr) && (map_place.itm_ptr != itm_hdr->direc_init_tbl.itm_ptr)) { return; } TRACE_MESSAGE('p', ("(&)map=%ld ", map_place.itm_ptr)); if (0 == tbl_hdr->name.itm_ptr) { name = NULL; } else { name = tbl_name(itm_hdr, tbl_hdr); } if ((0 == standalone) && (0 != tbl_hdr->name.itm_ptr)) { if (NULL != name) { printi(0, "%s;\n", name); } else { printi(0, RNPREF "unknown;\n", name); } return; } else { printi(1, RNPREF "map"); if (NULL != name) { printi(0, " %s", name); } printi(0, " {\n"); } printi(0, "// simple indexed map\n"); printi(0, "// source_len=%ld result_len=%ld\n", map_hdr->source_len, map_hdr->result_len); printi(0, "// start=0x%p end=0x%p\n", /* DO NOT CHANGE to %ld */ map_hdr->start.itm_ptr, map_hdr->end.itm_ptr); if (0 < map_hdr->error_num) { printi(0, "// error_num=%ld\n", map_hdr->error_num); } if (0 == map_hdr->default_error) { p = (((unsigned char *)(map_hdr + 1)) + (map_hdr->result_len * (map_hdr->end.itm_ptr - map_hdr->start.itm_ptr + 1))); printi(0, RNPREF "default 0x"); for (j = 0; j < map_hdr->result_len; j++) { printi(0, "%02x", *(p + j)); } printi(0, "\n"); } else if (-1 == map_hdr->default_error) { printi(0, RNPREF "default\t" RNPREF "default\n"); } error_flag = 0; for (i = 0; i <= (map_hdr->end.itm_ptr - map_hdr->start.itm_ptr); i++) { p = (((unsigned char *)(map_hdr + 1)) + (map_hdr->result_len * i)); if ((NULL == map_error) || (0 == *(map_error + i))) { printi(0, "0x%0*p\t", (map_hdr->source_len * 2), i + map_hdr->start.itm_ptr); printi(0, "0x"); for (j = 0; j < map_hdr->result_len; j++) { printi(0, "%02x", *(p + j)); } error_flag = 0; printi(0, "\n"); } else if (0 >= map_hdr->default_error) { if (0 == error_flag) { printi(0, "0x%0*p\t", (map_hdr->source_len * 2), i + map_hdr->start.itm_ptr); printi(0, "error\n"); error_flag = 1; } else if (error_flag == 1) { printi(0, " :\t:\n"); error_flag = 2; } } } printi(-1, "};\n"); } /* * Dump map-lookup-fixed */ static void dump_map_l_f(itm_hdr_t *itm_hdr, itm_place_t map_place, int standalone) { itm_tbl_hdr_t *tbl_hdr; itm_map_lookup_hdr_t *map_hdr; itm_num_t i; itm_num_t j; unsigned char *p; char *name; TRACE_MESSAGE('d', ("dump_map_l_f\n")); tbl_hdr = (itm_tbl_hdr_t *)ADDR(map_place); map_hdr = (itm_map_lookup_hdr_t *)(tbl_hdr + 1); if ((standalone) && (0 == tbl_hdr->name.itm_ptr) && (map_place.itm_ptr != itm_hdr->direc_init_tbl.itm_ptr)) { return; } TRACE_MESSAGE('p', ("(&)map=%ld ", map_place.itm_ptr)); if (0 == tbl_hdr->name.itm_ptr) { name = NULL; } else { name = tbl_name(itm_hdr, tbl_hdr); } if ((0 == standalone) && (0 != tbl_hdr->name.itm_ptr)) { if (NULL != name) { printi(0, "%s;\n", name); } else { printi(0, RNPREF "unknown;\n", name); } return; } else { printi(1, RNPREF "map"); if (NULL != name) { printi(0, " %s", name); } printi(0, " {\n"); } printi(0, "// binary search map\n"); printi(0, "// source_len=%ld result_len=%ld\n", map_hdr->source_len, map_hdr->result_len); if (0 < map_hdr->error_num) { printi(0, "// error_num=%ld\n", map_hdr->error_num); } if (0 == map_hdr->default_error) { printi(0, RNPREF "default\t0x"); p = ((unsigned char *)(map_hdr + 1) + (tbl_hdr->number * (map_hdr->source_len + map_hdr->result_len + 1)) + map_hdr->source_len + 1); for (j = 0; j < map_hdr->result_len; j++, p++) { printi(0, "%02x", *p); } printi(0, "\n"); } else if (-1 == map_hdr->default_error) { printi(0, RNPREF "default\t" RNPREF "default\n"); } p = (unsigned char *)(map_hdr + 1); for (i = 0; i < tbl_hdr->number; i++) { printi(0, "0x"); for (j = 0; j < map_hdr->source_len; j++, p++) { printi(0, "%02x", *p); } if (0 != (*p)) { p += map_hdr->result_len + 1; printi(0, "\terror"); } else { p++; printi(0, "\t0x"); for (j = 0; j < map_hdr->result_len; j++, p++) { printi(0, "%02x", *p); } } printi(0, "\n"); } printi(-1, "};\n"); } /* * Dump map-hash */ static void dump_map_hash(itm_hdr_t *itm_hdr, itm_place_t map_place, int standalone) { itm_tbl_hdr_t *tbl_hdr; itm_map_hash_hdr_t *map_hdr; itm_num_t i; itm_num_t j; unsigned char *p; unsigned char *map_hash; unsigned char *map_error; char *name; TRACE_MESSAGE('d', ("dump_map_hash\n")); tbl_hdr = (itm_tbl_hdr_t *)ADDR(map_place); map_hdr = (itm_map_hash_hdr_t *)(tbl_hdr + 1); map_error = (unsigned char *)(map_hdr + 1); map_hash = (map_error + map_hdr->hash_tbl_num); if ((standalone) && (0 == tbl_hdr->name.itm_ptr) && (map_place.itm_ptr != itm_hdr->direc_init_tbl.itm_ptr)) { return; } TRACE_MESSAGE('p', ("(&)map=%ld ", map_place.itm_ptr)); if (0 == tbl_hdr->name.itm_ptr) { name = NULL; } else { name = tbl_name(itm_hdr, tbl_hdr); } if ((0 == standalone) && (0 != tbl_hdr->name.itm_ptr)) { if (NULL != name) { printi(0, "%s;\n", name); } else { printi(0, RNPREF "unknown;\n", name); } return; } else { printi(1, RNPREF "map"); if (NULL != name) { printi(0, " %s", name); } printi(0, " {\n"); } printi(0, "// hashed map\n"); printi(0, "// number=%ld\n", tbl_hdr->number); printi(0, "// source_len=%ld result_len=%ld\n", map_hdr->source_len, map_hdr->result_len); printi(0, "// hash_tbl_size=%ld hash_of_size=%ld hash_of_num=%ld\n", map_hdr->hash_tbl_size, map_hdr->hash_of_size, map_hdr->hash_of_num); if (0 < map_hdr->error_num) { printi(0, "// error_num=%ld\n", map_hdr->error_num); } if (0 == map_hdr->default_error) { printi(0, RNPREF "default\t0x"); p = map_hash + map_hdr->hash_tbl_size + map_hdr->hash_of_size; for (j = 0; j < map_hdr->result_len; j++, p++) { printi(0, "%02x", *p); } printi(0, "\n"); } else if (-1 == map_hdr->default_error) { printi(0, RNPREF "default\t" RNPREF "default\n"); } p = map_hash; TRACE_MESSAGE('d', ("dump_map_hash: %ld %ld\n", tbl_hdr->number, map_hdr->hash_of_num)); for (i = 0; i < map_hdr->hash_tbl_num; i++) { TRACE_MESSAGE('d', ("dump_map_hash: %x (0x%08p)\n", *p, p)); if (0 == *(map_error + i)) { p += (map_hdr->source_len + 1 + map_hdr->result_len); continue; } printi(0, "0x"); for (j = 0; j < map_hdr->source_len; j++, p++) { printi(0, "%02x", *p); } if (0 != (*p)) { p += map_hdr->result_len + 1; printi(0, "\terror"); } else { p++; printi(0, "\t0x"); for (j = 0; j < map_hdr->result_len; j++, p++) { printi(0, "%02x", *p); } } printi(0, "\n"); } printi(0, "// of table\n"); for (i = 0; i < map_hdr->hash_of_num; i++) { printi(0, "0x"); for (j = 0; j < map_hdr->source_len; j++, p++) { printi(0, "%02x", *p); } if (0 != (*p)) { p += map_hdr->result_len + 1; printi(0, "\terror\n"); } else { p++; printi(0, "\t0x"); for (j = 0; j < map_hdr->result_len; j++, p++) { printi(0, "%02x", *p); } printi(0, "\n"); } } printi(-1, "};\n"); } /* * Dump map-dense-encoding */ static void dump_map_dense_enc(itm_hdr_t *itm_hdr, itm_place_t map_place, int standalone) { itm_tbl_hdr_t *tbl_hdr; itm_map_dense_enc_hdr_t *map_hdr; itm_num_t i; itm_num_t j; unsigned char *p; unsigned char *map_ptr; unsigned char *map_error; unsigned char *byte_seq_min; unsigned char *byte_seq_max; char *name; int error_flag; TRACE_MESSAGE('d', ("dump_map_dense_enc\n")); tbl_hdr = (itm_tbl_hdr_t *)ADDR(map_place); map_hdr = (itm_map_dense_enc_hdr_t *)(tbl_hdr + 1); map_ptr = ((unsigned char *)(map_hdr + 1) + map_hdr->source_len + map_hdr->source_len); if (0 < map_hdr->error_num) { map_error = (map_ptr + (tbl_hdr->number * map_hdr->result_len)); if (0 == map_hdr->default_error) { map_error += map_hdr->result_len; } } else if (1 == map_hdr->default_error) { map_error = (map_ptr + (tbl_hdr->number * map_hdr->result_len)); } else { map_error = NULL; } byte_seq_min = (unsigned char *)(map_hdr + 1); byte_seq_max = byte_seq_min + map_hdr->source_len; if ((standalone) && (0 == tbl_hdr->name.itm_ptr) && (map_place.itm_ptr != itm_hdr->direc_init_tbl.itm_ptr)) { return; } TRACE_MESSAGE('p', ("(&)map=%ld ", map_place.itm_ptr)); if (0 == tbl_hdr->name.itm_ptr) { name = NULL; } else { name = tbl_name(itm_hdr, tbl_hdr); } if ((0 == standalone) && (0 != tbl_hdr->name.itm_ptr)) { if (NULL != name) { printi(0, "%s;\n", name); } else { printi(0, RNPREF "unknown;\n", name); } return; } else { printi(1, RNPREF "map"); if (NULL != name) { printi(0, " %s", name); } printi(0, " {\n"); } printi(0, "// dense encoded map\n"); printi(0, "// entry_number=%ld\n", tbl_hdr->number); printi(0, "// source_len=%ld result_len=%ld\n", map_hdr->source_len, map_hdr->result_len); printi(0, "// byte_seq_min=0x"); p = byte_seq_min; for (i = 0; i < map_hdr->source_len; i++, p++) { printi(0, "%02x", *p); } printi(0, "\n"); printi(0, "// byte_seq_max=0x"); p = byte_seq_max; for (i = 0; i < map_hdr->source_len; i++, p++) { printi(0, "%02x", *p); } printi(0, "\n"); if (0 < map_hdr->error_num) { printi(0, "// error_num=%ld\n", map_hdr->error_num); } if (0 == map_hdr->default_error) { p = (map_ptr + (tbl_hdr->number * map_hdr->result_len)); printi(0, RNPREF "default 0x"); for (j = 0; j < map_hdr->result_len; j++) { printi(0, "%02x", *(p + j)); } printi(0, "\n"); } else if (-1 == map_hdr->default_error) { printi(0, RNPREF "default\t" RNPREF "default\n"); } error_flag = 0; for (i = 0, p = map_ptr; i < tbl_hdr->number; i++, p += map_hdr->result_len) { if ((NULL == map_error) || (0 == *(map_error + i))) { printi(0, "%s\t", dense_enc_index_to_byte_seq( i, map_hdr->source_len, byte_seq_min, byte_seq_max)); printi(0, "0x"); for (j = 0; j < map_hdr->result_len; j++) { printi(0, "%02x", *(p + j)); } printi(0, "\n"); error_flag = 0; } else if (0 >= map_hdr->default_error) { if (0 == error_flag) { printi(0, "%s\t", dense_enc_index_to_byte_seq( i, map_hdr->source_len, byte_seq_min, byte_seq_max)); printi(0, "error\n"); error_flag = 1; } else if (error_flag == 1) { printi(0, " :\t:\n"); error_flag = 2; } } } printi(-1, "};\n"); } /* * Evaluate condition table */ static void dump_cond_tbl(itm_hdr_t *itm_hdr, itm_place_t cond_place, int standalone) { itm_tbl_hdr_t *cond_hdr; itm_cond_t *cond; long i; char *name; TRACE_MESSAGE('p', ("(&)cond_tbl=%ld ", cond_place.itm_ptr)); cond_hdr = (itm_tbl_hdr_t *)(ADDR(cond_place)); cond = (itm_cond_t *)(cond_hdr + 1); if ((standalone) && (0 == cond_hdr->name.itm_ptr)) { TRACE_MESSAGE('t', ("skip condition(%d, %ld)\n", standalone, cond_hdr->name.itm_ptr)); return; } if (0 == cond_place.itm_ptr) { printi(0, RNPREF "true"); return; } if (0 == cond_hdr->name.itm_ptr) { name = NULL; } else { name = tbl_name(itm_hdr, cond_hdr); } if ((0 == standalone) && (0 != cond_hdr->name.itm_ptr)) { if (NULL != name) { printi(0, "%s", name); } else { printi(0, RNPREF "unknown"); } return; } else { printi(1, RNPREF "condition"); if (NULL != name) { printi(0, " %s", name); } printi(0, " {\n"); } for (i = 0; i < cond_hdr->number; i++, cond++) { switch (cond->type) { case ITM_COND_BETWEEN: dump_range(itm_hdr, cond->operand.place); break; case ITM_COND_EXPR: dump_expr(itm_hdr, cond->operand.place); printi(0, ";\n"); break; case ITM_COND_ESCAPESEQ: dump_escapeseq(itm_hdr, cond->operand.place); break; default: printi(0, "// unknown %d\n", cond->type); break; } } if (standalone) { printi(-1, "};\n"); } else { printi(-1, "}"); } } /* * Dump operation table */ static void dump_op_tbl(itm_hdr_t *itm_hdr, itm_place_t op_tbl_place, int standalone) { itm_tbl_hdr_t *op_hdr; itm_op_t *operation; itm_place2_t op_place; long i; char *name; static int op_tbl_level; op_hdr = (itm_tbl_hdr_t *)(ADDR(op_tbl_place)); operation = (itm_op_t *)(op_hdr + 1); TRACE_MESSAGE('p', ("(&)op_tbl=%ld ", op_tbl_place)); name = tbl_name(itm_hdr, op_hdr); if ((standalone) && (NULL == name)) return; if (0 == op_tbl_level) { if ((0 == standalone) && (0 != op_hdr->name.itm_ptr)) { if (NULL != name) { printi(0, "%s;\n", name); } else { printi(0, RNPREF "unknown;", name); } return; } else { printi(1, RNPREF "operation"); if (NULL != name) { printi(0, " %s", name); } printi(0, " {\n"); } } op_tbl_level += 1; op_place = op_tbl_place.itm_ptr + (sizeof (itm_tbl_hdr_t)); for (i = 0; i < op_hdr->number; i++, operation++, op_place += (sizeof (itm_op_t))) { dump_op(itm_hdr, op_place); } op_tbl_level -= 1; if (0 == op_tbl_level) { printi(-1, "};\n"); } } /* * Evaluate single operation */ static void dump_op(itm_hdr_t *itm_hdr, itm_place2_t op_place) { itm_op_t *operation; itm_tbl_hdr_t *op_hdr; operation = (itm_op_t *)ADDR2(op_place); TRACE_MESSAGE('p', ("(&)op=%ld ", op_place)); switch (operation->type) { case ITM_OP_EXPR: dump_expr(itm_hdr, operation->data.operand[0]); printi(0, ";\n"); break; case ITM_OP_ERROR: printi(0, RNPREF "error "); dump_expr(itm_hdr, operation->data.operand[0]); printi(0, ";\n"); break; case ITM_OP_ERROR_D: printi(0, RNPREF "error %d;", operation->data.operand[0].itm_ptr); printi(0, "\n"); break; case ITM_OP_DISCARD: printi(0, RNPREF "discard "); dump_expr(itm_hdr, operation->data.operand[0]); printi(0, ";\n"); break; case ITM_OP_DISCARD_D: printi(0, RNPREF "discard %ld;\n", operation->data.operand[0].itm_ptr); break; case ITM_OP_OUT: case ITM_OP_OUT_D: case ITM_OP_OUT_R: case ITM_OP_OUT_S: case ITM_OP_OUT_INVD: printi(0, RNPREF "out = "); dump_expr(itm_hdr, operation->data.operand[0]); printi(0, ";\n"); break; case ITM_OP_IF: printi(0, RNPREF "if "); dump_expr(itm_hdr, operation->data.operand[0]); printi(1, " {\n"); dump_op_tbl(itm_hdr, operation->data.operand[1], 0); printi(-1, "}\n"); break; case ITM_OP_IF_ELSE: printi(0, RNPREF "if "); dump_expr(itm_hdr, operation->data.operand[0]); printi(1, " {\n"); dump_op_tbl(itm_hdr, operation->data.operand[1], 0); printi(-1, "} "); op_hdr = ADDR(operation->data.operand[2]); if ((1 == op_hdr->number) && ((ITM_OP_IF_ELSE == ((itm_op_t *)(op_hdr + 1))->type) || (ITM_OP_IF == ((itm_op_t *)(op_hdr + 1))->type))) { printi(0, RNPREF "else "); dump_op_tbl(itm_hdr, operation->data.operand[2], 0); } else { printi(1, RNPREF "else {\n"); dump_op_tbl(itm_hdr, operation->data.operand[2], 0); printi(-1, "}\n"); } break; case ITM_OP_DIRECTION: /* switch direction */ printi(0, RNPREF "direction %1$s;\n", tbl_name(itm_hdr, (itm_tbl_hdr_t *)ADDR(operation->data.operand[0]))); break; case ITM_OP_MAP: /* use map */ printi(0, RNPREF "map %1$s", tbl_name(itm_hdr, (itm_tbl_hdr_t *)ADDR(operation->data.operand[0]))); if (0 != operation->data.operand[1].itm_ptr) { printi(0, " "); dump_expr(itm_hdr, operation->data.operand[1]); } printi(0, ";\n"); break; case ITM_OP_OPERATION: /* invoke operation */ printi(0, RNPREF "operation %1$s;\n", tbl_name(itm_hdr, (itm_tbl_hdr_t *)ADDR(operation->data.operand[0]))); break; case ITM_OP_INIT: /* invoke init operation */ printi(0, RNPREF "operation " RNPREF "init;\n"); break; case ITM_OP_RESET: /* invoke reset operation */ printi(0, RNPREF "operation " RNPREF "reset;\n"); break; case ITM_OP_BREAK: /* break */ printi(0, RNPREF "break;\n"); break; case ITM_OP_RETURN: /* return */ printi(0, RNPREF "return;\n"); break; case ITM_OP_PRINTCHR: printi(0, RNPREF "printchr "); dump_expr(itm_hdr, operation->data.operand[0]); printi(0, ";\n"); break; case ITM_OP_PRINTHD: printi(0, RNPREF "printhd "); dump_expr(itm_hdr, operation->data.operand[0]); printi(0, ";\n"); break; case ITM_OP_PRINTINT: printi(0, RNPREF "printint "); dump_expr(itm_hdr, operation->data.operand[0]); printi(0, ";\n"); break; default: printi(0, "// unknown operation: %lx\n", operation->type); break; } } /* * Dump expression */ static void dump_expr(itm_hdr_t *itm_hdr, itm_place_t expr_place) { itm_expr_t *expr; itm_data_t data; expr = (itm_expr_t *)ADDR(expr_place); TRACE_MESSAGE('p', ("(*)ex=%ld ", expr_place.itm_ptr)); switch (expr->type) { case ITM_EXPR_NONE: /* not used */ printi(0, "none"); break; case ITM_EXPR_NOP: /* not used */ printi(0, "NOP"); break; case ITM_EXPR_NAME: /* not used */ printi(0, "NAME"); break; case ITM_EXPR_INT: /* integer */ printi(0, "%ld", expr->data.itm_exnum); break; case ITM_EXPR_SEQ: /* byte sequence */ data = expr->data.value; if ((sizeof (itm_place_t)) < data.size) { data.place.itm_ptr = (itm_place2_t)ADDR(data.place); } printi(0, "0x%s", data_to_hexadecimal(&data)); break; case ITM_EXPR_REG: /* register */ printi(0, "%s", reg_name(itm_hdr, expr->data.operand[0])); break; case ITM_EXPR_IN_VECTOR: /* in[expr] */ printi(0, RNPREF "in["); dump_expr(itm_hdr, expr->data.operand[0]); printi(0, "]"); break; case ITM_EXPR_IN_VECTOR_D: /* in[num] */ printi(0, RNPREF "in[%ld]", expr->data.operand[0].itm_ptr); if (0 == expr->data.operand[0].itm_ptr) { printi(0, " // inputsize"); } break; case ITM_EXPR_OUT: /* out */ printi(0, RNPREF "out"); break; case ITM_EXPR_TRUE: /* true */ printi(0, RNPREF "true"); break; case ITM_EXPR_FALSE: /* false */ printi(0, RNPREF "false"); break; case ITM_EXPR_UMINUS: /* unary minus */ printi(0, "-"); dump_expr(itm_hdr, expr->data.operand[0]); break; case ITM_EXPR_PLUS: /* A + B */ printi(0, "("); dump_expr(itm_hdr, expr->data.operand[0]); printi(0, " + "); dump_expr(itm_hdr, expr->data.operand[1]); printi(0, ")"); break; case ITM_EXPR_PLUS_E_D: /* exprA + B */ printi(0, "("); dump_expr(itm_hdr, expr->data.operand[0]); printi(0, " + "); printi(0, "%ld", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_PLUS_E_R: /* exprA + varB */ printi(0, "("); dump_expr(itm_hdr, expr->data.operand[0]); printi(0, " + "); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[1])); printi(0, ")"); break; case ITM_EXPR_PLUS_E_INVD: /* exprA + in[B] */ printi(0, "("); dump_expr(itm_hdr, expr->data.operand[0]); printi(0, " + "); printi(0, RNPREF "in[%ld]", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_PLUS_D_E: /* intA + exprB */ printi(0, "("); printi(0, "%ld", expr->data.operand[0].itm_ptr); printi(0, " + "); dump_expr(itm_hdr, expr->data.operand[1]); printi(0, ")"); break; case ITM_EXPR_PLUS_D_D: /* intA + B */ printi(0, "("); printi(0, "%ld", expr->data.operand[0].itm_ptr); printi(0, " + "); printi(0, "%ld", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_PLUS_D_R: /* intA + varB */ printi(0, "("); printi(0, "%ld", expr->data.operand[0].itm_ptr); printi(0, " + "); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[1])); printi(0, ")"); break; case ITM_EXPR_PLUS_D_INVD: /* intA + in[B] */ printi(0, "("); printi(0, "%ld", expr->data.operand[0].itm_ptr); printi(0, " + "); printi(0, RNPREF "in[%ld]", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_PLUS_R_E: /* varA + exprB */ printi(0, "("); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[0])); printi(0, " + "); dump_expr(itm_hdr, expr->data.operand[1]); printi(0, ")"); break; case ITM_EXPR_PLUS_R_D: /* varA + B */ printi(0, "("); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[0])); printi(0, " + "); printi(0, "%ld", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_PLUS_R_R: /* varA + varB */ printi(0, "("); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[0])); printi(0, " + "); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[1])); printi(0, ")"); break; case ITM_EXPR_PLUS_R_INVD: /* varA + in[B] */ printi(0, "("); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[0])); printi(0, " + "); printi(0, RNPREF "in[%ld]", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_PLUS_INVD_E: /* in[A] + exprB */ printi(0, "("); printi(0, RNPREF "in[%ld]", expr->data.operand[0].itm_ptr); printi(0, " + "); dump_expr(itm_hdr, expr->data.operand[1]); printi(0, ")"); break; case ITM_EXPR_PLUS_INVD_D: /* in[A] + B */ printi(0, "("); printi(0, RNPREF "in[%ld]", expr->data.operand[0].itm_ptr); printi(0, " + "); printi(0, "%ld", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_PLUS_INVD_R: /* in[A] + varB */ printi(0, "("); printi(0, RNPREF "in[%ld]", expr->data.operand[0].itm_ptr); printi(0, " + "); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[1])); printi(0, ")"); break; case ITM_EXPR_PLUS_INVD_INVD: /* in[A] + in[B] */ printi(0, "("); printi(0, RNPREF "in[%ld]", expr->data.operand[0].itm_ptr); printi(0, " + "); printi(0, RNPREF "in[%ld]", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_MINUS: /* A - B */ printi(0, "("); dump_expr(itm_hdr, expr->data.operand[0]); printi(0, " - "); dump_expr(itm_hdr, expr->data.operand[1]); printi(0, ")"); break; case ITM_EXPR_MINUS_E_D: /* exprA - B */ printi(0, "("); dump_expr(itm_hdr, expr->data.operand[0]); printi(0, " - "); printi(0, "%ld", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_MINUS_E_R: /* exprA - varB */ printi(0, "("); dump_expr(itm_hdr, expr->data.operand[0]); printi(0, " - "); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[1])); printi(0, ")"); break; case ITM_EXPR_MINUS_E_INVD: /* exprA - in[B] */ printi(0, "("); dump_expr(itm_hdr, expr->data.operand[0]); printi(0, " - "); printi(0, RNPREF "in[%ld]", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_MINUS_D_E: /* intA - exprB */ printi(0, "("); printi(0, "%ld", expr->data.operand[0].itm_ptr); printi(0, " - "); dump_expr(itm_hdr, expr->data.operand[1]); printi(0, ")"); break; case ITM_EXPR_MINUS_D_D: /* intA - B */ printi(0, "("); printi(0, "%ld", expr->data.operand[0].itm_ptr); printi(0, " - "); printi(0, "%ld", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_MINUS_D_R: /* intA - varB */ printi(0, "("); printi(0, "%ld", expr->data.operand[0].itm_ptr); printi(0, " - "); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[1])); printi(0, ")"); break; case ITM_EXPR_MINUS_D_INVD: /* intA - in[B] */ printi(0, "("); printi(0, "%ld", expr->data.operand[0].itm_ptr); printi(0, " - "); printi(0, RNPREF "in[%ld]", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_MINUS_R_E: /* varA - exprB */ printi(0, "("); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[0])); printi(0, " - "); dump_expr(itm_hdr, expr->data.operand[1]); printi(0, ")"); break; case ITM_EXPR_MINUS_R_D: /* varA - B */ printi(0, "("); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[0])); printi(0, " - "); printi(0, "%ld", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_MINUS_R_R: /* varA - varB */ printi(0, "("); printi(0, " - "); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[0])); printi(0, ")"); break; case ITM_EXPR_MINUS_R_INVD: /* varA - in[B] */ printi(0, "("); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[0])); printi(0, " - "); printi(0, RNPREF "in[%ld]", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_MINUS_INVD_E: /* in[A] - exprB */ printi(0, "("); printi(0, RNPREF "in[%ld]", expr->data.operand[0].itm_ptr); printi(0, " - "); dump_expr(itm_hdr, expr->data.operand[1]); printi(0, ")"); break; case ITM_EXPR_MINUS_INVD_D: /* in[A] - B */ printi(0, "("); printi(0, RNPREF "in[%ld]", expr->data.operand[0].itm_ptr); printi(0, " - "); printi(0, "%ld", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_MINUS_INVD_R: /* in[A] - varB */ printi(0, "("); printi(0, RNPREF "in[%ld]", expr->data.operand[0].itm_ptr); printi(0, " - "); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[1])); printi(0, ")"); break; case ITM_EXPR_MINUS_INVD_INVD: /* in[A] - in[B] */ printi(0, "("); printi(0, RNPREF "in[%ld]", expr->data.operand[0].itm_ptr); printi(0, " - "); printi(0, RNPREF "in[%ld]", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_MUL: /* A * B */ printi(0, "("); dump_expr(itm_hdr, expr->data.operand[0]); printi(0, " * "); dump_expr(itm_hdr, expr->data.operand[1]); printi(0, ")"); break; case ITM_EXPR_MUL_E_D: /* exprA * B */ printi(0, "("); dump_expr(itm_hdr, expr->data.operand[0]); printi(0, " * "); printi(0, "%ld", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_MUL_E_R: /* exprA * varB */ printi(0, "("); dump_expr(itm_hdr, expr->data.operand[0]); printi(0, " * "); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[1])); printi(0, ")"); break; case ITM_EXPR_MUL_E_INVD: /* exprA * in[B] */ printi(0, "("); dump_expr(itm_hdr, expr->data.operand[0]); printi(0, " * "); printi(0, RNPREF "in[%ld]", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_MUL_D_E: /* intA * exprB */ printi(0, "("); printi(0, "%ld", expr->data.operand[0].itm_ptr); printi(0, " * "); dump_expr(itm_hdr, expr->data.operand[1]); printi(0, ")"); break; case ITM_EXPR_MUL_D_D: /* intA * B */ printi(0, "("); printi(0, "%ld", expr->data.operand[0].itm_ptr); printi(0, " * "); printi(0, "%ld", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_MUL_D_R: /* intA * varB */ printi(0, "("); printi(0, "%ld", expr->data.operand[0].itm_ptr); printi(0, " * "); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[1])); printi(0, ")"); break; case ITM_EXPR_MUL_D_INVD: /* intA * in[B] */ printi(0, "("); printi(0, "%ld", expr->data.operand[0].itm_ptr); printi(0, " * "); printi(0, RNPREF "in[%ld]", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_MUL_R_E: /* varA * exprB */ printi(0, "("); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[0])); printi(0, " * "); dump_expr(itm_hdr, expr->data.operand[1]); printi(0, ")"); break; case ITM_EXPR_MUL_R_D: /* varA * B */ printi(0, "("); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[0])); printi(0, " * "); printi(0, "%ld", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_MUL_R_R: /* varA * varB */ printi(0, "("); printi(0, " * "); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[0])); printi(0, ")"); break; case ITM_EXPR_MUL_R_INVD: /* varA * in[B] */ printi(0, "("); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[0])); printi(0, " * "); printi(0, RNPREF "in[%ld]", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_MUL_INVD_E: /* in[A] * exprB */ printi(0, "("); printi(0, RNPREF "in[%ld]", expr->data.operand[0].itm_ptr); printi(0, " * "); dump_expr(itm_hdr, expr->data.operand[1]); printi(0, ")"); break; case ITM_EXPR_MUL_INVD_D: /* in[A] * B */ printi(0, "("); printi(0, RNPREF "in[%ld]", expr->data.operand[0].itm_ptr); printi(0, " * "); printi(0, "%ld", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_MUL_INVD_R: /* in[A] * varB */ printi(0, "("); printi(0, RNPREF "in[%ld]", expr->data.operand[0].itm_ptr); printi(0, " * "); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[1])); printi(0, ")"); break; case ITM_EXPR_MUL_INVD_INVD: /* in[A] * in[B] */ printi(0, "("); printi(0, RNPREF "in[%ld]", expr->data.operand[0].itm_ptr); printi(0, " * "); printi(0, RNPREF "in[%ld]", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_DIV: /* A / B */ printi(0, "("); dump_expr(itm_hdr, expr->data.operand[0]); printi(0, " / "); dump_expr(itm_hdr, expr->data.operand[1]); printi(0, ")"); break; case ITM_EXPR_DIV_E_D: /* exprA / B */ printi(0, "("); dump_expr(itm_hdr, expr->data.operand[0]); printi(0, " / "); printi(0, "%ld", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_DIV_E_R: /* exprA / varB */ printi(0, "("); dump_expr(itm_hdr, expr->data.operand[0]); printi(0, " / "); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[1])); printi(0, ")"); break; case ITM_EXPR_DIV_E_INVD: /* exprA / in[B] */ printi(0, "("); dump_expr(itm_hdr, expr->data.operand[0]); printi(0, " / "); printi(0, RNPREF "in[%ld]", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_DIV_D_E: /* intA / exprB */ printi(0, "("); printi(0, "%ld", expr->data.operand[0].itm_ptr); printi(0, " / "); dump_expr(itm_hdr, expr->data.operand[1]); printi(0, ")"); break; case ITM_EXPR_DIV_D_D: /* intA / B */ printi(0, "("); printi(0, "%ld", expr->data.operand[0].itm_ptr); printi(0, " / "); printi(0, "%ld", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_DIV_D_R: /* intA / varB */ printi(0, "("); printi(0, "%ld", expr->data.operand[0].itm_ptr); printi(0, " / "); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[1])); printi(0, ")"); break; case ITM_EXPR_DIV_D_INVD: /* intA / in[B] */ printi(0, "("); printi(0, "%ld", expr->data.operand[0].itm_ptr); printi(0, " / "); printi(0, RNPREF "in[%ld]", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_DIV_R_E: /* varA / exprB */ printi(0, "("); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[0])); printi(0, " / "); dump_expr(itm_hdr, expr->data.operand[1]); printi(0, ")"); break; case ITM_EXPR_DIV_R_D: /* varA / B */ printi(0, "("); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[0])); printi(0, " / "); printi(0, "%ld", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_DIV_R_R: /* varA / varB */ printi(0, "("); printi(0, " / "); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[0])); printi(0, ")"); break; case ITM_EXPR_DIV_R_INVD: /* varA / in[B] */ printi(0, "("); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[0])); printi(0, " / "); printi(0, RNPREF "in[%ld]", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_DIV_INVD_E: /* in[A] / exprB */ printi(0, "("); printi(0, RNPREF "in[%ld]", expr->data.operand[0].itm_ptr); printi(0, " / "); dump_expr(itm_hdr, expr->data.operand[1]); printi(0, ")"); break; case ITM_EXPR_DIV_INVD_D: /* in[A] / B */ printi(0, "("); printi(0, RNPREF "in[%ld]", expr->data.operand[0].itm_ptr); printi(0, " / "); printi(0, "%ld", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_DIV_INVD_R: /* in[A] / varB */ printi(0, "("); printi(0, RNPREF "in[%ld]", expr->data.operand[0].itm_ptr); printi(0, " / "); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[1])); printi(0, ")"); break; case ITM_EXPR_DIV_INVD_INVD: /* in[A] / in[B] */ printi(0, "("); printi(0, RNPREF "in[%ld]", expr->data.operand[0].itm_ptr); printi(0, " / "); printi(0, RNPREF "in[%ld]", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_MOD: /* A % B */ printi(0, "("); dump_expr(itm_hdr, expr->data.operand[0]); printi(0, " %% "); dump_expr(itm_hdr, expr->data.operand[1]); printi(0, ")"); break; case ITM_EXPR_MOD_E_D: /* exprA % B */ printi(0, "("); dump_expr(itm_hdr, expr->data.operand[0]); printi(0, " %% "); printi(0, "%ld", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_MOD_E_R: /* exprA % varB */ printi(0, "("); dump_expr(itm_hdr, expr->data.operand[0]); printi(0, " %% "); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[1])); printi(0, ")"); break; case ITM_EXPR_MOD_E_INVD: /* exprA % in[B] */ printi(0, "("); dump_expr(itm_hdr, expr->data.operand[0]); printi(0, " %% "); printi(0, RNPREF "in[%ld]", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_MOD_D_E: /* intA % exprB */ printi(0, "("); printi(0, "%ld", expr->data.operand[0].itm_ptr); printi(0, " %% "); dump_expr(itm_hdr, expr->data.operand[1]); printi(0, ")"); break; case ITM_EXPR_MOD_D_D: /* intA % B */ printi(0, "("); printi(0, "%ld", expr->data.operand[0].itm_ptr); printi(0, " %% "); printi(0, "%ld", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_MOD_D_R: /* intA % varB */ printi(0, "("); printi(0, "%ld", expr->data.operand[0].itm_ptr); printi(0, " %% "); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[1])); printi(0, ")"); break; case ITM_EXPR_MOD_D_INVD: /* intA % in[B] */ printi(0, "("); printi(0, "%ld", expr->data.operand[0].itm_ptr); printi(0, " %% "); printi(0, RNPREF "in[%ld]", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_MOD_R_E: /* varA % exprB */ printi(0, "("); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[0])); printi(0, " %% "); dump_expr(itm_hdr, expr->data.operand[1]); printi(0, ")"); break; case ITM_EXPR_MOD_R_D: /* varA % B */ printi(0, "("); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[0])); printi(0, " %% "); printi(0, "%ld", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_MOD_R_R: /* varA % varB */ printi(0, "("); printi(0, " %% "); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[0])); printi(0, ")"); break; case ITM_EXPR_MOD_R_INVD: /* varA % in[B] */ printi(0, "("); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[0])); printi(0, " %% "); printi(0, RNPREF "in[%ld]", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_MOD_INVD_E: /* in[A] % exprB */ printi(0, "("); printi(0, RNPREF "in[%ld]", expr->data.operand[0].itm_ptr); printi(0, " %% "); dump_expr(itm_hdr, expr->data.operand[1]); printi(0, ")"); break; case ITM_EXPR_MOD_INVD_D: /* in[A] % B */ printi(0, "("); printi(0, RNPREF "in[%ld]", expr->data.operand[0].itm_ptr); printi(0, " %% "); printi(0, "%ld", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_MOD_INVD_R: /* in[A] % varB */ printi(0, "("); printi(0, RNPREF "in[%ld]", expr->data.operand[0].itm_ptr); printi(0, " %% "); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[1])); printi(0, ")"); break; case ITM_EXPR_MOD_INVD_INVD: /* in[A] % in[B] */ printi(0, "("); printi(0, RNPREF "in[%ld]", expr->data.operand[0].itm_ptr); printi(0, " %% "); printi(0, RNPREF "in[%ld]", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_SHIFT_L: /* A << B */ printi(0, "("); dump_expr(itm_hdr, expr->data.operand[0]); printi(0, " << "); dump_expr(itm_hdr, expr->data.operand[1]); printi(0, ")"); break; case ITM_EXPR_SHIFT_L_E_D: /* exprA << B */ printi(0, "("); dump_expr(itm_hdr, expr->data.operand[0]); printi(0, " << "); printi(0, "%ld", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_SHIFT_L_E_R: /* exprA << varB */ printi(0, "("); dump_expr(itm_hdr, expr->data.operand[0]); printi(0, " << "); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[1])); printi(0, ")"); break; case ITM_EXPR_SHIFT_L_E_INVD: /* exprA << in[B] */ printi(0, "("); dump_expr(itm_hdr, expr->data.operand[0]); printi(0, " << "); printi(0, RNPREF "in[%ld]", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_SHIFT_L_D_E: /* intA << exprB */ printi(0, "("); printi(0, "%ld", expr->data.operand[0].itm_ptr); printi(0, " << "); dump_expr(itm_hdr, expr->data.operand[1]); printi(0, ")"); break; case ITM_EXPR_SHIFT_L_D_D: /* intA << B */ printi(0, "("); printi(0, "%ld", expr->data.operand[0].itm_ptr); printi(0, " << "); printi(0, "%ld", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_SHIFT_L_D_R: /* intA << varB */ printi(0, "("); printi(0, "%ld", expr->data.operand[0].itm_ptr); printi(0, " << "); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[1])); printi(0, ")"); break; case ITM_EXPR_SHIFT_L_D_INVD: /* intA << in[B] */ printi(0, "("); printi(0, "%ld", expr->data.operand[0].itm_ptr); printi(0, " << "); printi(0, RNPREF "in[%ld]", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_SHIFT_L_R_E: /* varA << exprB */ printi(0, "("); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[0])); printi(0, " << "); dump_expr(itm_hdr, expr->data.operand[1]); printi(0, ")"); break; case ITM_EXPR_SHIFT_L_R_D: /* varA << B */ printi(0, "("); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[0])); printi(0, " << "); printi(0, "%ld", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_SHIFT_L_R_R: /* varA << varB */ printi(0, "("); printi(0, " << "); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[0])); printi(0, ")"); break; case ITM_EXPR_SHIFT_L_R_INVD: /* varA << in[B] */ printi(0, "("); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[0])); printi(0, " << "); printi(0, RNPREF "in[%ld]", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_SHIFT_L_INVD_E: /* in[A] << exprB */ printi(0, "("); printi(0, RNPREF "in[%ld]", expr->data.operand[0].itm_ptr); printi(0, " << "); dump_expr(itm_hdr, expr->data.operand[1]); printi(0, ")"); break; case ITM_EXPR_SHIFT_L_INVD_D: /* in[A] << B */ printi(0, "("); printi(0, RNPREF "in[%ld]", expr->data.operand[0].itm_ptr); printi(0, " << "); printi(0, "%ld", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_SHIFT_L_INVD_R: /* in[A] << varB */ printi(0, "("); printi(0, RNPREF "in[%ld]", expr->data.operand[0].itm_ptr); printi(0, " << "); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[1])); printi(0, ")"); break; case ITM_EXPR_SHIFT_L_INVD_INVD: /* in[A] << in[B] */ printi(0, "("); printi(0, RNPREF "in[%ld]", expr->data.operand[0].itm_ptr); printi(0, " << "); printi(0, RNPREF "in[%ld]", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_SHIFT_R: /* A >> B */ printi(0, "("); dump_expr(itm_hdr, expr->data.operand[0]); printi(0, " >> "); dump_expr(itm_hdr, expr->data.operand[1]); printi(0, ")"); break; case ITM_EXPR_SHIFT_R_E_D: /* exprA >> B */ printi(0, "("); dump_expr(itm_hdr, expr->data.operand[0]); printi(0, " >> "); printi(0, "%ld", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_SHIFT_R_E_R: /* exprA >> varB */ printi(0, "("); dump_expr(itm_hdr, expr->data.operand[0]); printi(0, " >> "); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[1])); printi(0, ")"); break; case ITM_EXPR_SHIFT_R_E_INVD: /* exprA >> in[B] */ printi(0, "("); dump_expr(itm_hdr, expr->data.operand[0]); printi(0, " >> "); printi(0, RNPREF "in[%ld]", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_SHIFT_R_D_E: /* intA >> exprB */ printi(0, "("); printi(0, "%ld", expr->data.operand[0].itm_ptr); printi(0, " >> "); dump_expr(itm_hdr, expr->data.operand[1]); printi(0, ")"); break; case ITM_EXPR_SHIFT_R_D_D: /* intA >> B */ printi(0, "("); printi(0, "%ld", expr->data.operand[0].itm_ptr); printi(0, " >> "); printi(0, "%ld", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_SHIFT_R_D_R: /* intA >> varB */ printi(0, "("); printi(0, "%ld", expr->data.operand[0].itm_ptr); printi(0, " >> "); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[1])); printi(0, ")"); break; case ITM_EXPR_SHIFT_R_D_INVD: /* intA >> in[B] */ printi(0, "("); printi(0, "%ld", expr->data.operand[0].itm_ptr); printi(0, " >> "); printi(0, RNPREF "in[%ld]", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_SHIFT_R_R_E: /* varA >> exprB */ printi(0, "("); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[0])); printi(0, " >> "); dump_expr(itm_hdr, expr->data.operand[1]); printi(0, ")"); break; case ITM_EXPR_SHIFT_R_R_D: /* varA >> B */ printi(0, "("); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[0])); printi(0, " >> "); printi(0, "%ld", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_SHIFT_R_R_R: /* varA >> varB */ printi(0, "("); printi(0, " >> "); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[0])); printi(0, ")"); break; case ITM_EXPR_SHIFT_R_R_INVD: /* varA >> in[B] */ printi(0, "("); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[0])); printi(0, " >> "); printi(0, RNPREF "in[%ld]", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_SHIFT_R_INVD_E: /* in[A] >> exprB */ printi(0, "("); printi(0, RNPREF "in[%ld]", expr->data.operand[0].itm_ptr); printi(0, " >> "); dump_expr(itm_hdr, expr->data.operand[1]); printi(0, ")"); break; case ITM_EXPR_SHIFT_R_INVD_D: /* in[A] >> B */ printi(0, "("); printi(0, RNPREF "in[%ld]", expr->data.operand[0].itm_ptr); printi(0, " >> "); printi(0, "%ld", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_SHIFT_R_INVD_R: /* in[A] >> varB */ printi(0, "("); printi(0, RNPREF "in[%ld]", expr->data.operand[0].itm_ptr); printi(0, " >> "); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[1])); printi(0, ")"); break; case ITM_EXPR_SHIFT_R_INVD_INVD: /* in[A] >> in[B] */ printi(0, "("); printi(0, RNPREF "in[%ld]", expr->data.operand[0].itm_ptr); printi(0, " >> "); printi(0, RNPREF "in[%ld]", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_OR: /* A | B */ printi(0, "("); dump_expr(itm_hdr, expr->data.operand[0]); printi(0, " | "); dump_expr(itm_hdr, expr->data.operand[1]); printi(0, ")"); break; case ITM_EXPR_OR_E_D: /* exprA | B */ printi(0, "("); dump_expr(itm_hdr, expr->data.operand[0]); printi(0, " | "); printi(0, "%ld", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_OR_E_R: /* exprA | varB */ printi(0, "("); dump_expr(itm_hdr, expr->data.operand[0]); printi(0, " | "); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[1])); printi(0, ")"); break; case ITM_EXPR_OR_E_INVD: /* exprA | in[B] */ printi(0, "("); dump_expr(itm_hdr, expr->data.operand[0]); printi(0, " | "); printi(0, RNPREF "in[%ld]", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_OR_D_E: /* intA | exprB */ printi(0, "("); printi(0, "%ld", expr->data.operand[0].itm_ptr); printi(0, " | "); dump_expr(itm_hdr, expr->data.operand[1]); printi(0, ")"); break; case ITM_EXPR_OR_D_D: /* intA | B */ printi(0, "("); printi(0, "%ld", expr->data.operand[0].itm_ptr); printi(0, " | "); printi(0, "%ld", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_OR_D_R: /* intA | varB */ printi(0, "("); printi(0, "%ld", expr->data.operand[0].itm_ptr); printi(0, " | "); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[1])); printi(0, ")"); break; case ITM_EXPR_OR_D_INVD: /* intA | in[B] */ printi(0, "("); printi(0, "%ld", expr->data.operand[0].itm_ptr); printi(0, " | "); printi(0, RNPREF "in[%ld]", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_OR_R_E: /* varA | exprB */ printi(0, "("); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[0])); printi(0, " | "); dump_expr(itm_hdr, expr->data.operand[1]); printi(0, ")"); break; case ITM_EXPR_OR_R_D: /* varA | B */ printi(0, "("); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[0])); printi(0, " | "); printi(0, "%ld", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_OR_R_R: /* varA | varB */ printi(0, "("); printi(0, " | "); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[0])); printi(0, ")"); break; case ITM_EXPR_OR_R_INVD: /* varA | in[B] */ printi(0, "("); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[0])); printi(0, " | "); printi(0, RNPREF "in[%ld]", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_OR_INVD_E: /* in[A] | exprB */ printi(0, "("); printi(0, RNPREF "in[%ld]", expr->data.operand[0].itm_ptr); printi(0, " | "); dump_expr(itm_hdr, expr->data.operand[1]); printi(0, ")"); break; case ITM_EXPR_OR_INVD_D: /* in[A] | B */ printi(0, "("); printi(0, RNPREF "in[%ld]", expr->data.operand[0].itm_ptr); printi(0, " | "); printi(0, "%ld", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_OR_INVD_R: /* in[A] | varB */ printi(0, "("); printi(0, RNPREF "in[%ld]", expr->data.operand[0].itm_ptr); printi(0, " | "); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[1])); printi(0, ")"); break; case ITM_EXPR_OR_INVD_INVD: /* in[A] | in[B] */ printi(0, "("); printi(0, RNPREF "in[%ld]", expr->data.operand[0].itm_ptr); printi(0, " | "); printi(0, RNPREF "in[%ld]", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_XOR: /* A ^ B */ printi(0, "("); dump_expr(itm_hdr, expr->data.operand[0]); printi(0, " ^ "); dump_expr(itm_hdr, expr->data.operand[1]); printi(0, ")"); break; case ITM_EXPR_XOR_E_D: /* exprA ^ B */ printi(0, "("); dump_expr(itm_hdr, expr->data.operand[0]); printi(0, " ^ "); printi(0, "%ld", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_XOR_E_R: /* exprA ^ varB */ printi(0, "("); dump_expr(itm_hdr, expr->data.operand[0]); printi(0, " ^ "); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[1])); printi(0, ")"); break; case ITM_EXPR_XOR_E_INVD: /* exprA ^ in[B] */ printi(0, "("); dump_expr(itm_hdr, expr->data.operand[0]); printi(0, " ^ "); printi(0, RNPREF "in[%ld]", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_XOR_D_E: /* intA ^ exprB */ printi(0, "("); printi(0, "%ld", expr->data.operand[0].itm_ptr); printi(0, " ^ "); dump_expr(itm_hdr, expr->data.operand[1]); printi(0, ")"); break; case ITM_EXPR_XOR_D_D: /* intA ^ B */ printi(0, "("); printi(0, "%ld", expr->data.operand[0].itm_ptr); printi(0, " ^ "); printi(0, "%ld", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_XOR_D_R: /* intA ^ varB */ printi(0, "("); printi(0, "%ld", expr->data.operand[0].itm_ptr); printi(0, " ^ "); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[1])); printi(0, ")"); break; case ITM_EXPR_XOR_D_INVD: /* intA ^ in[B] */ printi(0, "("); printi(0, "%ld", expr->data.operand[0].itm_ptr); printi(0, " ^ "); printi(0, RNPREF "in[%ld]", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_XOR_R_E: /* varA ^ exprB */ printi(0, "("); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[0])); printi(0, " ^ "); dump_expr(itm_hdr, expr->data.operand[1]); printi(0, ")"); break; case ITM_EXPR_XOR_R_D: /* varA ^ B */ printi(0, "("); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[0])); printi(0, " ^ "); printi(0, "%ld", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_XOR_R_R: /* varA ^ varB */ printi(0, "("); printi(0, " ^ "); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[0])); printi(0, ")"); break; case ITM_EXPR_XOR_R_INVD: /* varA ^ in[B] */ printi(0, "("); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[0])); printi(0, " ^ "); printi(0, RNPREF "in[%ld]", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_XOR_INVD_E: /* in[A] ^ exprB */ printi(0, "("); printi(0, RNPREF "in[%ld]", expr->data.operand[0].itm_ptr); printi(0, " ^ "); dump_expr(itm_hdr, expr->data.operand[1]); printi(0, ")"); break; case ITM_EXPR_XOR_INVD_D: /* in[A] ^ B */ printi(0, "("); printi(0, RNPREF "in[%ld]", expr->data.operand[0].itm_ptr); printi(0, " ^ "); printi(0, "%ld", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_XOR_INVD_R: /* in[A] ^ varB */ printi(0, "("); printi(0, RNPREF "in[%ld]", expr->data.operand[0].itm_ptr); printi(0, " ^ "); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[1])); printi(0, ")"); break; case ITM_EXPR_XOR_INVD_INVD: /* in[A] ^ in[B] */ printi(0, "("); printi(0, RNPREF "in[%ld]", expr->data.operand[0].itm_ptr); printi(0, " ^ "); printi(0, RNPREF "in[%ld]", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_AND: /* A & B */ printi(0, "("); dump_expr(itm_hdr, expr->data.operand[0]); printi(0, " & "); dump_expr(itm_hdr, expr->data.operand[1]); printi(0, ")"); break; case ITM_EXPR_AND_E_D: /* exprA & B */ printi(0, "("); dump_expr(itm_hdr, expr->data.operand[0]); printi(0, " & "); printi(0, "%ld", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_AND_E_R: /* exprA & varB */ printi(0, "("); dump_expr(itm_hdr, expr->data.operand[0]); printi(0, " & "); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[1])); printi(0, ")"); break; case ITM_EXPR_AND_E_INVD: /* exprA & in[B] */ printi(0, "("); dump_expr(itm_hdr, expr->data.operand[0]); printi(0, " & "); printi(0, RNPREF "in[%ld]", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_AND_D_E: /* intA & exprB */ printi(0, "("); printi(0, "%ld", expr->data.operand[0].itm_ptr); printi(0, " & "); dump_expr(itm_hdr, expr->data.operand[1]); printi(0, ")"); break; case ITM_EXPR_AND_D_D: /* intA & B */ printi(0, "("); printi(0, "%ld", expr->data.operand[0].itm_ptr); printi(0, " & "); printi(0, "%ld", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_AND_D_R: /* intA & varB */ printi(0, "("); printi(0, "%ld", expr->data.operand[0].itm_ptr); printi(0, " & "); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[1])); printi(0, ")"); break; case ITM_EXPR_AND_D_INVD: /* intA & in[B] */ printi(0, "("); printi(0, "%ld", expr->data.operand[0].itm_ptr); printi(0, " & "); printi(0, RNPREF "in[%ld]", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_AND_R_E: /* varA & exprB */ printi(0, "("); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[0])); printi(0, " & "); dump_expr(itm_hdr, expr->data.operand[1]); printi(0, ")"); break; case ITM_EXPR_AND_R_D: /* varA & B */ printi(0, "("); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[0])); printi(0, " & "); printi(0, "%ld", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_AND_R_R: /* varA & varB */ printi(0, "("); printi(0, " & "); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[0])); printi(0, ")"); break; case ITM_EXPR_AND_R_INVD: /* varA & in[B] */ printi(0, "("); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[0])); printi(0, " & "); printi(0, RNPREF "in[%ld]", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_AND_INVD_E: /* in[A] & exprB */ printi(0, "("); printi(0, RNPREF "in[%ld]", expr->data.operand[0].itm_ptr); printi(0, " & "); dump_expr(itm_hdr, expr->data.operand[1]); printi(0, ")"); break; case ITM_EXPR_AND_INVD_D: /* in[A] & B */ printi(0, "("); printi(0, RNPREF "in[%ld]", expr->data.operand[0].itm_ptr); printi(0, " & "); printi(0, "%ld", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_AND_INVD_R: /* in[A] & varB */ printi(0, "("); printi(0, RNPREF "in[%ld]", expr->data.operand[0].itm_ptr); printi(0, " & "); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[1])); printi(0, ")"); break; case ITM_EXPR_AND_INVD_INVD: /* in[A] & in[B] */ printi(0, "("); printi(0, RNPREF "in[%ld]", expr->data.operand[0].itm_ptr); printi(0, " & "); printi(0, RNPREF "in[%ld]", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_EQ: /* A == B */ printi(0, "("); dump_expr(itm_hdr, expr->data.operand[0]); printi(0, " == "); dump_expr(itm_hdr, expr->data.operand[1]); printi(0, ")"); break; case ITM_EXPR_EQ_E_D: /* exprA == B */ printi(0, "("); dump_expr(itm_hdr, expr->data.operand[0]); printi(0, " == "); printi(0, "%ld", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_EQ_E_R: /* exprA == varB */ printi(0, "("); dump_expr(itm_hdr, expr->data.operand[0]); printi(0, " == "); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[1])); printi(0, ")"); break; case ITM_EXPR_EQ_E_INVD: /* exprA == in[B] */ printi(0, "("); dump_expr(itm_hdr, expr->data.operand[0]); printi(0, " == "); printi(0, RNPREF "in[%ld]", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_EQ_D_E: /* intA == exprB */ printi(0, "("); printi(0, "%ld", expr->data.operand[0].itm_ptr); printi(0, " == "); dump_expr(itm_hdr, expr->data.operand[1]); printi(0, ")"); break; case ITM_EXPR_EQ_D_D: /* intA == B */ printi(0, "("); printi(0, "%ld", expr->data.operand[0].itm_ptr); printi(0, " == "); printi(0, "%ld", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_EQ_D_R: /* intA == varB */ printi(0, "("); printi(0, "%ld", expr->data.operand[0].itm_ptr); printi(0, " == "); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[1])); printi(0, ")"); break; case ITM_EXPR_EQ_D_INVD: /* intA == in[B] */ printi(0, "("); printi(0, "%ld", expr->data.operand[0].itm_ptr); printi(0, " == "); printi(0, RNPREF "in[%ld]", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_EQ_R_E: /* varA == exprB */ printi(0, "("); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[0])); printi(0, " == "); dump_expr(itm_hdr, expr->data.operand[1]); printi(0, ")"); break; case ITM_EXPR_EQ_R_D: /* varA == B */ printi(0, "("); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[0])); printi(0, " == "); printi(0, "%ld", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_EQ_R_R: /* varA == varB */ printi(0, "("); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[0])); printi(0, " == "); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[1])); printi(0, ")"); break; case ITM_EXPR_EQ_R_INVD: /* varA == in[B] */ printi(0, "("); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[0])); printi(0, " == "); printi(0, RNPREF "in[%ld]", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_EQ_INVD_E: /* in[A] == exprB */ printi(0, "("); printi(0, RNPREF "in[%ld]", expr->data.operand[0].itm_ptr); printi(0, " == "); dump_expr(itm_hdr, expr->data.operand[1]); printi(0, ")"); break; case ITM_EXPR_EQ_INVD_D: /* in[A] == B */ printi(0, "("); printi(0, RNPREF "in[%ld]", expr->data.operand[0].itm_ptr); printi(0, " == "); printi(0, "%ld", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_EQ_INVD_R: /* in[A] == varB */ printi(0, "("); printi(0, RNPREF "in[%ld]", expr->data.operand[0].itm_ptr); printi(0, " == "); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[1])); printi(0, ")"); break; case ITM_EXPR_EQ_INVD_INVD: /* in[A] == in[B] */ printi(0, "("); printi(0, RNPREF "in[%ld]", expr->data.operand[0].itm_ptr); printi(0, " == "); printi(0, RNPREF "in[%ld]", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_NE: /* A != B */ printi(0, "("); dump_expr(itm_hdr, expr->data.operand[0]); printi(0, " != "); dump_expr(itm_hdr, expr->data.operand[1]); printi(0, ")"); break; case ITM_EXPR_NE_E_D: /* exprA != B */ printi(0, "("); dump_expr(itm_hdr, expr->data.operand[0]); printi(0, " != "); printi(0, "%ld", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_NE_E_R: /* exprA != varB */ printi(0, "("); dump_expr(itm_hdr, expr->data.operand[0]); printi(0, " != "); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[1])); printi(0, ")"); break; case ITM_EXPR_NE_E_INVD: /* exprA != in[B] */ printi(0, "("); dump_expr(itm_hdr, expr->data.operand[0]); printi(0, " != "); printi(0, RNPREF "in[%ld]", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_NE_D_E: /* intA != exprB */ printi(0, "("); printi(0, "%ld", expr->data.operand[0].itm_ptr); printi(0, " != "); dump_expr(itm_hdr, expr->data.operand[1]); printi(0, ")"); break; case ITM_EXPR_NE_D_D: /* intA != B */ printi(0, "("); printi(0, "%ld", expr->data.operand[0].itm_ptr); printi(0, " != "); printi(0, "%ld", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_NE_D_R: /* intA != varB */ printi(0, "("); printi(0, "%ld", expr->data.operand[0].itm_ptr); printi(0, " != "); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[1])); printi(0, ")"); break; case ITM_EXPR_NE_D_INVD: /* intA != in[B] */ printi(0, "("); printi(0, "%ld", expr->data.operand[0].itm_ptr); printi(0, " != "); printi(0, RNPREF "in[%ld]", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_NE_R_E: /* varA != exprB */ printi(0, "("); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[0])); printi(0, " != "); dump_expr(itm_hdr, expr->data.operand[1]); printi(0, ")"); break; case ITM_EXPR_NE_R_D: /* varA != B */ printi(0, "("); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[0])); printi(0, " != "); printi(0, "%ld", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_NE_R_R: /* varA != varB */ printi(0, "("); printi(0, " != "); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[0])); printi(0, ")"); break; case ITM_EXPR_NE_R_INVD: /* varA != in[B] */ printi(0, "("); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[0])); printi(0, " != "); printi(0, RNPREF "in[%ld]", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_NE_INVD_E: /* in[A] != exprB */ printi(0, "("); printi(0, RNPREF "in[%ld]", expr->data.operand[0].itm_ptr); printi(0, " != "); dump_expr(itm_hdr, expr->data.operand[1]); printi(0, ")"); break; case ITM_EXPR_NE_INVD_D: /* in[A] != B */ printi(0, "("); printi(0, RNPREF "in[%ld]", expr->data.operand[0].itm_ptr); printi(0, " != "); printi(0, "%ld", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_NE_INVD_R: /* in[A] != varB */ printi(0, "("); printi(0, RNPREF "in[%ld]", expr->data.operand[0].itm_ptr); printi(0, " != "); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[1])); printi(0, ")"); break; case ITM_EXPR_NE_INVD_INVD: /* in[A] != in[B] */ printi(0, "("); printi(0, RNPREF "in[%ld]", expr->data.operand[0].itm_ptr); printi(0, " != "); printi(0, RNPREF "in[%ld]", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_GT: /* A > B */ printi(0, "("); dump_expr(itm_hdr, expr->data.operand[0]); printi(0, " > "); dump_expr(itm_hdr, expr->data.operand[1]); printi(0, ")"); break; case ITM_EXPR_GT_E_D: /* exprA > B */ printi(0, "("); dump_expr(itm_hdr, expr->data.operand[0]); printi(0, " > "); printi(0, "%ld", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_GT_E_R: /* exprA > varB */ printi(0, "("); dump_expr(itm_hdr, expr->data.operand[0]); printi(0, " > "); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[1])); printi(0, ")"); break; case ITM_EXPR_GT_E_INVD: /* exprA > in[B] */ printi(0, "("); dump_expr(itm_hdr, expr->data.operand[0]); printi(0, " > "); printi(0, RNPREF "in[%ld]", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_GT_D_E: /* intA > exprB */ printi(0, "("); printi(0, "%ld", expr->data.operand[0].itm_ptr); printi(0, " > "); dump_expr(itm_hdr, expr->data.operand[1]); printi(0, ")"); break; case ITM_EXPR_GT_D_D: /* intA > B */ printi(0, "("); printi(0, "%ld", expr->data.operand[0].itm_ptr); printi(0, " > "); printi(0, "%ld", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_GT_D_R: /* intA > varB */ printi(0, "("); printi(0, "%ld", expr->data.operand[0].itm_ptr); printi(0, " > "); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[1])); printi(0, ")"); break; case ITM_EXPR_GT_D_INVD: /* intA > in[B] */ printi(0, "("); printi(0, "%ld", expr->data.operand[0].itm_ptr); printi(0, " > "); printi(0, RNPREF "in[%ld]", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_GT_R_E: /* varA > exprB */ printi(0, "("); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[0])); printi(0, " > "); dump_expr(itm_hdr, expr->data.operand[1]); printi(0, ")"); break; case ITM_EXPR_GT_R_D: /* varA > B */ printi(0, "("); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[0])); printi(0, " > "); printi(0, "%ld", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_GT_R_R: /* varA > varB */ printi(0, "("); printi(0, " > "); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[0])); printi(0, ")"); break; case ITM_EXPR_GT_R_INVD: /* varA > in[B] */ printi(0, "("); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[0])); printi(0, " > "); printi(0, RNPREF "in[%ld]", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_GT_INVD_E: /* in[A] > exprB */ printi(0, "("); printi(0, RNPREF "in[%ld]", expr->data.operand[0].itm_ptr); printi(0, " > "); dump_expr(itm_hdr, expr->data.operand[1]); printi(0, ")"); break; case ITM_EXPR_GT_INVD_D: /* in[A] > B */ printi(0, "("); printi(0, RNPREF "in[%ld]", expr->data.operand[0].itm_ptr); printi(0, " > "); printi(0, "%ld", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_GT_INVD_R: /* in[A] > varB */ printi(0, "("); printi(0, RNPREF "in[%ld]", expr->data.operand[0].itm_ptr); printi(0, " > "); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[1])); printi(0, ")"); break; case ITM_EXPR_GT_INVD_INVD: /* in[A] > in[B] */ printi(0, "("); printi(0, RNPREF "in[%ld]", expr->data.operand[0].itm_ptr); printi(0, " > "); printi(0, RNPREF "in[%ld]", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_GE: /* A >= B */ printi(0, "("); dump_expr(itm_hdr, expr->data.operand[0]); printi(0, " >= "); dump_expr(itm_hdr, expr->data.operand[1]); printi(0, ")"); break; case ITM_EXPR_GE_E_D: /* exprA >= B */ printi(0, "("); dump_expr(itm_hdr, expr->data.operand[0]); printi(0, " >= "); printi(0, "%ld", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_GE_E_R: /* exprA >= varB */ printi(0, "("); dump_expr(itm_hdr, expr->data.operand[0]); printi(0, " >= "); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[1])); printi(0, ")"); break; case ITM_EXPR_GE_E_INVD: /* exprA >= in[B] */ printi(0, "("); dump_expr(itm_hdr, expr->data.operand[0]); printi(0, " >= "); printi(0, RNPREF "in[%ld]", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_GE_D_E: /* intA >= exprB */ printi(0, "("); printi(0, "%ld", expr->data.operand[0].itm_ptr); printi(0, " >= "); dump_expr(itm_hdr, expr->data.operand[1]); printi(0, ")"); break; case ITM_EXPR_GE_D_D: /* intA >= B */ printi(0, "("); printi(0, "%ld", expr->data.operand[0].itm_ptr); printi(0, " >= "); printi(0, "%ld", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_GE_D_R: /* intA >= varB */ printi(0, "("); printi(0, "%ld", expr->data.operand[0].itm_ptr); printi(0, " >= "); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[1])); printi(0, ")"); break; case ITM_EXPR_GE_D_INVD: /* intA >= in[B] */ printi(0, "("); printi(0, "%ld", expr->data.operand[0].itm_ptr); printi(0, " >= "); printi(0, RNPREF "in[%ld]", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_GE_R_E: /* varA >= exprB */ printi(0, "("); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[0])); printi(0, " >= "); dump_expr(itm_hdr, expr->data.operand[1]); printi(0, ")"); break; case ITM_EXPR_GE_R_D: /* varA >= B */ printi(0, "("); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[0])); printi(0, " >= "); printi(0, "%ld", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_GE_R_R: /* varA >= varB */ printi(0, "("); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[0])); printi(0, " >= "); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[1])); printi(0, ")"); break; case ITM_EXPR_GE_R_INVD: /* varA >= in[B] */ printi(0, "("); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[0])); printi(0, " >= "); printi(0, RNPREF "in[%ld]", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_GE_INVD_E: /* in[A] >= exprB */ printi(0, "("); printi(0, RNPREF "in[%ld]", expr->data.operand[0].itm_ptr); printi(0, " >= "); dump_expr(itm_hdr, expr->data.operand[1]); printi(0, ")"); break; case ITM_EXPR_GE_INVD_D: /* in[A] >= B */ printi(0, "("); printi(0, RNPREF "in[%ld]", expr->data.operand[0].itm_ptr); printi(0, " >= "); printi(0, "%ld", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_GE_INVD_R: /* in[A] >= varB */ printi(0, "("); printi(0, RNPREF "in[%ld]", expr->data.operand[0].itm_ptr); printi(0, " >= "); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[1])); printi(0, ")"); break; case ITM_EXPR_GE_INVD_INVD: /* in[A] >= in[B] */ printi(0, "("); printi(0, RNPREF "in[%ld]", expr->data.operand[0].itm_ptr); printi(0, " >= "); printi(0, RNPREF "in[%ld]", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_LT: /* A < B */ printi(0, "("); dump_expr(itm_hdr, expr->data.operand[0]); printi(0, " < "); dump_expr(itm_hdr, expr->data.operand[1]); printi(0, ")"); break; case ITM_EXPR_LT_E_D: /* exprA < B */ printi(0, "("); dump_expr(itm_hdr, expr->data.operand[0]); printi(0, " < "); printi(0, "%ld", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_LT_E_R: /* exprA < varB */ printi(0, "("); dump_expr(itm_hdr, expr->data.operand[0]); printi(0, " < "); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[1])); printi(0, ")"); break; case ITM_EXPR_LT_E_INVD: /* exprA < in[B] */ printi(0, "("); dump_expr(itm_hdr, expr->data.operand[0]); printi(0, " < "); printi(0, RNPREF "in[%ld]", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_LT_D_E: /* intA < exprB */ printi(0, "("); printi(0, "%ld", expr->data.operand[0].itm_ptr); printi(0, " < "); dump_expr(itm_hdr, expr->data.operand[1]); printi(0, ")"); break; case ITM_EXPR_LT_D_D: /* intA < B */ printi(0, "("); printi(0, "%ld", expr->data.operand[0].itm_ptr); printi(0, " < "); printi(0, "%ld", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_LT_D_R: /* intA < varB */ printi(0, "("); printi(0, "%ld", expr->data.operand[0].itm_ptr); printi(0, " < "); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[1])); printi(0, ")"); break; case ITM_EXPR_LT_D_INVD: /* intA < in[B] */ printi(0, "("); printi(0, "%ld", expr->data.operand[0].itm_ptr); printi(0, " < "); printi(0, RNPREF "in[%ld]", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_LT_R_E: /* varA < exprB */ printi(0, "("); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[0])); printi(0, " < "); dump_expr(itm_hdr, expr->data.operand[1]); printi(0, ")"); break; case ITM_EXPR_LT_R_D: /* varA < B */ printi(0, "("); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[0])); printi(0, " < "); printi(0, "%ld", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_LT_R_R: /* varA < varB */ printi(0, "("); printi(0, " < "); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[0])); printi(0, ")"); break; case ITM_EXPR_LT_R_INVD: /* varA < in[B] */ printi(0, "("); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[0])); printi(0, " < "); printi(0, RNPREF "in[%ld]", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_LT_INVD_E: /* in[A] < exprB */ printi(0, "("); printi(0, RNPREF "in[%ld]", expr->data.operand[0].itm_ptr); printi(0, " < "); dump_expr(itm_hdr, expr->data.operand[1]); printi(0, ")"); break; case ITM_EXPR_LT_INVD_D: /* in[A] < B */ printi(0, "("); printi(0, RNPREF "in[%ld]", expr->data.operand[0].itm_ptr); printi(0, " < "); printi(0, "%ld", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_LT_INVD_R: /* in[A] < varB */ printi(0, "("); printi(0, RNPREF "in[%ld]", expr->data.operand[0].itm_ptr); printi(0, " < "); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[1])); printi(0, ")"); break; case ITM_EXPR_LT_INVD_INVD: /* in[A] < in[B] */ printi(0, "("); printi(0, RNPREF "in[%ld]", expr->data.operand[0].itm_ptr); printi(0, " < "); printi(0, RNPREF "in[%ld]", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_LE: /* A <= B */ printi(0, "("); dump_expr(itm_hdr, expr->data.operand[0]); printi(0, " <= "); dump_expr(itm_hdr, expr->data.operand[1]); printi(0, ")"); break; case ITM_EXPR_LE_E_D: /* exprA <= B */ printi(0, "("); dump_expr(itm_hdr, expr->data.operand[0]); printi(0, " <= "); printi(0, "%ld", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_LE_E_R: /* exprA <= varB */ printi(0, "("); dump_expr(itm_hdr, expr->data.operand[0]); printi(0, " <= "); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[1])); printi(0, ")"); break; case ITM_EXPR_LE_E_INVD: /* exprA <= in[B] */ printi(0, "("); dump_expr(itm_hdr, expr->data.operand[0]); printi(0, " <= "); printi(0, RNPREF "in[%ld]", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_LE_D_E: /* intA <= exprB */ printi(0, "("); printi(0, "%ld", expr->data.operand[0].itm_ptr); printi(0, " <= "); dump_expr(itm_hdr, expr->data.operand[1]); printi(0, ")"); break; case ITM_EXPR_LE_D_D: /* intA <= B */ printi(0, "("); printi(0, "%ld", expr->data.operand[0].itm_ptr); printi(0, " <= "); printi(0, "%ld", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_LE_D_R: /* intA <= varB */ printi(0, "("); printi(0, "%ld", expr->data.operand[0].itm_ptr); printi(0, " <= "); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[1])); printi(0, ")"); break; case ITM_EXPR_LE_D_INVD: /* intA <= in[B] */ printi(0, "("); printi(0, "%ld", expr->data.operand[0].itm_ptr); printi(0, " <= "); printi(0, RNPREF "in[%ld]", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_LE_R_E: /* varA <= exprB */ printi(0, "("); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[0])); printi(0, " <= "); dump_expr(itm_hdr, expr->data.operand[1]); printi(0, ")"); break; case ITM_EXPR_LE_R_D: /* varA <= B */ printi(0, "("); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[0])); printi(0, " <= "); printi(0, "%ld", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_LE_R_R: /* varA <= varB */ printi(0, "("); printi(0, " <= "); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[0])); printi(0, ")"); break; case ITM_EXPR_LE_R_INVD: /* varA <= in[B] */ printi(0, "("); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[0])); printi(0, " <= "); printi(0, RNPREF "in[%ld]", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_LE_INVD_E: /* in[A] <= exprB */ printi(0, "("); printi(0, RNPREF "in[%ld]", expr->data.operand[0].itm_ptr); printi(0, " <= "); dump_expr(itm_hdr, expr->data.operand[1]); printi(0, ")"); break; case ITM_EXPR_LE_INVD_D: /* in[A] <= B */ printi(0, "("); printi(0, RNPREF "in[%ld]", expr->data.operand[0].itm_ptr); printi(0, " <= "); printi(0, "%ld", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_LE_INVD_R: /* in[A] <= varB */ printi(0, "("); printi(0, RNPREF "in[%ld]", expr->data.operand[0].itm_ptr); printi(0, " <= "); printi(0, "%s", reg_name(itm_hdr, expr->data.operand[1])); printi(0, ")"); break; case ITM_EXPR_LE_INVD_INVD: /* in[A] <= in[B] */ printi(0, "("); printi(0, RNPREF "in[%ld]", expr->data.operand[0].itm_ptr); printi(0, " <= "); printi(0, RNPREF "in[%ld]", expr->data.operand[1].itm_ptr); printi(0, ")"); break; case ITM_EXPR_NOT: /* !A */ printi(0, "("); printi(0, "!"); dump_expr(itm_hdr, expr->data.operand[0]); printi(0, ")"); break; case ITM_EXPR_NEG: /* ~A */ printi(0, "("); printi(0, " ~"); dump_expr(itm_hdr, expr->data.operand[0]); printi(0, ")"); break; case ITM_EXPR_LOR: /* A || B */ printi(0, "("); dump_expr(itm_hdr, expr->data.operand[0]); printi(0, " || "); dump_expr(itm_hdr, expr->data.operand[1]); printi(0, ")"); break; case ITM_EXPR_LAND: /* A && B */ printi(0, "("); dump_expr(itm_hdr, expr->data.operand[0]); printi(0, " && "); dump_expr(itm_hdr, expr->data.operand[1]); printi(0, ")"); break; case ITM_EXPR_ASSIGN: /* A = B */ printi(0, "%s = ", reg_name(itm_hdr, expr->data.operand[0])); dump_expr(itm_hdr, expr->data.operand[1]); break; case ITM_EXPR_IN_EQ: /* in == A */ printi(0, "(" RNPREF "in == ", 0); dump_expr(itm_hdr, expr->data.operand[0]); printi(0, ")"); break; default: break; } } /* * Dump range (between) */ static void dump_range(itm_hdr_t *itm_hdr, itm_place_t range_place) { itm_tbl_hdr_t *rth; itm_range_hdr_t *rtsh; unsigned char *p; long i; long j; rth = (itm_tbl_hdr_t *)(ADDR(range_place)); rtsh = (itm_range_hdr_t *)(rth + 1); p = (unsigned char *)(rtsh + 1); TRACE_MESSAGE('p', ("(&)between=%ld ", range_place.itm_ptr)); printi(0, RNPREF "between "); for (i = 0; i < rth->number; i++) { if (0 != i) printi(0, "\t "); printi(0, "0x"); for (j = 0; j < rtsh->len; j++) { printi(0, "%02x", *(p++)); } printi(0, " - "); printi(0, "0x"); for (j = 0; j < rtsh->len; j++) { printi(0, "%02x", *(p++)); } if (i < (rth->number - 1)) { printi(0, ",\n"); } else { printi(0, ";\n"); } } } /* * Dump escape sequence */ static void dump_escapeseq(itm_hdr_t *itm_hdr, itm_place_t escapeseq_place) { itm_tbl_hdr_t *eth; itm_escapeseq_hdr_t *eh; itm_data_t *d; itm_data_t data; long i; eth = (itm_tbl_hdr_t *)(ADDR(escapeseq_place)); eh = (itm_escapeseq_hdr_t *)(eth + 1); d = (itm_data_t *)(eh + 1); TRACE_MESSAGE('p', ("(&)escseq=%ld ", escapeseq_place.itm_ptr)); printi(1, RNPREF "escapceseq {"); for (i = 0; i < eth->number; i++, d++) { if (0 != i) printi(0, " "); data = *d; if ((sizeof (itm_place_t)) < data.size) { data.place.itm_ptr = (itm_place2_t)ADDR(d->place); } printi(0, "0x%s;", data_to_hexadecimal(&data)); } printi(-1, "}\n"); } static void printi(int c, char *format, ...) { static int indent_level; static int new_line = 1; int i; va_list ap; va_start(ap, format); if (c < 0) { indent_level += c; if (indent_level < 0) { indent_level = 0; } } if (new_line) { for (i = indent_level; 0 < i; i -= 1) { (void) putchar('\t'); } } if (0 < c) { indent_level += c; if (indent_level < 0) { indent_level = 0; } } if (NULL == strchr(format, '\n')) { new_line = 0; } else { new_line = 1; } (void) vfprintf(stdout, format, ap); va_end(ap); } static char * name_place_to_str(itm_hdr_t *itm_hdr, itm_place2_t place) { itm_data_t d; if (0 != place) { d = *((itm_data_t *)ADDR2(place)); if ((sizeof (itm_place_t)) < d.size) { d.place.itm_ptr = (itm_place2_t)ADDR(d.place); } } else { d.size = 0; d.place.itm_ptr = 0; } return (name_to_str(&d)); } static char * tbl_name(itm_hdr_t *itm_hdr, itm_tbl_hdr_t *tbl_hdr) { if (ITM_TBL_OP_INIT == tbl_hdr->type) { return (RNPREF "init"); } else if (ITM_TBL_OP_RESET == tbl_hdr->type) { return (RNPREF "reset"); } else if (tbl_hdr->name.itm_ptr) { return (name_place_to_str(itm_hdr, tbl_hdr->name.itm_ptr)); } else { return (NULL); } } static char * reg_name(itm_hdr_t *itm_hdr, itm_place_t op) { itm_info_hdr_t *info_hdr; static char sbuf[32]; itm_num_t reg_num; reg_num = (itm_num_t)(op.itm_ptr); if (0 == itm_hdr->info_hdr.itm_ptr) { (void) sprintf(sbuf, "reg%ld\n", reg_num); return (sbuf); } else { info_hdr = INFO_HDR(itm_hdr); return (name_place_to_str( itm_hdr, info_hdr->reg_plc_tbl.place.itm_ptr + (reg_num *sizeof (itm_data_t)))); } } static itm_hdr_t * itm_attach(const char *itm_file) { itm_hdr_t *itm_hdr; struct stat st; int fd; fd = open(itm_file, O_RDONLY, 0); if (fd == -1) { PERROR(gettext("open()")); return (NULL); } if (fstat(fd, &st) == -1) { PERROR(gettext("fstat()")); return (NULL); } itm_hdr = (void *) mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0); if (MAP_FAILED == itm_hdr) { PERROR(gettext("mmap()")); return (NULL); } (void) close(fd); if ((itm_hdr->ident[0] != ITM_IDENT_0) || (itm_hdr->ident[1] != ITM_IDENT_1) || (itm_hdr->ident[2] != ITM_IDENT_2) || (itm_hdr->ident[3] != ITM_IDENT_3)) { itm_error(gettext("magic number error\n")); return (NULL); } if ((itm_hdr->version[0] != ITM_VER_0) || (itm_hdr->version[1] != ITM_VER_1) || (itm_hdr->version[2] != ITM_VER_2) || #if defined(_LITTLE_ENDIAN) #if defined(_LP64) ((itm_hdr->spec[3] != ITM_SPEC_3_32_LITTLE_ENDIAN) && (itm_hdr->spec[3] != ITM_SPEC_3_64_LITTLE_ENDIAN))) { #else (itm_hdr->spec[3] != ITM_SPEC_3_32_LITTLE_ENDIAN)) { #endif #else #if defined(_LP64) ((itm_hdr->spec[3] != ITM_SPEC_3_32_BIG_ENDIAN) && (itm_hdr->spec[3] != ITM_SPEC_3_64_BIG_ENDIAN))) { #else (itm_hdr->spec[3] != ITM_SPEC_3_32_BIG_ENDIAN)) { #endif #endif itm_error(gettext("version number error\n")); return (NULL); } if (itm_hdr->itm_size.itm_ptr != st.st_size) { itm_error(gettext( "size error: expected=%1$d current=%2$d\n"), (size_t)(itm_hdr->itm_size.itm_ptr), st.st_size); return (NULL); } return (itm_hdr); } /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #include #include #include #include #include #include #include #include #include #include #if defined(DEBUG) #include #endif /* !DEBUG */ #include "iconv_tm.h" #include "hash.h" /* * Debug */ #if defined(DEBUG) static void trace_init(void); static void trace_message(char *, ...); static char trace_option[128]; #define TRACE(c) (*(trace_option + (c & 0x007f))) #define TRACE_MESSAGE(c, args) ((TRACE(c))? trace_message args: (void)0) #else /* !DEBUG */ #define trace_init() #define TRACE() #define TRACE_MESSAGE(c, args) #endif /* !DEBUG */ /* * ITM reference information */ typedef struct _itm_ref { char *name; /* ITM file name */ itm_hdr_t *hdr; /* address of ITM */ size_t len; /* length of ITM */ } itm_ref_t; /* * struct _icv_state; to keep status */ typedef struct _icv_state { struct _itm_ref *itm; /* reference to ITM */ itm_hdr_t *itm_hdr; /* address of ITM */ itm_tbl_hdr_t *direc; /* current direction */ itm_place_t default_action; /* default action */ itm_num_t *regs; /* register */ itm_num_t reg_num; /* number of register */ #if defined(OP_DEPTH_MAX) int op_depth; /* depth of operation */ #endif /* OP_DEPTH_MAX */ } icv_state_t; /* * function prototype */ void * _icv_open(const char *); void _icv_close(icv_state_t *); size_t _icv_iconv(icv_state_t *, const unsigned char **, size_t *, unsigned char **, size_t *); static size_t map_i_f(itm_tbl_hdr_t *, const unsigned char **, size_t *, unsigned char **, size_t *, long); static size_t map_l_f(itm_tbl_hdr_t *, const unsigned char **, size_t *, unsigned char **, size_t *, long); static size_t map_h_l(itm_tbl_hdr_t *, const unsigned char **, size_t *, unsigned char **, size_t *, long); static size_t map_d_e_l(itm_tbl_hdr_t *, const unsigned char **, size_t *, unsigned char **, size_t *, long); static size_t eval_cond_tbl(icv_state_t *, itm_place_t, const unsigned char **, size_t *, size_t, itm_direc_t *); static size_t eval_op_tbl(icv_state_t *, itm_place_t, const unsigned char **, size_t *, unsigned char **, size_t *); static size_t eval_op(icv_state_t *, itm_place2_t, const unsigned char **, size_t *, unsigned char **, size_t *); static itm_num_t eval_expr(icv_state_t *, itm_place_t, size_t, const unsigned char *, size_t); static void itm_ref_free(int, void *, void *, void *, size_t); static itm_ref_t *itm_ref_inc(const char *); static void itm_ref_dec(itm_ref_t *); static void op_init_default(icv_state_t *); static void op_reset_default(icv_state_t *); static void regs_init(icv_state_t *); /* * macro definition */ #define ADDR(place) ((void *)(((char *)(ist->itm_hdr)) +\ ((itm_place2_t)(place.itm_ptr)))) #define ADDR2(place2) ((void *)(((char *)(ist->itm_hdr)) +\ ((itm_place2_t)(place2)))) #define DADDR(n) (((n)->size <= (sizeof ((n)->place.itm_64d))) ? \ ((unsigned char *)(&((n)->place.itm_64d))) :\ ((unsigned char *)(ADDR((n)->place)))) #define REG(n) (*(ist->regs + (n))) #define DISCARD(c) (((*inbuf) = (void *)((*inbuf) + (c))),\ ((*inbytesleft) -= (c))) #define GET(c) ((c) = **inbuf, (*inbuf)++, (*inbytesleft)--) #define PUT(c) (**outbuf = (c), (*outbuf)++, (*outbytesleft)--) #define RETVALERR ((size_t)(-1)) #define RETVALDIR ((size_t)(-2)) #define RETVALBRK ((size_t)(-3)) #define RETVALRET ((size_t)(-4)) #define UPDATE_ARGS() (*inbuf = ip, \ *inbytesleft = ileft, \ *outbuf = op, \ *outbytesleft = oleft) /* * Open; called from iconv_open() */ void * _icv_open(const char *itm) { icv_state_t *ist; itm_hdr_t *hdr; itm_ref_t *itm_ref; int r; /* * for debug */ trace_init(); /* * _icv_open() primaty task */ itm_ref = itm_ref_inc(itm); if (NULL == itm_ref) { return ((void *)(-1)); } if (NULL == (ist = malloc(sizeof (icv_state_t)))) { r = errno; itm_ref_dec(itm_ref); errno = r; return (NULL); } ist->itm = itm_ref; ist->itm_hdr = ist->itm->hdr; ist->reg_num = ist->itm->hdr->reg_num; hdr = ist->itm->hdr; ist->direc = ADDR(hdr->direc_init_tbl); ist->default_action.itm_64d = 0; #if defined(OP_DEPTH_MAX) ist->op_depth = 0; #endif /* OP_DEPTH_MAX */ /* * brief sanity check */ if (hdr->itm_size.itm_ptr <= hdr->direc_init_tbl.itm_ptr) { _icv_close(ist); errno = ELIBBAD; return ((void *)(-1)); } /* allocate register region */ if (hdr->reg_num <= 0) { ist->regs = NULL; } else { ist->regs = malloc((sizeof (itm_num_t)) * hdr->reg_num); if (NULL == ist->regs) { r = errno; _icv_close(ist); errno = r; return ((void *)(-1)); } (void) memset(ist->regs, 0, (sizeof (itm_num_t)) * hdr->reg_num); } /* evaluate init operation */ if (0 != ist->itm_hdr->op_init_tbl.itm_ptr) { const unsigned char *ip = NULL; size_t ileft = 0; unsigned char *op = NULL; size_t oleft = 0; (void) eval_op_tbl(ist, ist->itm_hdr->op_init_tbl, &ip, &ileft, &op, &oleft); } else { op_init_default(ist); } return (ist); } /* * Close; called from iconv_close */ void _icv_close(icv_state_t *ist) { if (NULL == ist) { errno = EBADF; return; } itm_ref_dec(ist->itm); free(ist->regs); free(ist); } /* * Actual conversion; called from iconv() */ size_t _icv_iconv( icv_state_t *ist, const unsigned char **inbuf, size_t *inbytesleft, unsigned char **outbuf, size_t *outbytesleft) { size_t retval; itm_hdr_t *hdr; itm_type_t type; const unsigned char *ip; size_t ileft; itm_place_t action; if (NULL == ist) { errno = EBADF; TRACE_MESSAGE('e', ("_icv_iconv: error=%d\n", errno)); return ((size_t)(-1)); } if (NULL == inbuf) { ip = NULL; inbuf = &ip; } if (NULL == inbytesleft) { ileft = 0; inbytesleft = &ileft; } hdr = ist->itm_hdr; retval = 0; TRACE_MESSAGE('i', ("_icv_iconv(inbuf=%p inbytesleft=%ld " "outbuf=%p outbytesleft=%ld)\n", (NULL == inbuf) ? 0 : *inbuf, (NULL == inbytesleft) ? 0 : *inbytesleft, (NULL == outbuf) ? 0 : *outbuf, (NULL == outbytesleft) ? 0 : *outbytesleft)); /* * If (NULL == inbuf || NULL == *inbuf) then this conversion is * placed into initial state. */ if ((NULL == inbuf) || (NULL == *inbuf)) { if (0 != hdr->op_reset_tbl.itm_ptr) { ist->direc = ADDR(hdr->direc_init_tbl); retval = eval_op_tbl(ist, hdr->op_reset_tbl, inbuf, inbytesleft, outbuf, outbytesleft); if ((size_t)(-1) == retval) { return (retval); } } else { op_reset_default(ist); } return ((size_t)(0)); } if (ITM_TBL_MAP_INDEX_FIXED_1_1 == ist->direc->type) { itm_map_idx_fix_hdr_t *map_hdr; char *map; const unsigned char *ip; size_t ileft; unsigned char *op; size_t oleft; map_hdr = (itm_map_idx_fix_hdr_t *)(ist->direc + 1); map = (char *)(map_hdr + 1); if (1 == map_hdr->default_error) { retval = map_i_f(ist->direc, inbuf, inbytesleft, outbuf, outbytesleft, 0); return (retval); } ip = *inbuf; ileft = *inbytesleft; op = *outbuf; oleft = *outbytesleft; while (1 <= ileft) { if (oleft < 1) { UPDATE_ARGS(); errno = E2BIG; TRACE_MESSAGE('e', ("_icv_iconv: error=%d\n", errno)); return ((size_t)-1); } *(op++) = *(map + *(ip++)); ileft--; oleft--; } UPDATE_ARGS(); return (0); } else if (ITM_TBL_MAP_INDEX_FIXED == ist->direc->type) { retval = map_i_f(ist->direc, inbuf, inbytesleft, outbuf, outbytesleft, 0); return (retval); } else if (ITM_TBL_MAP_HASH == ist->direc->type) { retval = map_h_l(ist->direc, inbuf, inbytesleft, outbuf, outbytesleft, 0); return (retval); } else if (ITM_TBL_MAP_DENSE_ENC == ist->direc->type) { retval = map_d_e_l(ist->direc, inbuf, inbytesleft, outbuf, outbytesleft, 0); return (retval); } else if (ITM_TBL_MAP_LOOKUP == ist->direc->type) { retval = map_l_f(ist->direc, inbuf, inbytesleft, outbuf, outbytesleft, 0); return (retval); } #if defined(OP_DEPTH_MAX) ist->op_depth = 0; #endif /* OP_DEPTH_MAX */ /* * Main loop; basically 1 loop per 1 output character */ retry_cond_eval: while (0 < *inbytesleft) { itm_tbl_hdr_t *direc_hdr; itm_direc_t *direc; long i; direc_hdr = ist->direc; direc = (itm_direc_t *)(ist->direc + 1); for (i = 0; /* NULL */; i++, direc++) { if (i >= direc_hdr->number) { if (0 == ist->default_action.itm_ptr) { errno = EILSEQ; TRACE_MESSAGE('e', ("_icv_iconv:error=%d\n", errno)); return ((size_t)(-1)); } action = ist->default_action; type = ((itm_tbl_hdr_t *)(ADDR(action)))->type; TRACE_MESSAGE('E', ("escape seq (default action=%6p, " "type=%ld) executing\n", action.itm_ptr, type)); } else if (0 != direc->condition.itm_ptr) { retval = eval_cond_tbl(ist, direc->condition, inbuf, inbytesleft, *outbytesleft, direc); if ((size_t)(0) == retval) { continue; } else if ((size_t)(-1) == retval) { return (retval); } else if ((size_t)(2) == retval) { goto retry_cond_eval; } action = direc->action; type = ((itm_tbl_hdr_t *)(ADDR(action)))->type; } else { action = direc->action; type = ((itm_tbl_hdr_t *)(ADDR(action)))->type; } TRACE_MESSAGE('a', ("inbytesleft=%ld; type=%ld:action=%p\n", *inbytesleft, type, action.itm_ptr)); switch (ITM_TBL_MASK & type) { case ITM_TBL_OP: retval = eval_op_tbl(ist, action, inbuf, inbytesleft, outbuf, outbytesleft); if ((size_t)(-1) == retval) { return (retval); } break; case ITM_TBL_DIREC: ist->direc = ADDR(action); break; case ITM_TBL_MAP: switch (type) { case ITM_TBL_MAP_INDEX_FIXED_1_1: case ITM_TBL_MAP_INDEX_FIXED: retval = map_i_f(ADDR(action), inbuf, inbytesleft, outbuf, outbytesleft, 1); break; case ITM_TBL_MAP_HASH: retval = map_h_l(ADDR(action), inbuf, inbytesleft, outbuf, outbytesleft, 1); break; case ITM_TBL_MAP_DENSE_ENC: retval = map_d_e_l(ADDR(action), inbuf, inbytesleft, outbuf, outbytesleft, 1); break; case ITM_TBL_MAP_LOOKUP: retval = map_l_f(ADDR(action), inbuf, inbytesleft, outbuf, outbytesleft, 1); break; default: errno = ELIBBAD; TRACE_MESSAGE('e', ("_icv_iconv:error=%d\n", errno)); return ((size_t)(-1)); } if ((size_t)(-1) == retval) { return (retval); } break; default: /* never */ errno = ELIBBAD; TRACE_MESSAGE('e', ("_icv_iconv:error=%d\n", errno)); return ((size_t)(-1)); } break; } } return (retval); } /* * map-indexed-fixed */ static size_t map_i_f( itm_tbl_hdr_t *tbl_hdr, const unsigned char **inbuf, size_t *inbytesleft, unsigned char **outbuf, size_t *outbytesleft, long once) { itm_map_idx_fix_hdr_t *map_hdr; long i; unsigned char c; unsigned long j; const unsigned char *p; TRACE_MESSAGE('i', ("map_i_f\n")); map_hdr = (itm_map_idx_fix_hdr_t *)(tbl_hdr + 1); do { if (*inbytesleft < map_hdr->source_len) { errno = EINVAL; TRACE_MESSAGE('e', ("map_i_f:error=%d\n", errno)); return ((size_t)(-1)); } j = 0; for (i = 0; i < map_hdr->source_len; i++) { GET(c); j = ((j << 8) | c); } if (((j < map_hdr->start.itm_ptr) || (map_hdr->end.itm_ptr < j)) && (0 < map_hdr->default_error)) { errno = EILSEQ; (*inbuf) = (void*) ((*inbuf) - map_hdr->source_len); (*inbytesleft) += map_hdr->source_len; TRACE_MESSAGE('e', ("map_i_f:error=%d\n", errno)); return ((size_t)(-1)); } if (*outbytesleft < map_hdr->result_len) { errno = E2BIG; (*inbuf) = (void *)((*inbuf) - map_hdr->source_len); (*inbytesleft) += map_hdr->source_len; TRACE_MESSAGE('e', ("map_i_f:error=%d\n", errno)); return ((size_t)(-1)); } if ((j < map_hdr->start.itm_ptr) || (map_hdr->end.itm_ptr < j)) { if (0 == map_hdr->default_error) { p = (((unsigned char *)(map_hdr + 1)) + (map_hdr->result_len * (tbl_hdr->number))); for (i = 0; i < map_hdr->result_len; i++) { PUT(*(p + i)); } } else { p = ((*inbuf) - map_hdr->source_len); for (i = 0; i < map_hdr->source_len; i++) { PUT(*(p + i)); } } } else { char *map_error; map_error = (((char *)(map_hdr + 1)) + (map_hdr->result_len * (tbl_hdr->number)) + (j - map_hdr->start.itm_ptr)); if (0 == map_hdr->default_error) { map_error = (void *) (map_error + map_hdr->result_len); } if (((1 == map_hdr->default_error) || (0 < map_hdr->error_num)) && (0 != *(map_error))) { errno = EILSEQ; (*inbuf) = (void *) ((*inbuf) - map_hdr->source_len); (*inbytesleft) += map_hdr->source_len; TRACE_MESSAGE('e', ("map_i_f:error=%d\n", errno)); return ((size_t)(-1)); } p = (((unsigned char *)(map_hdr + 1)) + (map_hdr->result_len * (j - map_hdr->start.itm_ptr))); for (i = 0; i < map_hdr->result_len; i++) { PUT(*(p + i)); } } } while ((0 < *inbytesleft) && (0 == once)); return (size_t)(0); } /* * map-lookup-fixed */ static size_t map_l_f( itm_tbl_hdr_t *tbl_hdr, const unsigned char **inbuf, size_t *inbytesleft, unsigned char **outbuf, size_t *outbytesleft, long once) { itm_map_lookup_hdr_t *map_hdr; long i; unsigned char *map; const unsigned char *p; long high; long mid; long low; long result; itm_size_t pair_size; TRACE_MESSAGE('i', ("map_l_f\n")); map_hdr = (itm_map_lookup_hdr_t *)(tbl_hdr + 1); map = (unsigned char *)(map_hdr + 1); pair_size = map_hdr->source_len + 1 + map_hdr->result_len; do { if (*inbytesleft < map_hdr->source_len) { errno = EINVAL; TRACE_MESSAGE('e', ("map_l_f:error=%d\n", errno)); return ((size_t)(-1)); } for (low = 0, high = tbl_hdr->number; low < high; ) { mid = (low + high) / 2; p = map + (pair_size * mid); for (i = 0, result = 0; i < map_hdr->source_len; i++, p++) { if (*(unsigned char *)(*inbuf + i) < *p) { result = -1; break; } if (*p < *(unsigned char *)(*inbuf + i)) { result = 1; break; } } if (result < 0) { high = mid; } else if (0 < result) { low = mid + 1; } else { /* 0 == result */ break; } } if (0 != result) { if (map_hdr->default_error < 0) { p = *inbuf; } else if (0 == map_hdr->default_error) { p = map + (pair_size * tbl_hdr->number) + map_hdr->source_len + 1; } else if (0 < map_hdr->default_error) { errno = EILSEQ; TRACE_MESSAGE('e', ("map_l_f:error=%d\n", errno)); return ((size_t)(-1)); } } else { if (0 != (*p)) { errno = EILSEQ; TRACE_MESSAGE('e', ("map_l_f:error=%d\n", errno)); return ((size_t)(-1)); } p++; } if (*outbytesleft < map_hdr->result_len) { errno = E2BIG; TRACE_MESSAGE('e', ("map_l_f:error=%d\n", errno)); return ((size_t)(-1)); } DISCARD(map_hdr->source_len); for (i = 0; i < map_hdr->result_len; i++) { PUT(*(p + i)); } } while ((0 < *inbytesleft) && (0 == once)); return ((size_t)(0)); } /* * map-hash-lookup */ static size_t map_h_l( itm_tbl_hdr_t *tbl_hdr, const unsigned char **inbuf, size_t *inbytesleft, unsigned char **outbuf, size_t *outbytesleft, long once) { itm_map_hash_hdr_t *map_hdr; long i; unsigned char *map_error; unsigned char *map_hash; unsigned char *map_of; const unsigned char *p; const unsigned char *q; long high; long mid; long low; long result; itm_size_t pair_size; itm_size_t hash_value; itm_size_t source_len; itm_size_t result_len; TRACE_MESSAGE('i', ("map_hash\n")); map_hdr = (itm_map_hash_hdr_t *)(tbl_hdr + 1); map_error = (unsigned char *)(map_hdr + 1); map_hash = (map_error + map_hdr->hash_tbl_num); map_of = map_hash + map_hdr->hash_tbl_size; pair_size = map_hdr->source_len + 1 + map_hdr->result_len; source_len = map_hdr->source_len; result_len = map_hdr->result_len; do { if (*inbytesleft < source_len) { errno = EINVAL; TRACE_MESSAGE('e', ("map_h_l:error=%d\n", errno)); return ((size_t)(-1)); } result = 1; q = *inbuf; hash_value = hash((const char *)(q), source_len, map_hdr->hash_tbl_num); p = map_hash + (pair_size * hash_value); if (1 == *(map_error + hash_value)) { for (i = 0, result = 0; i < source_len; i++) { if (*(q + i) != *(p++)) { result = -2; break; } } TRACE_MESSAGE('G', ("(h=%d): find pair without conflict\n", hash_value)); } else if (0 == *(map_error + hash_value)) { TRACE_MESSAGE('G', ("(h=%d): No Pair\n", hash_value)); result = -3; } else /* if (0 < *(map_error + hash_value)) */ { for (i = 0, result = 0; i < source_len; i++) { if (*(q + i) != *(p++)) { result = 1; break; } } if (0 < result) { for (low = 0, high = map_hdr->hash_of_num; low < high; /* NOP */) { mid = (low + high) / 2; p = map_of + (pair_size * mid); for (i = 0, result = 0; i < source_len; i++, p++) { if (*(q + i) < *p) { result = -1; break; } if (*p < *(q + i)) { result = 1; break; } } if (result < 0) { high = mid; } else if (0 < result) { low = mid + 1; } else { /* 0 == result */ TRACE_MESSAGE('G', ("(h=%d): " "find data on out of " "hashtable with CONFLICT\n", hash_value)); break; } } } } if (0 != result) { if (map_hdr->default_error < 0) { p = q; } else if (0 == map_hdr->default_error) { p = map_of + map_hdr->hash_of_size; } else if (0 < map_hdr->default_error) { TRACE_MESSAGE('G', ("(h=%d): NO PAIR\n", hash_value)); errno = EILSEQ; TRACE_MESSAGE('e', ("map_h_l:error=%d\n", errno)); return ((size_t)(-1)); } } else { if (0 != (*p)) { errno = EILSEQ; TRACE_MESSAGE('G', (" : error pair\n")); TRACE_MESSAGE('e', ("map_l_f:error\n", errno)); return ((size_t)(-1)); } p++; } if (*outbytesleft < result_len) { errno = E2BIG; TRACE_MESSAGE('e', ("map_h_l:error=%d\n", errno)); return ((size_t)(-1)); } DISCARD(source_len); for (i = 0; i < result_len; i++) { PUT(*(p + i)); } } while ((0 < *inbytesleft) && (0 == once)); return ((size_t)(0)); } /* * map-dense_encoding-lookup */ static size_t map_d_e_l( itm_tbl_hdr_t *tbl_hdr, const unsigned char **inbuf, size_t *inbytesleft, unsigned char **outbuf, size_t *outbytesleft, long once) { itm_map_dense_enc_hdr_t *map_hdr; long i; itm_num_t j; const unsigned char *p; unsigned char *map_ptr; unsigned char *map_error; unsigned char *byte_seq_min; unsigned char *byte_seq_max; TRACE_MESSAGE('i', ("map_d_e_l\n")); map_hdr = (itm_map_dense_enc_hdr_t *)(tbl_hdr + 1); map_ptr = ((unsigned char *)(map_hdr + 1) + map_hdr->source_len + map_hdr->source_len); map_error = (map_ptr + (tbl_hdr->number * map_hdr->result_len)); if (0 == map_hdr->default_error) { map_error = (void *)(map_error + map_hdr->result_len); } byte_seq_min = (unsigned char *)(map_hdr + 1); byte_seq_max = byte_seq_min + map_hdr->source_len; do { if (*inbytesleft < map_hdr->source_len) { errno = EINVAL; TRACE_MESSAGE('e', ("map_d_e_l:error=%d\n", errno)); return ((size_t)(-1)); } j = hash_dense_encoding(*inbuf, map_hdr->source_len, byte_seq_min, byte_seq_max); if (((j < 0) || (tbl_hdr->number < j)) && (0 < map_hdr->default_error)) { errno = EILSEQ; TRACE_MESSAGE('e', ("map_d_e_l:error=%d\n", errno)); return ((size_t)(-1)); } if (*outbytesleft < map_hdr->result_len) { errno = E2BIG; TRACE_MESSAGE('e', ("map_d_e_l:error=%d\n", errno)); return ((size_t)(-1)); } if ((j < 0) || (tbl_hdr->number < j)) { if (0 == map_hdr->default_error) { p = (map_ptr + (tbl_hdr->number * map_hdr->result_len)); for (i = 0; i < map_hdr->result_len; i++) { PUT(*(p + i)); } } else { p = *inbuf; for (i = 0; i < map_hdr->source_len; i++) { PUT(*(p + i)); } } } else { if ((1 == map_hdr->default_error) || (0 < map_hdr->error_num)) { if (0 != *(map_error + j)) { errno = EILSEQ; TRACE_MESSAGE('e', ("map_d_e_l:error=%d\n", errno)); return ((size_t)(-1)); } } p = (map_ptr + (map_hdr->result_len * j)); for (i = 0; i < map_hdr->result_len; i++) { PUT(*(p + i)); } } DISCARD(map_hdr->source_len); } while ((0 < *inbytesleft) && (0 == once)); return ((size_t)(0)); } /* * Evaluate condition table * */ static size_t eval_cond_tbl(icv_state_t *ist, itm_place_t cond_place, const unsigned char **inbuf, size_t *inbytesleft, size_t outbytesleft, itm_direc_t *direc) { itm_tbl_hdr_t *cond_hdr; itm_cond_t *cond; long i; long j; long k; size_t retval; itm_tbl_hdr_t *rth; itm_range_hdr_t *rtsh; unsigned char *p; itm_tbl_hdr_t *eth; itm_escapeseq_hdr_t *eh; itm_data_t *d; const unsigned char *ip; size_t ileft; retval = 0; ip = *inbuf; ileft = *inbytesleft; cond_hdr = ADDR(cond_place); cond = (itm_cond_t *)(cond_hdr + 1); for (i = 0; i < cond_hdr->number; i++, cond++) { switch (cond->type) { case ITM_COND_BETWEEN: rth = ADDR(cond->operand.place); rtsh = (itm_range_hdr_t *)(rth + 1); if (ileft < rtsh->len) { errno = EINVAL; TRACE_MESSAGE('e', ("eval_cond_tbl:error=%d\n", errno)); retval = ((size_t)(-1)); goto eval_cond_return; } p = (unsigned char *)(rtsh + 1); retval = 0; for (j = 0; j < rth->number; j++, p = (void *)(p + (2 * rtsh->len))) { retval = 1; for (k = 0; k < rtsh->len; k++) { if ((*(ip + k) < *(p + k)) || (*(p + rtsh->len + k) < *(ip + k))) { retval = 0; break; } } if (1 == retval) { break; } } if (0 == retval) { TRACE_MESSAGE('b', ("out of between (%p) len= rtsh=%ld\n", *ip, rtsh->len)); goto eval_cond_return; } break; /* continue */ case ITM_COND_ESCAPESEQ: /* * if escape sequence occur, * change ist->default_action and return 2. * never return 1. */ retval = 0; eth = ADDR(cond->operand.place); eh = (itm_escapeseq_hdr_t *)(eth + 1); if (0 == ist->default_action.itm_ptr) { ist->default_action = direc->action; TRACE_MESSAGE('E', ("escape seq (default action=%6p, " "type=%ld) set\n", direc->action.itm_ptr, ((itm_tbl_hdr_t *) (ADDR(direc->action)))->type)); } retval = 0; if (*inbytesleft < eh->len_min) { break; } for (j = 0, d = (itm_data_t *)(eh + 1); j < eth->number; j++, d++) { if (*inbytesleft < d->size) { continue; } if (0 == memcmp(*inbuf, DADDR(d), d->size)) { TRACE_MESSAGE('E', ("escape seq: discard=%ld chars\n", d->size)); TRACE_MESSAGE('E', ("escape seq (default " "action=%6p, type=%ld) set\n", direc->action.itm_ptr, ((itm_tbl_hdr_t *) (ADDR(direc->action)))->type)); ist->default_action = direc->action; DISCARD(d->size); retval = 2; goto eval_cond_return; } } if (0 == retval) { goto eval_cond_return; } break; /* continue */ case ITM_COND_EXPR: retval = eval_expr(ist, cond->operand.place, *inbytesleft, ip, outbytesleft); if (0 == retval) { goto eval_cond_return; } else { retval = 1; } break; /* continue */ default: TRACE_MESSAGE('e', ("eval_cond_tbl:illegal cond=%d\n", cond->type)); retval = (size_t)-1; goto eval_cond_return; } } eval_cond_return: return (retval); } /* * Evaluate operation table * */ static size_t eval_op_tbl( icv_state_t *ist, itm_place_t op_tbl_place, const unsigned char **inbuf, size_t *inbytesleft, unsigned char **outbuf, size_t *outbytesleft) { itm_tbl_hdr_t *op_hdr; itm_op_t *operation; itm_place2_t op_place; size_t retval; long i; retval = 0; #if defined(OP_DEPTH_MAX) if (OP_DEPTH_MAX <= ist->op_depth) { errno = ELIBBAD; TRACE_MESSAGE('e', ("eval_op_tbl:error=%d\n", errno)); return (RETVALERR); } ist->op_depth += 1; #endif /* OP_DEPTH_MAX */ op_hdr = ADDR(op_tbl_place); operation = (itm_op_t *)(op_hdr + 1); op_place = op_tbl_place.itm_ptr + (sizeof (itm_tbl_hdr_t)); for (i = 0; i < op_hdr->number; i++, operation++, op_place += (sizeof (itm_op_t))) { TRACE_MESSAGE('O', ("eval_op_tbl: %ld %p\n", i, op_place)); retval = eval_op(ist, op_place, inbuf, inbytesleft, outbuf, outbytesleft); if (((long)(retval)) < 0) { #if defined(OP_DEPTH_MAX) ist->op_depth -= 1; #endif /* OP_DEPTH_MAX */ switch (retval) { case RETVALERR: return (retval); case RETVALRET: if (0 == op_hdr->name.itm_ptr) { return (RETVALRET); } else { return (0); } } } } #if defined(OP_DEPTH_MAX) ist->op_depth -= 1; #endif /* OP_DEPTH_MAX */ return (retval); } /* * Evaluate single operation * */ static size_t eval_op( icv_state_t *ist, itm_place2_t op_place, const unsigned char **inbuf, size_t *inbytesleft, unsigned char **outbuf, size_t *outbytesleft) { size_t retval; itm_num_t num; itm_op_t *operation; itm_expr_t *expr; itm_num_t c; itm_num_t i; itm_size_t z; unsigned char *p; itm_expr_t *expr0; itm_tbl_hdr_t *h; itm_type_t t; #define EVAL_EXPR(n) \ (expr0 = ADDR(operation->data.operand[(n)]), \ (itm_num_t)((expr0->type == ITM_EXPR_INT) ? \ expr0->data.itm_exnum : \ ((expr0->type == ITM_EXPR_REG) ? \ REG(expr0->data.itm_exnum) : \ ((expr0->type == ITM_EXPR_IN_VECTOR_D) ? \ ((expr0->data.itm_exnum < 0) ? \ (((-1) == expr0->data.itm_exnum) ? *inbytesleft : 0) : \ ((expr0->data.itm_exnum < *inbytesleft) ? \ (*(uchar_t *)(*inbuf + expr0->data.itm_exnum)) : 0)): \ eval_expr(ist, operation->data.operand[(n)], \ *inbytesleft, *inbuf, *outbytesleft))))) retval = 0; operation = (itm_op_t *)ADDR2(op_place); switch (operation->type) { case ITM_OP_EXPR: num = eval_expr(ist, operation->data.operand[0], *inbytesleft, *inbuf, *outbytesleft); TRACE_MESSAGE('o', ("ITM_OP_EXPR: %ld\n", retval)); break; case ITM_OP_ERROR: num = eval_expr(ist, operation->data.operand[0], *inbytesleft, *inbuf, *outbytesleft); errno = (int)num; TRACE_MESSAGE('o', ("ITM_OP_ERROR: %ld\n", num)); retval = (size_t)(-1); break; case ITM_OP_ERROR_D: errno = (int)operation->data.itm_opnum; TRACE_MESSAGE('o', ("ITM_OP_ERROR_D: %d\n", errno)); retval = (size_t)(-1); break; case ITM_OP_OUT: expr = ADDR(operation->data.operand[0]); if ((*outbytesleft) == 0) { errno = E2BIG; TRACE_MESSAGE('e', ("eval_op:error=%d\n", errno)); return ((size_t)(-1)); } c = eval_expr(ist, operation->data.operand[0], *inbytesleft, *inbuf, *outbytesleft); PUT((uchar_t)c); retval = *inbytesleft; TRACE_MESSAGE('o', ("ITM_OP_OUT: %ld %ld\n", c, *inbytesleft)); break; case ITM_OP_OUT_D: expr = ADDR(operation->data.operand[0]); if ((*outbytesleft) == 0) { errno = E2BIG; TRACE_MESSAGE('e', ("eval_op:error=%d\n", errno)); return ((size_t)(-1)); } PUT(0xff & (expr->data.itm_exnum)); break; case ITM_OP_OUT_S: expr = ADDR(operation->data.operand[0]); if ((*outbytesleft) == 0) { errno = E2BIG; TRACE_MESSAGE('e', ("eval_op:error=%d\n", errno)); return ((size_t)(-1)); } z = expr->data.value.size; if (*outbytesleft < z) { errno = E2BIG; TRACE_MESSAGE('e', ("eval_op:error=%d\n", errno)); return ((size_t)(-1)); } p = DADDR(&(expr->data.value)); for (; 0 < z; --z, p++) { PUT(*p); } break; case ITM_OP_OUT_R: expr = ADDR(operation->data.operand[0]); if ((*outbytesleft) == 0) { errno = E2BIG; TRACE_MESSAGE('e', ("eval_op:error=%d\n", errno)); return ((size_t)(-1)); } c = REG(expr->data.itm_exnum); PUT((uchar_t)c); break; case ITM_OP_OUT_INVD: expr = ADDR(operation->data.operand[0]); if ((*outbytesleft) == 0) { errno = E2BIG; TRACE_MESSAGE('e', ("eval_op:error=%d\n", errno)); return ((size_t)(-1)); } z = (((0 <= expr->data.itm_exnum) && (expr->data.itm_exnum < *inbytesleft)) ? (*((unsigned char *)(*inbuf + expr->data.itm_exnum))) : (((-1) == expr->data.itm_exnum) ? *inbytesleft : 0)); PUT((uchar_t)z); break; case ITM_OP_DISCARD: #if defined(EVAL_EXPR) num = EVAL_EXPR(0); #else /* !defined(EVAL_EXPR) */ num = eval_expr(ist, operation->data.operand[0], *inbytesleft, *inbuf, *outbytesleft); #endif /* defined(EVAL_EXPR) */ TRACE_MESSAGE('o', ("ITM_OP_DISCARD: %ld\n", num)); #if defined(DISCARD) DISCARD((num <= *inbytesleft) ? ((ulong_t)num) : *inbytesleft); #else /* defined(DISCARD) */ for (num = ((num <= *inbytesleft) ? num : *inbytesleft); 0 < num; --num) { GET(c); } #endif /* defined(DISCARD) */ break; case ITM_OP_DISCARD_D: num = operation->data.itm_opnum; TRACE_MESSAGE('o', ("ITM_OP_DISCARD_D: %ld\n", num)); #if defined(DISCARD) DISCARD((num <= *inbytesleft) ? num : *inbytesleft); #else /* defined(DISCARD) */ for (num = ((num <= *inbytesleft) ? num : *inbytesleft); 0 < num; --num) { GET(c); } #endif /* defined(DISCARD) */ break; case ITM_OP_IF: c = eval_expr(ist, operation->data.operand[0], *inbytesleft, *inbuf, *outbytesleft); TRACE_MESSAGE('o', ("ITM_OP_IF: %ld\n", c)); if (c) { retval = eval_op_tbl(ist, operation->data.operand[1], inbuf, inbytesleft, outbuf, outbytesleft); } break; case ITM_OP_IF_ELSE: c = eval_expr(ist, operation->data.operand[0], *inbytesleft, *inbuf, *outbytesleft); TRACE_MESSAGE('o', ("ITM_OP_IF_ELSE: %ld\n", c)); if (c) { retval = eval_op_tbl(ist, operation->data.operand[1], inbuf, inbytesleft, outbuf, outbytesleft); } else { retval = eval_op_tbl(ist, operation->data.operand[2], inbuf, inbytesleft, outbuf, outbytesleft); } break; case ITM_OP_DIRECTION: TRACE_MESSAGE('o', ("ITM_OP_DIRECTION: %p\n", operation->data.operand[0].itm_ptr)); ist->direc = ADDR(operation->data.operand[0]); return ((size_t)(-2)); case ITM_OP_MAP: TRACE_MESSAGE('o', ("ITM_OP_MAP: %p\n", operation->data.operand[0].itm_ptr)); i = 0; if (0 != operation->data.operand[1].itm_ptr) { #if defined(EVAL_EXPR) i = EVAL_EXPR(1); #else /* !defined(EVAL_EXPR) */ i = eval_expr(ist, operation->data.operand[1], *inbytesleft, *inbuf, *outbytesleft); #endif /* defined(EVAL_EXPR) */ (*inbytesleft) -= i; (*inbuf) += i; } /* * Based on what is the maptype, we call the corresponding * mapping function. */ h = ADDR(operation->data.operand[0]); t = h->type; switch (t) { case ITM_TBL_MAP_INDEX_FIXED: case ITM_TBL_MAP_INDEX_FIXED_1_1: retval = map_i_f(h, inbuf, inbytesleft, outbuf, outbytesleft, 1); break; case ITM_TBL_MAP_HASH: retval = map_h_l(h, inbuf, inbytesleft, outbuf, outbytesleft, 1); break; case ITM_TBL_MAP_DENSE_ENC: retval = map_d_e_l(h, inbuf, inbytesleft, outbuf, outbytesleft, 1); break; case ITM_TBL_MAP_LOOKUP: retval = map_l_f(h, inbuf, inbytesleft, outbuf, outbytesleft, 1); break; default: /* * This should not be possible, but in case we * have an incorrect maptype, don't fall back to * map_i_f(). Instead, because it is an error, return * an error. See CR 6622765. */ errno = EBADF; TRACE_MESSAGE('e', ("eval_op:error=%d\n", errno)); retval = (size_t)-1; break; } if ((size_t)(-1) == retval) { (*outbytesleft) += i; (*outbuf) -= i; } break; case ITM_OP_OPERATION: TRACE_MESSAGE('o', ("ITM_OP_OPERATION: %p\n", operation->data.operand[0].itm_ptr)); retval = eval_op_tbl(ist, operation->data.operand[0], inbuf, inbytesleft, outbuf, outbytesleft); break; case ITM_OP_INIT: TRACE_MESSAGE('o', ("ITM_OP_INIT: %p\n", ist->itm_hdr->op_init_tbl)); if (0 != ist->itm_hdr->op_init_tbl.itm_ptr) { retval = eval_op_tbl(ist, ist->itm_hdr->op_init_tbl, inbuf, inbytesleft, outbuf, outbytesleft); } else { op_init_default(ist); retval = (size_t)-2; } break; case ITM_OP_RESET: TRACE_MESSAGE('o', ("ITM_OP_RESET: %p\n", ist->itm_hdr->op_reset_tbl)); if (0 != ist->itm_hdr->op_reset_tbl.itm_ptr) { retval = eval_op_tbl(ist, ist->itm_hdr->op_reset_tbl, inbuf, inbytesleft, outbuf, outbytesleft); } else { op_reset_default(ist); retval = (size_t)-2; } break; case ITM_OP_BREAK: TRACE_MESSAGE('o', ("ITM_OP_BREAK\n")); return (RETVALBRK); case ITM_OP_RETURN: TRACE_MESSAGE('o', ("ITM_OP_RETURN\n")); return (RETVALRET); case ITM_OP_PRINTCHR: c = eval_expr(ist, operation->data.operand[0], *inbytesleft, *inbuf, *outbytesleft); (void) fputc((uchar_t)c, stderr); TRACE_MESSAGE('o', ("ITM_OP_PRINTCHR: %ld %ld\n", c, *inbytesleft)); break; case ITM_OP_PRINTHD: c = eval_expr(ist, operation->data.operand[0], *inbytesleft, *inbuf, *outbytesleft); (void) fprintf(stderr, "%lx", c); TRACE_MESSAGE('o', ("ITM_OP_PRINTHD: %ld %ld\n", c, *inbytesleft)); break; case ITM_OP_PRINTINT: c = eval_expr(ist, operation->data.operand[0], *inbytesleft, *inbuf, *outbytesleft); (void) fprintf(stderr, "%ld", c); TRACE_MESSAGE('o', ("ITM_OP_PRINTINT: %ld %ld\n", c, *inbytesleft)); break; default: /* never */ errno = ELIBBAD; TRACE_MESSAGE('e', ("eval_op:error=%d\n", errno)); return (size_t)(-1); } return (retval); #undef EVAL_EXPR } /* * Evaluate expression */ static itm_num_t eval_expr( icv_state_t *ist, itm_place_t expr_place, size_t inbytesleft, const unsigned char *inbuf, size_t outbytesleft) { itm_expr_t *expr; itm_expr_t *expr_op; itm_num_t num; unsigned char *p; long i; itm_expr_t *expr0; itm_num_t num00; itm_num_t num01; #define EVAL_EXPR_E(n) (eval_expr(ist, expr->data.operand[(n)], \ inbytesleft, inbuf, outbytesleft)) #define EVAL_EXPR_D(n) ((itm_num_t)(expr->data.operand[(n)].itm_ptr)) #define EVAL_EXPR_R(n) (REG((itm_num_t)(expr->data.operand[(n)].itm_ptr))) #define EVAL_EXPR_INVD(n) \ ((num0 ## n) = ((itm_num_t)(expr->data.operand[(n)].itm_ptr)), \ ((num0 ## n) < 0) ? \ (((-1) == (num0 ## n)) ? inbytesleft : 0) : \ (((num0 ## n) < inbytesleft) ? \ (*(unsigned char *)(inbuf + (num0 ## n))) : 0)) #define EVAL_EXPR(n) \ (expr0 = ADDR(expr->data.operand[(n)]), \ (itm_num_t)((expr0->type == ITM_EXPR_INT) ? \ expr0->data.itm_exnum : \ ((expr0->type == ITM_EXPR_REG) ? \ REG(expr0->data.itm_exnum) : \ ((expr0->type == ITM_EXPR_IN_VECTOR_D) ? \ ((expr0->data.itm_exnum < 0) ? \ (((-1) == expr0->data.itm_exnum) ? inbytesleft : 0) : \ ((expr0->data.itm_exnum < inbytesleft) ? \ (*(uchar_t *)(inbuf + expr0->data.itm_exnum)) : 0)) : \ eval_expr(ist, expr->data.operand[(n)], \ inbytesleft, inbuf, outbytesleft))))) #define EVAL_OP_BIN_PROTO(op, name, name0, name1) \ case ITM_EXPR_##name##_##name0##_##name1: \ return (EVAL_EXPR_##name0(0) op EVAL_EXPR_##name1(1)); #define EVAL_OP_BIN1(op, name) \ EVAL_OP_BIN_PROTO(op, name, E, E) \ EVAL_OP_BIN_PROTO(op, name, E, D) \ EVAL_OP_BIN_PROTO(op, name, E, R) \ EVAL_OP_BIN_PROTO(op, name, E, INVD) #define EVAL_OP_BIN2(op, name) \ EVAL_OP_BIN_PROTO(op, name, D, E) \ EVAL_OP_BIN_PROTO(op, name, D, D) \ EVAL_OP_BIN_PROTO(op, name, D, R) \ EVAL_OP_BIN_PROTO(op, name, D, INVD) #define EVAL_OP_BIN3(op, name) \ EVAL_OP_BIN_PROTO(op, name, R, E) \ EVAL_OP_BIN_PROTO(op, name, R, D) \ EVAL_OP_BIN_PROTO(op, name, R, R) \ EVAL_OP_BIN_PROTO(op, name, R, INVD) #define EVAL_OP_BIN4(op, name) \ EVAL_OP_BIN_PROTO(op, name, INVD, E) \ EVAL_OP_BIN_PROTO(op, name, INVD, D) \ EVAL_OP_BIN_PROTO(op, name, INVD, R) \ EVAL_OP_BIN_PROTO(op, name, INVD, INVD) #define EVAL_OP_BIN_PROTECT_PROTO(op, name, name0, name1) \ case ITM_EXPR_##name##_##name0##_##name1: \ num = EVAL_EXPR_##name1(1); \ if (0 != num) { \ return (EVAL_EXPR_##name0(0) op num); \ } else { \ return (0); \ } #define EVAL_OP_BIN_PROTECT1(op, name) \ EVAL_OP_BIN_PROTECT_PROTO(op, name, E, E) \ EVAL_OP_BIN_PROTECT_PROTO(op, name, E, D) \ EVAL_OP_BIN_PROTECT_PROTO(op, name, E, R) \ EVAL_OP_BIN_PROTECT_PROTO(op, name, E, INVD) #define EVAL_OP_BIN_PROTECT2(op, name) \ EVAL_OP_BIN_PROTECT_PROTO(op, name, D, E) \ EVAL_OP_BIN_PROTECT_PROTO(op, name, D, D) \ EVAL_OP_BIN_PROTECT_PROTO(op, name, D, R) \ EVAL_OP_BIN_PROTECT_PROTO(op, name, D, INVD) #define EVAL_OP_BIN_PROTECT3(op, name) \ EVAL_OP_BIN_PROTECT_PROTO(op, name, R, E) \ EVAL_OP_BIN_PROTECT_PROTO(op, name, R, D) \ EVAL_OP_BIN_PROTECT_PROTO(op, name, R, R) \ EVAL_OP_BIN_PROTECT_PROTO(op, name, R, INVD) #define EVAL_OP_BIN_PROTECT4(op, name) \ EVAL_OP_BIN_PROTECT_PROTO(op, name, INVD, E) \ EVAL_OP_BIN_PROTECT_PROTO(op, name, INVD, D) \ EVAL_OP_BIN_PROTECT_PROTO(op, name, INVD, R) \ EVAL_OP_BIN_PROTECT_PROTO(op, name, INVD, INVD) expr = ADDR(expr_place); switch (expr->type) { case ITM_EXPR_NONE: /* not used */ return (0); case ITM_EXPR_NOP: /* not used */ return (0); case ITM_EXPR_NAME: /* not used */ return (0); case ITM_EXPR_INT: /* integer */ return (expr->data.itm_exnum); case ITM_EXPR_SEQ: /* byte sequence */ if ((sizeof (itm_place_t)) < expr->data.value.size) { p = (unsigned char *)ADDR(expr->data.value.place); } else { p = (unsigned char *)&(expr->data.value.place); } for (i = 0, num = 0; i < expr->data.value.size; i++, p++) { num = ((num << 8) | *p); } return (num); case ITM_EXPR_REG: /* register */ return (REG(expr->data.itm_exnum)); case ITM_EXPR_IN_VECTOR: /* in[expr] */ num = EVAL_EXPR(0); if ((0 <= num) && (num < inbytesleft)) { return (*((unsigned char *)(inbuf + num))); } else if ((-1) == num) { return (inbytesleft); } else { return (0); } case ITM_EXPR_IN_VECTOR_D: /* in[DECIMAL] */ num = expr->data.itm_exnum; if ((0 <= num) && (num < inbytesleft)) { return (*((unsigned char *)(inbuf + num))); } else if ((-1) == num) { return (inbytesleft); } else { return (0); } case ITM_EXPR_OUT: /* out */ return (outbytesleft); case ITM_EXPR_TRUE: /* true */ return (1); case ITM_EXPR_FALSE: /* false */ return (0); case ITM_EXPR_UMINUS: /* unary minus */ return ((-1) * EVAL_EXPR(0)); #define PLUS_FOR_CSTYLE_CLEAN + #define MINUS_FOR_CSTYLE_CLEAN - #define MUL_FOR_CSTYLE_CLEAN * #define DIV_FOR_CSTYLE_CLEAN / #define MOD_FOR_CSTYLE_CLEAN % #define SHIFT_L_FOR_CSTYLE_CLEAN << #define SHIFT_R_FOR_CSTYLE_CLEAN >> #define OR_FOR_CSTYLE_CLEAN | #define XOR_FOR_CSTYLE_CLEAN ^ #define AND_FOR_CSTYLE_CLEAN & #define EQ_FOR_CSTYLE_CLEAN == #define NE_FOR_CSTYLE_CLEAN != #define GT_FOR_CSTYLE_CLEAN > #define GE_FOR_CSTYLE_CLEAN >= #define LT_FOR_CSTYLE_CLEAN < #define LE_FOR_CSTYLE_CLEAN <= EVAL_OP_BIN1(PLUS_FOR_CSTYLE_CLEAN, PLUS) /* A + B */ EVAL_OP_BIN2(PLUS_FOR_CSTYLE_CLEAN, PLUS) /* A + B */ EVAL_OP_BIN3(PLUS_FOR_CSTYLE_CLEAN, PLUS) /* A + B */ EVAL_OP_BIN4(PLUS_FOR_CSTYLE_CLEAN, PLUS) /* A + B */ EVAL_OP_BIN1(MINUS_FOR_CSTYLE_CLEAN, MINUS) /* A - B */ EVAL_OP_BIN2(MINUS_FOR_CSTYLE_CLEAN, MINUS) /* A - B */ EVAL_OP_BIN3(MINUS_FOR_CSTYLE_CLEAN, MINUS) /* A - B */ EVAL_OP_BIN4(MINUS_FOR_CSTYLE_CLEAN, MINUS) /* A - B */ EVAL_OP_BIN1(MUL_FOR_CSTYLE_CLEAN, MUL) /* A * B */ EVAL_OP_BIN2(MUL_FOR_CSTYLE_CLEAN, MUL) /* A * B */ EVAL_OP_BIN3(MUL_FOR_CSTYLE_CLEAN, MUL) /* A * B */ EVAL_OP_BIN4(MUL_FOR_CSTYLE_CLEAN, MUL) /* A * B */ EVAL_OP_BIN_PROTECT1(DIV_FOR_CSTYLE_CLEAN, DIV) /* A / B */ EVAL_OP_BIN_PROTECT2(DIV_FOR_CSTYLE_CLEAN, DIV) /* A / B */ EVAL_OP_BIN_PROTECT3(DIV_FOR_CSTYLE_CLEAN, DIV) /* A / B */ EVAL_OP_BIN_PROTECT4(DIV_FOR_CSTYLE_CLEAN, DIV) /* A / B */ EVAL_OP_BIN_PROTECT1(MOD_FOR_CSTYLE_CLEAN, MOD) /* A % B */ EVAL_OP_BIN_PROTECT2(MOD_FOR_CSTYLE_CLEAN, MOD) /* A % B */ EVAL_OP_BIN_PROTECT3(MOD_FOR_CSTYLE_CLEAN, MOD) /* A % B */ EVAL_OP_BIN_PROTECT4(MOD_FOR_CSTYLE_CLEAN, MOD) /* A % B */ EVAL_OP_BIN1(SHIFT_L_FOR_CSTYLE_CLEAN, SHIFT_L) /* A << B */ EVAL_OP_BIN2(SHIFT_L_FOR_CSTYLE_CLEAN, SHIFT_L) /* A << B */ EVAL_OP_BIN3(SHIFT_L_FOR_CSTYLE_CLEAN, SHIFT_L) /* A << B */ EVAL_OP_BIN4(SHIFT_L_FOR_CSTYLE_CLEAN, SHIFT_L) /* A << B */ EVAL_OP_BIN1(SHIFT_R_FOR_CSTYLE_CLEAN, SHIFT_R) /* A >> B */ EVAL_OP_BIN2(SHIFT_R_FOR_CSTYLE_CLEAN, SHIFT_R) /* A >> B */ EVAL_OP_BIN3(SHIFT_R_FOR_CSTYLE_CLEAN, SHIFT_R) /* A >> B */ EVAL_OP_BIN4(SHIFT_R_FOR_CSTYLE_CLEAN, SHIFT_R) /* A >> B */ EVAL_OP_BIN1(OR_FOR_CSTYLE_CLEAN, OR) /* A | B */ EVAL_OP_BIN2(OR_FOR_CSTYLE_CLEAN, OR) /* A | B */ EVAL_OP_BIN3(OR_FOR_CSTYLE_CLEAN, OR) /* A | B */ EVAL_OP_BIN4(OR_FOR_CSTYLE_CLEAN, OR) /* A | B */ EVAL_OP_BIN1(XOR_FOR_CSTYLE_CLEAN, XOR) /* A ^ B */ EVAL_OP_BIN2(XOR_FOR_CSTYLE_CLEAN, XOR) /* A ^ B */ EVAL_OP_BIN3(XOR_FOR_CSTYLE_CLEAN, XOR) /* A ^ B */ EVAL_OP_BIN4(XOR_FOR_CSTYLE_CLEAN, XOR) /* A ^ B */ EVAL_OP_BIN1(AND_FOR_CSTYLE_CLEAN, AND) /* A & B */ EVAL_OP_BIN2(AND_FOR_CSTYLE_CLEAN, AND) /* A & B */ EVAL_OP_BIN3(AND_FOR_CSTYLE_CLEAN, AND) /* A & B */ EVAL_OP_BIN4(AND_FOR_CSTYLE_CLEAN, AND) /* A & B */ EVAL_OP_BIN1(EQ_FOR_CSTYLE_CLEAN, EQ) /* A == B */ EVAL_OP_BIN2(EQ_FOR_CSTYLE_CLEAN, EQ) /* A == B */ EVAL_OP_BIN3(EQ_FOR_CSTYLE_CLEAN, EQ) /* A == B */ EVAL_OP_BIN4(EQ_FOR_CSTYLE_CLEAN, EQ) /* A == B */ EVAL_OP_BIN1(NE_FOR_CSTYLE_CLEAN, NE) /* A != B */ EVAL_OP_BIN2(NE_FOR_CSTYLE_CLEAN, NE) /* A != B */ EVAL_OP_BIN3(NE_FOR_CSTYLE_CLEAN, NE) /* A != B */ EVAL_OP_BIN4(NE_FOR_CSTYLE_CLEAN, NE) /* A != B */ EVAL_OP_BIN1(GT_FOR_CSTYLE_CLEAN, GT) /* A > B */ EVAL_OP_BIN2(GT_FOR_CSTYLE_CLEAN, GT) /* A > B */ EVAL_OP_BIN3(GT_FOR_CSTYLE_CLEAN, GT) /* A > B */ EVAL_OP_BIN4(GT_FOR_CSTYLE_CLEAN, GT) /* A > B */ EVAL_OP_BIN1(GE_FOR_CSTYLE_CLEAN, GE) /* A >= B */ EVAL_OP_BIN2(GE_FOR_CSTYLE_CLEAN, GE) /* A >= B */ EVAL_OP_BIN3(GE_FOR_CSTYLE_CLEAN, GE) /* A >= B */ EVAL_OP_BIN4(GE_FOR_CSTYLE_CLEAN, GE) /* A >= B */ EVAL_OP_BIN1(LT_FOR_CSTYLE_CLEAN, LT) /* A < B */ EVAL_OP_BIN2(LT_FOR_CSTYLE_CLEAN, LT) /* A < B */ EVAL_OP_BIN3(LT_FOR_CSTYLE_CLEAN, LT) /* A < B */ EVAL_OP_BIN4(LT_FOR_CSTYLE_CLEAN, LT) /* A < B */ EVAL_OP_BIN1(LE_FOR_CSTYLE_CLEAN, LE) /* A <= B */ EVAL_OP_BIN2(LE_FOR_CSTYLE_CLEAN, LE) /* A <= B */ EVAL_OP_BIN3(LE_FOR_CSTYLE_CLEAN, LE) /* A <= B */ EVAL_OP_BIN4(LE_FOR_CSTYLE_CLEAN, LE) /* A <= B */ case ITM_EXPR_NOT: /* !A */ return (!(EVAL_EXPR(0))); case ITM_EXPR_NEG: /* ~A */ return (~(EVAL_EXPR(0))); case ITM_EXPR_LOR: /* A || B */ if (0 != (num = EVAL_EXPR(0))) return (num); if (0 != (num = EVAL_EXPR(1))) return (num); return (0); case ITM_EXPR_LAND: /* A && B */ if (0 == EVAL_EXPR(0)) return (0); if (0 == (num = EVAL_EXPR(1))) return (0); return (num); case ITM_EXPR_ASSIGN: /* A = B */ num = EVAL_EXPR(1); if (expr->data.operand[0].itm_ptr < ist->itm_hdr->reg_num) { return (*(ist->regs + expr->data.operand[0].itm_ptr) = num); } else { return (0); } case ITM_EXPR_IN_EQ: /* in == A */ expr_op = ADDR(expr->data.operand[0]); switch (expr_op->type) { case ITM_EXPR_SEQ: if (inbytesleft < expr_op->data.value.size) { return (0); } p = DADDR(&(expr_op->data.value)); for (i = 0; i < expr_op->data.value.size; i++, p++) { if (*p != *(inbuf + i)) { return (0); } } return (1); default: num = EVAL_EXPR(0); return (num == *((unsigned char *)inbuf)); } default: break; } return (0); #undef EVAL_EXPR_E #undef EVAL_EXPR_D #undef EVAL_EXPR_R #undef EVAL_EXPR_INVD #undef EVAL_EXPR } /* * maintain ITM reference information */ static void itm_ref_free(int fd, void *ptr0, void *ptr1, void *ptr2, size_t len) { int r; r = errno; if (0 <= fd) { (void) close(fd); } free(ptr0); free(ptr1); if (0 < len) { (void) munmap(ptr2, len); } errno = r; } static itm_ref_t * itm_ref_inc(const char *itm) { itm_ref_t *ref; itm_hdr_t *hdr; struct stat st; int fd; fd = open(itm, O_RDONLY, 0); if (fd == -1) { itm_ref_free(-1, NULL, NULL, NULL, 0); return (NULL); } if (fstat(fd, &st) == -1) { itm_ref_free(fd, NULL, NULL, NULL, 0); return (NULL); } hdr = (void *) mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0); if (MAP_FAILED == hdr) { itm_ref_free(fd, NULL, NULL, NULL, 0); return (NULL); } (void) close(fd); ref = malloc(sizeof (itm_ref_t)); if (NULL == ref) { itm_ref_free(-1, NULL, NULL, hdr, st.st_size); return (NULL); } ref->name = malloc(strlen(itm) + 1); if (NULL == ref->name) { itm_ref_free(-1, ref, NULL, hdr, st.st_size); return (NULL); } (void) strcpy(ref->name, itm); ref->hdr = hdr; ref->len = st.st_size; if ((hdr->ident[0] != ITM_IDENT_0) || (hdr->ident[1] != ITM_IDENT_1) || (hdr->ident[2] != ITM_IDENT_2) || (hdr->ident[3] != ITM_IDENT_3) || (hdr->spec[0] != ITM_SPEC_0) || (hdr->spec[1] != ITM_SPEC_1) || (hdr->spec[2] != ITM_SPEC_2) || #if defined(_LITTLE_ENDIAN) #if defined(_LP64) ((hdr->spec[3] != ITM_SPEC_3_32_LITTLE_ENDIAN) && (hdr->spec[3] != ITM_SPEC_3_64_LITTLE_ENDIAN)) || #else (hdr->spec[3] != ITM_SPEC_3_32_LITTLE_ENDIAN) || #endif #else #if defined(_LP64) ((hdr->spec[3] != ITM_SPEC_3_32_BIG_ENDIAN) && (hdr->spec[3] != ITM_SPEC_3_64_BIG_ENDIAN)) || #else (hdr->spec[3] != ITM_SPEC_3_32_BIG_ENDIAN) || #endif #endif (hdr->version[0] != ITM_VER_0) || (hdr->version[1] != ITM_VER_1) || (hdr->version[2] != ITM_VER_2) || (hdr->version[3] != ITM_VER_3) || (((size_t)(hdr->itm_size.itm_ptr)) != st.st_size)) { itm_ref_free(-1, ref, ref->name, ref->hdr, ref->len); errno = ELIBBAD; TRACE_MESSAGE('e', ("itm_ref_inc:error=%d\n", errno)); return (NULL); } return (ref); } static void itm_ref_dec(itm_ref_t *ref) { (void) munmap((char *)(ref->hdr), ref->len); free(ref->name); free(ref); } static void op_init_default(icv_state_t *ist) { ist->direc = ADDR(ist->itm_hdr->direc_init_tbl); regs_init(ist); } static void op_reset_default(icv_state_t *ist) { ist->direc = ADDR(ist->itm_hdr->direc_init_tbl); regs_init(ist); } static void regs_init(icv_state_t *ist) { if (0 < ist->itm_hdr->reg_num) { (void) memset(ist->regs, 0, (sizeof (itm_num_t)) * ist->itm_hdr->reg_num); } } #if defined(DEBUG) static void trace_init() { char *env_val; char *p; env_val = getenv("ITM_INT_TRACE"); if (NULL == env_val) return; for (p = env_val; *p; p++) { trace_option[(*p) & 0x007f] = 1; } } static void trace_message(char *format, ...) { va_list ap; va_start(ap, format); (void) vfprintf(stderr, format, ap); va_end(ap); } #endif /* DEBUG */ /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright (c) 1999 by Sun Microsystems, Inc. * All rights reserved. */ #ifndef _ICONV_TM_HASH_H #define _ICONV_TM_HASH_H #ifdef __cplusplus extern "C" { #endif static itm_size_t hash(const char *, itm_size_t, itm_size_t); static itm_num_t hash_dense_encoding(const unsigned char *, itm_size_t, const unsigned char *, const unsigned char *); static itm_size_t hash(const char *ptr, itm_size_t size, itm_size_t hash_size) { itm_size_t value; value = *(ptr++); --size; for (; 0 < size; --size) { value *= 27239; value += *(ptr++); } return (value % hash_size); } static itm_num_t hash_dense_encoding( const unsigned char *byte_seq, itm_size_t length, const unsigned char *byte_seq_min, const unsigned char *byte_seq_max) { long i; itm_num_t num; num = (*byte_seq - *byte_seq_min); byte_seq_min++; byte_seq_max++; for (i = 1, byte_seq++; i < length; i++, byte_seq++, byte_seq_min++, byte_seq_max++) { if ((*byte_seq < *byte_seq_min) || (*byte_seq_max < *byte_seq)) { return (-1); } num *= (*byte_seq_max - *byte_seq_min + 1); num += (*byte_seq - *byte_seq_min); } return (num); } #ifdef __cplusplus } #endif #endif /* !_ICONV_TM_HASH_H */ /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright (c) 1999 by Sun Microsystems, Inc. * All rights reserved. */ #ifndef _ICONV_TM_H #define _ICONV_TM_H #ifdef __cplusplus extern "C" { #endif #include #include #include #if !defined(DEBUG) #define NDEBUG /* for assert() */ #endif /* DEBUG */ #if defined(DEBUG) #define ENABLE_TRACE #endif /* DEBUG */ #define MAXSEQUENCE (128) #define MAXREGID (256) #define MAXNAMELENGTH (255) /* * ITM Identifier */ #define ITM_IDENT_LEN (4) #define ITM_IDENT_0 (0x49) #define ITM_IDENT_1 (0x54) #define ITM_IDENT_2 (0x4d) #define ITM_IDENT_3 (0x00) /* * ITM Platform Specification */ #define ITM_SPEC_LEN (4) #define ITM_SPEC_0 (0) #define ITM_SPEC_1 (0) #define ITM_SPEC_2 (0) #define ITM_SPEC_3_UNSPECIFIED (0) #define ITM_SPEC_3_32_BIG_ENDIAN (1) #define ITM_SPEC_3_32_LITTLE_ENDIAN (2) #define ITM_SPEC_3_64_BIG_ENDIAN (3) #define ITM_SPEC_3_64_LITTLE_ENDIAN (4) /* * ITM Version */ #define ITM_VER_LEN (4) #define ITM_VER_0 (0) #define ITM_VER_1 (0) #define ITM_VER_2 (0) #define ITM_VER_3 (1) /* * PADDING */ #define ITM_PAD_LEN (4) /* * Generic offset&pointer/data/string */ typedef uint32_t pad_t; typedef ulong_t itm_type_t; typedef uintptr_t itm_place2_t; /* position of data */ typedef size_t itm_size_t; typedef long itm_num_t; typedef union itm_place_union { int64_t itm_64d; /* positon of real data */ struct { #if !defined(_LP64) && !defined(_LITTLE_ENDIAN) pad_t pad; #endif itm_place2_t ptr; #if !defined(_LP64) && defined(_LITTLE_ENDIAN) pad_t pad; #endif }itm_place_union_struct; char itm_c[8]; } itm_place_t; #define itm_ptr itm_place_union_struct.ptr #define itm_pad itm_place_union_struct.pad typedef struct { #if !defined(_LP64) && !defined(_LITTLE_ENDIAN) pad_t pad; #endif itm_size_t size; /* size in bytes */ #if !defined(_LP64) && defined(_LITTLE_ENDIAN) pad_t pad; #endif itm_place_t place; /* place of data */ } itm_data_t; /* * Generic place table information */ typedef struct { #if !defined(_LP64) && !defined(_LITTLE_ENDIAN) pad_t pad1; #endif itm_size_t size; /* size in bytes */ #if !defined(_LP64) && defined(_LITTLE_ENDIAN) pad_t pad1; #endif itm_place_t place; /* place of place table */ #if !defined(_LP64) && !defined(_LITTLE_ENDIAN) pad_t pad2; #endif itm_num_t number; /* number of entry */ #if !defined(_LP64) && defined(_LITTLE_ENDIAN) pad_t pad2; #endif } itm_place_tbl_info_t; /* * Generic place table section */ typedef struct { #if !defined(_LP64) && !defined(_LITTLE_ENDIAN) pad_t pad1; #endif itm_size_t size; /* size in bytes */ #if !defined(_LP64) && defined(_LITTLE_ENDIAN) pad_t pad1; #endif itm_place_t place; /* place of table section */ #if !defined(_LP64) && !defined(_LITTLE_ENDIAN) pad_t pad2; #endif itm_num_t number; /* number of table */ #if !defined(_LP64) && defined(_LITTLE_ENDIAN) pad_t pad2; #endif } itm_section_info_t; /* * Generic table header */ #define ITM_TBL_MASK (0x000000ffUL) #define ITM_TBL_NONE (0x00000000UL) #define ITM_TBL_ITM (0x00000001UL) #define ITM_TBL_DIREC (0x00000002UL) #define ITM_TBL_COND (0x00000003UL) #define ITM_TBL_MAP (0x00000004UL) #define ITM_TBL_OP (0x00000005UL) #define ITM_TBL_RANGE (0x00000006UL) #define ITM_TBL_ESCAPESEQ (0x00000007UL) #define ITM_TBL_NONE_NONE (ITM_TBL_NONE | 0x00000000UL) #define ITM_TBL_DIREC_NONE (ITM_TBL_DIREC | 0x00000000UL) #define ITM_TBL_DIREC_RESET (ITM_TBL_DIREC | 0x00000100UL) #define ITM_TBL_COND_NONE (ITM_TBL_COND | 0x00000000UL) #define ITM_TBL_MAP_NONE (ITM_TBL_MAP | 0x00000000UL) #define ITM_TBL_MAP_INDEX_FIXED_1_1 (ITM_TBL_MAP | 0x00000100UL) #define ITM_TBL_MAP_INDEX_FIXED (ITM_TBL_MAP | 0x00000200UL) #define ITM_TBL_MAP_LOOKUP (ITM_TBL_MAP | 0x00000300UL) #define ITM_TBL_MAP_HASH (ITM_TBL_MAP | 0x00000400UL) #define ITM_TBL_MAP_DENSE_ENC (ITM_TBL_MAP | 0x00000500UL) #define ITM_TBL_MAP_VAR (ITM_TBL_MAP | 0x00000600UL) #define ITM_TBL_OP_NONE (ITM_TBL_OP | 0x00000000UL) #define ITM_TBL_OP_INIT (ITM_TBL_OP | 0x00000100UL) #define ITM_TBL_OP_RESET (ITM_TBL_OP | 0x00000200UL) #define ITM_TBL_RANGE_NONE (ITM_TBL_RANGE | 0x00000000UL) #define ITM_TBL_ESCAPESEQ_NONE (ITM_TBL_ESCAPESEQ | 0x00000000UL) typedef struct { #if !defined(_LP64) && !defined(_LITTLE_ENDIAN) pad_t pad1; #endif itm_type_t type; /* type of table */ #if !defined(_LP64) && defined(_LITTLE_ENDIAN) pad_t pad1; #endif itm_place_t name; /* name of table */ #if !defined(_LP64) && !defined(_LITTLE_ENDIAN) pad_t pad2; #endif itm_size_t size; /* size of table */ #if !defined(_LP64) && defined(_LITTLE_ENDIAN) pad_t pad2; #endif #if !defined(_LP64) && !defined(_LITTLE_ENDIAN) pad_t pad3; #endif itm_num_t number; /* number of entry */ #if !defined(_LP64) && defined(_LITTLE_ENDIAN) pad_t pad3; #endif } itm_tbl_hdr_t; /* * Iconv Code Set Translation Module (ITM) header */ typedef struct { unsigned char ident[ITM_IDENT_LEN]; /* identifier */ unsigned char spec[ITM_SPEC_LEN]; /* platform specification */ unsigned char version[ITM_VER_LEN]; /* version */ unsigned char padding[ITM_PAD_LEN]; /* padding */ #if !defined(_LP64) && !defined(_LITTLE_ENDIAN) pad_t pad1; #endif itm_size_t itm_hdr_size; /* ITM header size */ #if !defined(_LP64) && defined(_LITTLE_ENDIAN) pad_t pad1; #endif itm_place_t itm_size; /* size of ITM (file size) */ itm_data_t type_id; /* type identifier */ itm_data_t interpreter; /* interpreter */ itm_place_t op_init_tbl; /* init operation table */ itm_place_t op_reset_tbl; /* reset operation table */ itm_place_t direc_init_tbl; /* initial direction table */ #if !defined(_LP64) && !defined(_LITTLE_ENDIAN) pad_t pad3; #endif itm_num_t reg_num; /* number of register */ #if !defined(_LP64) && defined(_LITTLE_ENDIAN) pad_t pad3; #endif itm_place_t info_hdr; /* ITM Info header */ } itm_hdr_t; /* * ITM Info header */ typedef struct { itm_section_info_t str_sec; /* string section */ itm_section_info_t direc_tbl_sec; /* direction table section */ itm_section_info_t cond_tbl_sec; /* condition table section */ itm_section_info_t map_tbl_sec; /* map table section */ itm_section_info_t op_tbl_sec; /* operation table section */ itm_section_info_t range_tbl_sec; /* range section */ itm_section_info_t escapeseq_tbl_sec; /* escapeseq section */ itm_section_info_t data_sec; /* data section */ itm_section_info_t name_sec; /* name section */ itm_place_tbl_info_t str_plc_tbl; /* string info */ itm_place_tbl_info_t direc_plc_tbl; /* direction table info */ itm_place_tbl_info_t cond_plc_tbl; /* condition table info */ itm_place_tbl_info_t map_plc_tbl; /* map table info */ itm_place_tbl_info_t op_plc_tbl; /* operation table info */ itm_place_tbl_info_t range_plc_tbl; /* range info */ itm_place_tbl_info_t escapeseq_plc_tbl; /* escape info */ itm_place_tbl_info_t data_plc_tbl; /* data info */ itm_place_tbl_info_t name_plc_tbl; /* name info */ itm_place_tbl_info_t reg_plc_tbl; /* register name info */ } itm_info_hdr_t; /* * Direction */ typedef enum { ITM_ACTION_NONE, /* not used */ ITM_ACTION_DIRECTION, /* direction */ ITM_ACTION_MAP, /* map */ ITM_ACTION_OPERATION /* operation */ } itm_action_type_t; typedef struct { itm_place_t condition; itm_place_t action; } itm_direc_t; /* * Condition */ typedef enum { ITM_COND_NONE = 0, /* not used */ ITM_COND_BETWEEN = 1, /* input data is inside of ranges */ ITM_COND_EXPR = 2, /* expression */ ITM_COND_ESCAPESEQ = 3 /* escape sequense */ } itm_cond_type_t; typedef struct { pad_t pad; itm_cond_type_t type; union { itm_place_t place; itm_data_t data; } operand; } itm_cond_t; typedef struct { #if !defined(_LP64) && !defined(_LITTLE_ENDIAN) pad_t pad; #endif itm_size_t len; #if !defined(_LP64) && defined(_LITTLE_ENDIAN) pad_t pad; #endif } itm_range_hdr_t; typedef struct { #if !defined(_LP64) && !defined(_LITTLE_ENDIAN) pad_t pad1; #endif itm_size_t len_min; #if !defined(_LP64) && defined(_LITTLE_ENDIAN) pad_t pad1; #endif #if !defined(_LP64) && !defined(_LITTLE_ENDIAN) pad_t pad2; #endif itm_size_t len_max; #if !defined(_LP64) && defined(_LITTLE_ENDIAN) pad_t pad2; #endif } itm_escapeseq_hdr_t; /* * Map table: octet-sequence to octet-sequence: index */ typedef struct { #if !defined(_LP64) && !defined(_LITTLE_ENDIAN) pad_t pad1; #endif itm_size_t source_len; /* source length */ #if !defined(_LP64) && defined(_LITTLE_ENDIAN) pad_t pad1; #endif #if !defined(_LP64) && !defined(_LITTLE_ENDIAN) pad_t pad2; #endif itm_size_t result_len; /* result length */ #if !defined(_LP64) && defined(_LITTLE_ENDIAN) pad_t pad2; #endif itm_place_t start; /* start offset */ itm_place_t end; /* end offset */ #if !defined(_LP64) && !defined(_LITTLE_ENDIAN) pad_t pad3_num; #endif itm_num_t default_error; /* * -1:path through * 0:with default value * 1:with error table * 2:without error table */ #if !defined(_LP64) && defined(_LITTLE_ENDIAN) pad_t pad3_num; #endif #if !defined(_LP64) && !defined(_LITTLE_ENDIAN) pad_t pad4_num; #endif itm_num_t error_num; #if !defined(_LP64) && defined(_LITTLE_ENDIAN) pad_t pad4_num; #endif } itm_map_idx_fix_hdr_t; /* * Map table: octet-sequence to octet-sequence: lookup */ typedef struct { #if !defined(_LP64) && !defined(_LITTLE_ENDIAN) pad_t pad1; #endif itm_size_t source_len; /* source length */ #if !defined(_LP64) && defined(_LITTLE_ENDIAN) pad_t pad1; #endif #if !defined(_LP64) && !defined(_LITTLE_ENDIAN) pad_t pad2; #endif itm_size_t result_len; /* result length */ #if !defined(_LP64) && defined(_LITTLE_ENDIAN) pad_t pad2; #endif #if !defined(_LP64) && !defined(_LITTLE_ENDIAN) pad_t pad3_num; #endif itm_num_t default_error; /* * -1:path through * 0:with default value * 1:with error table * 2:without error table */ #if !defined(_LP64) && defined(_LITTLE_ENDIAN) pad_t pad3_num; #endif #if !defined(_LP64) && !defined(_LITTLE_ENDIAN) pad_t pad4_num; #endif itm_num_t error_num; #if !defined(_LP64) && defined(_LITTLE_ENDIAN) pad_t pad4_num; #endif } itm_map_lookup_hdr_t; /* * Map table: octet-sequence to octet-sequence: hash */ typedef struct { #if !defined(_LP64) && !defined(_LITTLE_ENDIAN) pad_t pad1; #endif itm_size_t source_len; /* source length */ #if !defined(_LP64) && defined(_LITTLE_ENDIAN) pad_t pad1; #endif #if !defined(_LP64) && !defined(_LITTLE_ENDIAN) pad_t pad2; #endif itm_size_t result_len; /* result length */ #if !defined(_LP64) && defined(_LITTLE_ENDIAN) pad_t pad2; #endif #if !defined(_LP64) && !defined(_LITTLE_ENDIAN) pad_t pad3; #endif itm_size_t hash_tbl_size; /* hash table size */ #if !defined(_LP64) && defined(_LITTLE_ENDIAN) pad_t pad3; #endif #if !defined(_LP64) && !defined(_LITTLE_ENDIAN) pad_t pad4; #endif itm_num_t hash_tbl_num; /* hash table entryies */ #if !defined(_LP64) && defined(_LITTLE_ENDIAN) pad_t pad4; #endif #if !defined(_LP64) && !defined(_LITTLE_ENDIAN) pad_t pad5; #endif itm_size_t hash_of_size; /* hash overflow table size */ #if !defined(_LP64) && defined(_LITTLE_ENDIAN) pad_t pad5; #endif #if !defined(_LP64) && !defined(_LITTLE_ENDIAN) pad_t pad6; #endif itm_num_t hash_of_num; /* hash overflow table entryies */ #if !defined(_LP64) && defined(_LITTLE_ENDIAN) pad_t pad6; #endif #if !defined(_LP64) && !defined(_LITTLE_ENDIAN) pad_t pad7_num; #endif itm_num_t default_error; /* * -1:path through * 0:with default value * 1:with error table * 2:without error table */ #if !defined(_LP64) && defined(_LITTLE_ENDIAN) pad_t pad7_num; #endif #if !defined(_LP64) && !defined(_LITTLE_ENDIAN) pad_t pad8_num; #endif itm_num_t error_num; #if !defined(_LP64) && defined(_LITTLE_ENDIAN) pad_t pad8_num; #endif } itm_map_hash_hdr_t; /* * Map table: octet-sequence to octet-sequence: dense encoding */ typedef struct { #if !defined(_LP64) && !defined(_LITTLE_ENDIAN) pad_t pad1; #endif itm_size_t source_len; /* source length */ #if !defined(_LP64) && defined(_LITTLE_ENDIAN) pad_t pad1; #endif #if !defined(_LP64) && !defined(_LITTLE_ENDIAN) pad_t pad2; #endif itm_size_t result_len; /* result length */ #if !defined(_LP64) && defined(_LITTLE_ENDIAN) pad_t pad2; #endif #if !defined(_LP64) && !defined(_LITTLE_ENDIAN) pad_t pad3_num; #endif itm_num_t default_error; /* * -1:path through * 0:with default value * 1:with error table * 2:without error table */ #if !defined(_LP64) && defined(_LITTLE_ENDIAN) pad_t pad3_num; #endif #if !defined(_LP64) && !defined(_LITTLE_ENDIAN) pad_t pad4_num; #endif itm_num_t error_num; #if !defined(_LP64) && defined(_LITTLE_ENDIAN) pad_t pad4_num; #endif } itm_map_dense_enc_hdr_t; /* * Operation */ typedef enum { /* Operation Type */ ITM_OP_NONE, /* not used */ ITM_OP_ERROR, /* error */ ITM_OP_ERROR_D, /* error */ ITM_OP_OUT, /* output */ ITM_OP_OUT_D, /* output */ ITM_OP_OUT_S, /* output */ ITM_OP_OUT_R, /* output */ ITM_OP_OUT_INVD, /* output */ ITM_OP_DISCARD, /* discard */ ITM_OP_DISCARD_D, /* discard */ ITM_OP_EXPR, /* expression */ ITM_OP_IF, /* if */ ITM_OP_IF_ELSE, /* if_else */ ITM_OP_DIRECTION, /* switch direction */ ITM_OP_MAP, /* use map */ ITM_OP_OPERATION, /* invoke operation */ ITM_OP_INIT, /* invoke init operation */ ITM_OP_RESET, /* invoke reset operation */ ITM_OP_BREAK, /* break */ ITM_OP_RETURN, /* return */ ITM_OP_PRINTCHR, /* print out argument as character */ ITM_OP_PRINTHD, /* print out argument as hexadecimal */ ITM_OP_PRINTINT /* print out argument as integer */ } itm_op_type_t; typedef struct { pad_t pad; itm_op_type_t type; itm_place_t name; union { itm_place_t operand[3]; itm_data_t value; struct { #if !defined(_LP64) && !defined(_LITTLE_ENDIAN) pad_t pad_num; #endif itm_num_t num; #if !defined(_LP64) && defined(_LITTLE_ENDIAN) pad_t pad_num; #endif } itm_op_num; } data; } itm_op_t; #define itm_opnum itm_op_num.num #define itm_oppad itm_op_num.pad_num /* * Expression */ #define ITM_EXPR_PROTO(type, op0, op1) ITM_EXPR_##type##_##op0##_##op1 #define ITM_EXPR_BIN(type) \ ITM_EXPR_PROTO(type, E, E), \ ITM_EXPR_PROTO(type, E, D), \ ITM_EXPR_PROTO(type, E, R), \ ITM_EXPR_PROTO(type, E, INVD), \ ITM_EXPR_PROTO(type, D, E), \ ITM_EXPR_PROTO(type, D, D), \ ITM_EXPR_PROTO(type, D, R), \ ITM_EXPR_PROTO(type, D, INVD), \ ITM_EXPR_PROTO(type, R, E), \ ITM_EXPR_PROTO(type, R, D), \ ITM_EXPR_PROTO(type, R, R), \ ITM_EXPR_PROTO(type, R, INVD), \ ITM_EXPR_PROTO(type, INVD, E), \ ITM_EXPR_PROTO(type, INVD, D), \ ITM_EXPR_PROTO(type, INVD, R), \ ITM_EXPR_PROTO(type, INVD, INVD) #define ITM_EXPR_PLUS ITM_EXPR_PLUS_E_E #define ITM_EXPR_MINUS ITM_EXPR_MINUS_E_E #define ITM_EXPR_MUL ITM_EXPR_MUL_E_E #define ITM_EXPR_DIV ITM_EXPR_DIV_E_E #define ITM_EXPR_MOD ITM_EXPR_MOD_E_E #define ITM_EXPR_SHIFT_L ITM_EXPR_SHIFT_L_E_E #define ITM_EXPR_SHIFT_R ITM_EXPR_SHIFT_R_E_E #define ITM_EXPR_OR ITM_EXPR_OR_E_E #define ITM_EXPR_XOR ITM_EXPR_XOR_E_E #define ITM_EXPR_AND ITM_EXPR_AND_E_E #define ITM_EXPR_EQ ITM_EXPR_EQ_E_E #define ITM_EXPR_NE ITM_EXPR_NE_E_E #define ITM_EXPR_GT ITM_EXPR_GT_E_E #define ITM_EXPR_GE ITM_EXPR_GE_E_E #define ITM_EXPR_LT ITM_EXPR_LT_E_E #define ITM_EXPR_LE ITM_EXPR_LE_E_E typedef enum { /* Expression Type */ ITM_EXPR_NONE, /* not used */ ITM_EXPR_NOP, /* not used */ ITM_EXPR_NAME, /* not used */ ITM_EXPR_INT, /* integer */ ITM_EXPR_SEQ, /* byte sequence */ ITM_EXPR_REG, /* register */ ITM_EXPR_IN_VECTOR, /* in[expr] */ ITM_EXPR_IN_VECTOR_D, /* in[DECIMAL] */ ITM_EXPR_OUT, /* out */ ITM_EXPR_TRUE, /* true */ ITM_EXPR_FALSE, /* false */ ITM_EXPR_IN, /* input data */ ITM_EXPR_UMINUS, /* unary minus */ ITM_EXPR_BIN(PLUS), /* A + B */ ITM_EXPR_BIN(MINUS), /* A - B */ ITM_EXPR_BIN(MUL), /* A * B */ ITM_EXPR_BIN(DIV), /* A / B */ ITM_EXPR_BIN(MOD), /* A % B */ ITM_EXPR_BIN(SHIFT_L), /* A << B */ ITM_EXPR_BIN(SHIFT_R), /* A >> B */ ITM_EXPR_BIN(OR), /* A | B */ ITM_EXPR_BIN(XOR), /* A ^ B */ ITM_EXPR_BIN(AND), /* A & B */ ITM_EXPR_BIN(EQ), /* A == B */ ITM_EXPR_BIN(NE), /* A != B */ ITM_EXPR_BIN(GT), /* A > B */ ITM_EXPR_BIN(GE), /* A >= B */ ITM_EXPR_BIN(LT), /* A < B */ ITM_EXPR_BIN(LE), /* A <= B */ ITM_EXPR_NOT, /* !A */ ITM_EXPR_NEG, /* ~A */ ITM_EXPR_LOR, /* A || B */ ITM_EXPR_LAND, /* A && B */ ITM_EXPR_ASSIGN, /* A = B */ ITM_EXPR_OUT_ASSIGN, /* out = A */ ITM_EXPR_IN_EQ, /* in == A */ ITM_EXPR_IF, /* if */ ITM_EXPR_ELSE /* else */ } itm_expr_type_t; #define ITM_OPERAND_EXPR (0) #define ITM_OPERAND_PLACE (1) #define ITM_OPERAND_VALUE (2) #define ITM_OPERAND_REGISTER (3) typedef struct { pad_t pad; itm_expr_type_t type; union { itm_place_t operand[2]; itm_data_t value; struct { #if !defined(_LP64) && !defined(_LITTLE_ENDIAN) pad_t pad_num; #endif itm_num_t num; #if !defined(_LP64) && defined(_LITTLE_ENDIAN) pad_t pad_num; #endif } itm_ex_num; } data; } itm_expr_t; #define itm_exnum itm_ex_num.num #define itm_expad itm_ex_num.pad_num #ifdef __cplusplus } #endif #endif /* !_ICONV_TM_H */ %{ /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END * * Copyright (c) 1999 by Sun Microsystems, Inc. * All rights reserved. */ #include #include #include #include #include #include #include #include "iconv_tm.h" #include "itmcomp.h" #include "y.tab.h" static itm_data_t *hexadecimal_data(int, char *); static itm_data_t *name_data(int, char *); static void filename_lineno(void); static int at_name_to_token(char *); %} %start norm comment DECIMAL ([0-9]+) OCTAL (0[0-7][0-7]+) HEXADECIMAL (("0x"|"0X")([0-9A-Fa-f])+) ITMNAME (([^% \t\n\r])+"%"([^% \t\n\r])+) ATNAME "@"([0-9A-Za-z_]+) NAME ([A-Za-z_][A-Za-z0-9_]*) MAPTYPE_NAME (automatic|dense|index|hash|binary) %% [ \t\n]+ ; "//".*"\n" ; ^"#"[ \t]*{DECIMAL}[ \t]*"\"".*"\"".*"\n" { filename_lineno(); } ^"#".*"\n" { if (NULL == cmd_opt.preprocess) { itm_error( gettext("warning: " "preprocess may be required\n")); } } {DECIMAL} { yylval.num = strtoul(yytext, (char **)NULL, 10); return (DECIMAL); } {OCTAL} { yylval.num = strtoul(yytext, (char **)NULL, 8); return (DECIMAL); } {HEXADECIMAL} { yylval.data = hexadecimal_data(yyleng - 2, yytext + 2); return (HEXADECIMAL); } {ITMNAME} { yylval.data = str_to_data(yyleng, yytext); return (ITMNAME); } {ATNAME} { return at_name_to_token(yytext); } {MAPTYPE_NAME} { yylval.num = at_name_to_token(yytext); yylval.data = name_data(yyleng, yytext); return (MAPTYPE_NAME); } {NAME} { yylval.num = at_name_to_token(yytext); if (0 != yylval.num) { return (yylval.num); } else { yylval.data = name_data(yyleng, yytext); return (NAME); } } "{" {return (CBO);} "}" {return (CBC);} "[" {return (SBO);} "]" {return (SBC);} "(" {return (PO);} ")" {return (PC);} ";" {return (SC);} "," {return (COMMA);} ":" {return (COLON);} "..." {return (ELLIPSES);} "=" {return (ASSIGN);} "||" {return (LOR);} "&&" {return (LAND);} "|" {return (OR);} "^" {return (XOR);} "&" {return (AND);} "==" {return (EQ);} "!=" {return (NE);} "<" {return (LT);} "<=" {return (LE);} ">" {return (GT);} ">=" {return (GE);} "<<" {return (SHL);} ">>" {return (SHR);} "+" {return (PLUS);} "-" {return (MINUS);} "*" {return (MUL);} "/" {return (DIV);} "%" {return (MOD);} "!" {return (NOT);} "~" {return (NEG);} . { itm_error( gettext("Unrecognized token '%1$c' \n"), cmd_opt.my_name, yytext[0]); return (0); } %% /* * lexinit - starts the Lexical Analyzer off in the right start condition */ void lexinit() { BEGIN norm; } /* does this really need to be here? */ int yywrap() { return (1); } void yyerror(char *s) { extern int yylineno; itm_error( gettext("%1$s: file(%2$s) line(%3$d) last token(%4$s)\n"), s, itm_input_file, yylineno, yytext); exit(ITMC_STATUS_BT); } typedef struct { char *name; int token; } at_name_token_t; /* * NOT: This table must be sorted alphabetically. */ static at_name_token_t at_table[] = { "@automatic", MAPTYPE_AUTO, "@binary", MAPTYPE_BINARY, "@between", BETWEEN, "@condition", CONDITION, "@default", ITM_DEFAULT, "@dense", MAPTYPE_DENSE, "@direction", DIRECTION, "@discard", DISCARD, "@else", ITM_ELSE, "@error", ERROR, "@escapeseq", ESCAPESEQ, "@false", ITM_FALSE, "@hash", MAPTYPE_HASH, "@identical", ITM_IDENTICAL, "@if", ITM_IF, "@in", ITM_IN, "@index", MAPTYPE_INDEX, "@init", ITM_INIT, "@input", ITM_IN, "@inputsize", ITM_INSIZE, "@map", MAP, "@maptype", MAPTYPE, "@no_change_copy", ITM_IDENTICAL, "@nop", NOP, "@operation", OPERATION, "@out", ITM_OUT, "@output", ITM_OUT, "@output_byte_length", RESULTLEN, "@outputsize", ITM_OUTSIZE, "@printchr", PRINTCHR, "@printhd", PRINTHD, "@printint", PRINTINT, "@reset", RESET, "@resultlen", RESULTLEN, "@return", RETURN, "@true", ITM_TRUE, "automatic", MAPTYPE_AUTO, "between", BETWEEN, "binary", MAPTYPE_BINARY, "break", BREAK, "condition", CONDITION, "default", ITM_DEFAULT, "dense", MAPTYPE_DENSE, "direction", DIRECTION, "discard", DISCARD, "else", ITM_ELSE, "error", ERROR, "escapeseq", ESCAPESEQ, "false", ITM_FALSE, "hash", MAPTYPE_HASH, "if", ITM_IF, "index", MAPTYPE_INDEX, "init", ITM_INIT, "input", ITM_IN, "inputsize", ITM_INSIZE, "map", MAP, "maptype", MAPTYPE, "no_change_copy", ITM_IDENTICAL, "nop", NOP, "operation", OPERATION, "output", ITM_OUT, "output_byte_length", RESULTLEN, "outputsize", ITM_OUTSIZE, "printchr", PRINTCHR, "printhd", PRINTHD, "printint", PRINTINT, "reset", RESET, "return", RETURN, "true", ITM_TRUE, }; int at_name_to_token(char *s) { int high; int mid; int low; int result; TRACE_MESSAGE('l', ("at_name_to_token: %s", s)); for (low = 0, high = (sizeof (at_table) / sizeof (at_name_token_t)); low < high; /* NOP */) { mid = (low + high) / 2; result = strcmp(s, at_table[mid].name); if (result < 0) { high = mid; } else if (0 < result) { low = mid + 1; } else { /* 0 == result */ TRACE_MESSAGE('l', (" %d\n", at_table[mid].token)); return (at_table[mid].token); } } TRACE_MESSAGE('l', (" - not found\n")); return (0); } static itm_data_t * hexadecimal_data(int seqsize, char *seq) { itm_data_t *data; char *binary; int i, j; int val; int high; int low; int size; /* size is assured to be multiple of 2 */ assert(seqsize != 0); size = seqsize + 1; size /= 2; if (size > MAXSEQUENCE) { itm_error( gettext(" specified sequence must be less than %$1d\n"), MAXSEQUENCE); return (NULL); } binary = malloc_vital(size); i = j = 0; if (seqsize % 2 != 0) { low = *(seq); if (('0' <= low) && (low <= '9')) { val = (low - '0'); } else if (('a' <= low) && (low <= 'f')) { val = (low - 'a' + 10); } else if (('A' <= low) && (low <= 'F')) { val = (low - 'A' + 10); } *(binary + i) = val; i++; j++; } for (/* NOP */; i < size; i++, j += 2) { high = *(seq + j); low = *(seq + j + 1); if (('0' <= high) && (high <= '9')) { val = ((high - '0') << 4); } else if (('a' <= high) && (high <= 'f')) { val = ((high - 'a' + 10) << 4); } else if (('A' <= high) && (high <= 'F')) { val = ((high - 'A' + 10) << 4); } if (('0' <= low) && (low <= '9')) { val |= (low - '0'); } else if (('a' <= low) && (low <= 'f')) { val |= (low - 'a' + 10); } else if (('A' <= low) && (low <= 'F')) { val |= (low - 'A' + 10); } *(binary + i) = val; } data = malloc_vital(sizeof (itm_data_t)); data->size = size; if (size <= sizeof (data->place)) { (void) memmove(&(data->place), binary, size); free(binary); } else { data->place.itm_ptr = (itm_place2_t)binary; } return (data); } static itm_data_t * name_data(int size, char *seq) { itm_data_t *data; if (size > MAXNAMELENGTH) { itm_error(gettext("the length(%d) exceed limitation(%d)"), size, MAXNAMELENGTH); exit(ITMC_STATUS_BT2); } data = malloc_vital(sizeof (itm_data_t)); data->size = size; if (size <= sizeof (data->place)) { (void) memmove(&(data->place), seq, size); } else { data->place.itm_ptr = (itm_place2_t)malloc_vital(size); (void) memmove((char *)(data->place.itm_ptr), seq, size); } return (data); } static void filename_lineno(void) { static char *re; static char restr[] = "^#[ \t]*\\([0-9]\\{1,\\}\\)[ \t]*\"\\(.*\\)\".*"; int match; extern char *braslist[]; extern char *braelist[]; static char *filename; int len; int lineno; if (NULL == re) { re = compile(restr, NULL, NULL); if (NULL == re) { itm_error( gettext("REGEXP compile error\n")); exit(ITMC_STATUS_BT); } } match = step(yytext, re); if (0 != match) { lineno = atoi(braslist[0]); free(filename); len = braelist[1] - braslist[1]; filename = malloc_vital(len + 1); (void) memcpy(filename, braslist[1], len); *(filename + len) = '\0'; itm_input_file = filename; yylineno = lineno; } } %{ /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END * * Copyright (c) 1999 by Sun Microsystems, Inc. * All rights reserved. */ #include #include #include #include #include #include "iconv_tm.h" #include "itmcomp.h" #include "itm_util.h" %} %start itm_def %union yystacktype { int intval; itm_num_t num; itm_data_t *name; itm_data_t *data; itm_tbl_hdr_t *tbl_hdr; itm_direc_t *direc_unit; itm_expr_t *expr; itmc_action_t action; itmc_obj_t *obj; itmc_map_t *map_list; itmc_ref_t *itmc_ref; itmc_map_attr_t *map_attr; } %type itm_def %type def_element_list %type def_element %type direction %type direction_unit_list %type direction_unit %type action %type condition %type condition_list %type condition_expr %type range_list %type range_pair %type escseq_list %type escseq %type map %type map_list %type map_pair %type map_attribute %type map_resultlen %type map_type %type map_type_names %type operation %type op_list %type op_unit %type op_if_else %type name %type expr %type itm_in %token ITMNAME %token NAME %token MAPTYPE_NAME %token HEXADECIMAL %token DECIMAL %token ITM_DEFAULT %token ITM_IDENTICAL %token BETWEEN %token BREAK %token CONDITION %token DIRECTION %token DISCARD %token ERROR %token ITM_ELSE %token ITM_INIT %token ITM_FALSE %token ITM_IF %token ITM_IN %token ITM_INSIZE %token NOP %token OPERATION %token ITM_OUT %token ITM_OUTSIZE %token PRINTCHR %token PRINTHD %token PRINTINT %token MAP %token RESET %token RETURN %token ITM_TRUE %token ESCAPESEQ %token MAPTYPE %token RESULTLEN %token MAPTYPE_AUTO %token MAPTYPE_INDEX %token MAPTYPE_DENSE %token MAPTYPE_HASH %token MAPTYPE_BINARY %token ELLIPSES %token CBO CBC %token SBO SBC %token PO PC %token SC %token COMMA %token COLON %right ASSIGN %left LOR %left LAND %left OR %left XOR %left AND %left EQ NE %left LT LE GT GE %left SHL SHR %left PLUS MINUS %left MUL DIV MOD %right NOT NEG UMINUS %% itm_def : ITMNAME CBO def_element_list CBC { itm_def_process($1); } ; def_element_list : def_element SC { TRACE_MESSAGE('y', ("def_element_list: def_element ;\n")); $$ = NULL; } | def_element_list def_element SC { TRACE_MESSAGE('y', ("def_element_list: def_element_list def_element ;\n")); $$ = NULL; } ; def_element : direction { TRACE_MESSAGE('y', ("def_element: direction\n")); (void) obj_register(ITMC_OBJ_DIREC, (itm_data_t *)($1->name.itm_ptr), $1, $1->size, NULL, OBJ_REG_TAIL); $$ = $1; } | condition { TRACE_MESSAGE('y', ("def_element: condition\n")); $$ = (itm_tbl_hdr_t *)($1->referencee); } | map { TRACE_MESSAGE('y', ("def_element: map\n")); if (NULL != $1) { (void) obj_register(ITMC_OBJ_MAP, (itm_data_t *)($1->name.itm_ptr), $1, $1->size, NULL, OBJ_REG_TAIL); } $$ = $1; } | operation { TRACE_MESSAGE('y', ("def_element: operation\n")); (void) obj_register(ITMC_OBJ_OP, (itm_data_t *)($1->name.itm_ptr), $1, $1->size, NULL, OBJ_REG_TAIL); $$ = $1; } ; direction : DIRECTION name CBO direction_unit_list CBC { TRACE_MESSAGE('y', ("direction name (direction_unit_list)\n")); $$ = obj_table(ITM_TBL_DIREC, $2, $4, sizeof (itm_direc_t)); } | DIRECTION CBO direction_unit_list CBC { TRACE_MESSAGE('y', ("direction name (direction_unit_list)\n")); $$ = obj_table(ITM_TBL_DIREC, NULL, $3, sizeof (itm_direc_t)); } ; direction_unit_list : direction_unit { TRACE_MESSAGE('y', ("direction_unit_list: direction_unit\n")); $$ = obj_list_append(NULL, $1); } | direction_unit_list direction_unit { TRACE_MESSAGE('y', ("direction_unit_list: " "direction_unit_list direction_unit\n")); $$ = obj_list_append($1, $2); } ; direction_unit : condition action SC { TRACE_MESSAGE('y', ("direction_unit: condition action ;\n")); $$ = direction_unit($1, NULL, &($2), NULL); } | condition name SC { itm_direc_t *direc; TRACE_MESSAGE('y', ("direction_unit: condition NAME ;\n")); $$ = direction_unit($1, NULL, NULL, $2); } | name action SC { itm_direc_t *direc; TRACE_MESSAGE('y', ("direction_unit: NAME action ;\n")); $$ = direction_unit(NULL, $1, &($2), NULL); } | name name SC { itm_direc_t *direc; TRACE_MESSAGE('y', ("direction_unit: NAME NAME ;\n")); $$ = direction_unit(NULL, $1, NULL, $2); } | ITM_TRUE action SC { itm_direc_t *direc; $$ = direction_unit(NULL, NULL, &($2), NULL); } | ITM_TRUE name SC { itm_direc_t *direc; TRACE_MESSAGE('y', ("direction_unit: TRUE NAME ;\n")); $$ = direction_unit(NULL, NULL, NULL, $2); } ; action : direction { TRACE_MESSAGE('y', ("action: direction\n")); $$.type = ITMC_OBJ_DIREC; $$.tbl_hdr = $1; } | map { TRACE_MESSAGE('y', ("action: map\n")); $$.type = ITMC_OBJ_MAP; $$.tbl_hdr = $1; } | operation { TRACE_MESSAGE('y', ("action: operation\n")); $$.type = ITMC_OBJ_OP; $$.tbl_hdr = $1; } ; condition : CONDITION name CBO condition_list CBC { itm_tbl_hdr_t *tbl_hdr; TRACE_MESSAGE('y', ("condition\n")); tbl_hdr = obj_table(ITM_TBL_COND, $2, $4, sizeof (itm_cond_t)); $$ = obj_register(ITMC_OBJ_COND, $2, tbl_hdr, tbl_hdr->size, NULL, OBJ_REG_TAIL); } | CONDITION CBO condition_list CBC { itm_tbl_hdr_t *tbl_hdr; TRACE_MESSAGE('y', ("condition\n")); tbl_hdr = obj_table(ITM_TBL_COND, NULL, $3, sizeof (itm_cond_t)); $$ = obj_register(ITMC_OBJ_COND, NULL, tbl_hdr, tbl_hdr->size, NULL, OBJ_REG_TAIL); } ; condition_list : condition_expr SC { TRACE_MESSAGE('y', ("condition_list: condition_expr;\n")); $$ = obj_list_append(NULL, $1); } | condition_list condition_expr SC { TRACE_MESSAGE('y', ("condition_list: " "condition_list condition_expr;\n")); $$ = obj_list_append($1, $2); } ; condition_expr : BETWEEN range_list { itm_tbl_hdr_t *range; itm_cond_t *cond; TRACE_MESSAGE('y', ("condition_expr: between\n")); range = range_table(NULL, $2); if (range == NULL) { $$ = NULL; } else { $$ = malloc_vital(sizeof (itmc_obj_t)); $$->type = ITMC_OBJ_RANGE; $$->name = NULL; cond = malloc_vital(sizeof (itm_cond_t)); $$->obj = cond; cond->type = ITM_COND_BETWEEN; cond->operand.place.itm_ptr = (itm_place2_t)range; $$->ref[0] = obj_register(ITMC_OBJ_RANGE, NULL, range, range->size, &(cond->operand.place), OBJ_REG_TAIL); $$->ref[1] = NULL; $$->ref[2] = NULL; $$->next = $$->last = NULL; } } | expr { itm_cond_t *cond; TRACE_MESSAGE('y', ("condition_expr: expr\n")); $$ = malloc_vital(sizeof (itmc_obj_t)); $$->type = ITMC_OBJ_EXPR; $$->name = NULL; cond = malloc_vital(sizeof (itm_cond_t)); $$->obj = cond; cond->type = ITM_COND_EXPR; cond->operand.place.itm_ptr = (itm_place2_t)($1); $$->ref[0] = obj_register(ITMC_OBJ_EXPR, NULL, $1, sizeof (itm_expr_t), &(cond->operand.place), OBJ_REG_TAIL); $$->ref[1] = NULL; $$->ref[2] = NULL; $$->next = $$->last = NULL; } | ESCAPESEQ escseq_list { itm_tbl_hdr_t *escseq; itm_cond_t *cond; TRACE_MESSAGE('y', ("condition_expr: escseq {escseq_list;}\n")); escseq = escseq_table(NULL, $2); if (escseq == NULL) { $$ = NULL; } else { $$ = malloc_vital(sizeof (itmc_obj_t)); $$->type = ITMC_OBJ_ESCAPESEQ; $$->name = NULL; cond = malloc_vital(sizeof (itm_cond_t)); $$->obj = cond; cond->type = ITM_COND_ESCAPESEQ; cond->operand.place.itm_ptr = (itm_place2_t)escseq; $$->ref[0] = obj_register(ITMC_OBJ_ESCAPESEQ, NULL, escseq, escseq->size, &(cond->operand.place), OBJ_REG_TAIL); $$->ref[1] = NULL; $$->ref[2] = NULL; $$->next = $$->last = NULL; } } ; range_list : range_pair { TRACE_MESSAGE('y', ("range_list: range_pair\n")); $$ = obj_list_append(NULL, $1); } | range_list COMMA range_pair { TRACE_MESSAGE('y', ("range_list: range_list, range_pair\n")); $$ = obj_list_append($1, $3); } ; range_pair : HEXADECIMAL ELLIPSES HEXADECIMAL { itmc_data_pair_t *range; TRACE_MESSAGE('y', ("range_pair: HEXADECIMAL...HEXADECIMAL\n")); $$ = malloc_vital(sizeof (itmc_obj_t)); $$->type = ITMC_OBJ_RANGE; $$->name = NULL; range = malloc_vital(sizeof (itmc_data_pair_t)); $$->obj = range; if (data_compare($1, $3) < 0) { range->data0 = *($1); range->data1 = *($3); } else { range->data0 = *($3); range->data1 = *($1); } } ; escseq_list : escseq { TRACE_MESSAGE('y', ("escseq_list: escseq\n")); $$ = obj_list_append(NULL, $1); } | escseq_list COMMA escseq { TRACE_MESSAGE('y', ("escseq_list: escseq_list; escseq\n")); $$ = obj_list_append($1, $3); } ; escseq : HEXADECIMAL { itm_data_t *escseq; TRACE_MESSAGE('y', ("escseq: HEXADECIMAL\n")); $$ = malloc_vital(sizeof (itmc_obj_t)); $$->type = ITMC_OBJ_ESCAPESEQ; $$->name = NULL; escseq = malloc_vital(sizeof (itm_data_t)); $$->obj = escseq; *escseq = *($1); } ; map : MAP name CBO map_list CBC { TRACE_MESSAGE('y', ("map: map name {map_list}\n")); $$ = map_table($2, $4, NULL); } | MAP CBO map_list CBC { TRACE_MESSAGE('y', ("map: map {map_list}\n")); $$ = map_table(NULL, $3, NULL); } | MAP name map_attribute CBO map_list CBC { TRACE_MESSAGE('y', ("map: map name attribute {map_list}\n")); $$ = map_table($2, $5, $3); } | MAP map_attribute CBO map_list CBC { TRACE_MESSAGE('y', ("map: map attribute {map_list}\n")); $$ = map_table(NULL, $4, $2); } ; map_attribute :map_type COMMA map_resultlen { TRACE_MESSAGE('y', ("map_attribute: map_type map_resultlen\n")); $$ = $1; $$->resultlen = $3; } |map_type { TRACE_MESSAGE('y', ("map_attribute: map_type\n")); $$ = $1; $$->resultlen = 0; } |map_resultlen COMMA map_type { TRACE_MESSAGE('y', ("map_attribute: map_resultlen map_type\n")); $$ = $3; $$->resultlen = $1; } |map_resultlen { TRACE_MESSAGE('y', ("map_attribute: map_resultlen\n")); $$ = malloc_vital(sizeof (itmc_map_attr_t)); $$->resultlen = $1; $$->type = NULL; $$->hash_factor = 0; } ; map_type : MAPTYPE ASSIGN map_type_names COLON DECIMAL { TRACE_MESSAGE('y', ("map_type: maptype=type:factor(%d)\n", $5)); $$ = malloc_vital(sizeof (itmc_map_attr_t)); $$->type = $3; $$->hash_factor = $5; } | MAPTYPE ASSIGN map_type_names { TRACE_MESSAGE('y', ("map_type: maptype=type\n")); $$ = malloc_vital(sizeof (itmc_map_attr_t)); $$->type = $3; $$->hash_factor = 0; } ; map_type_names : MAPTYPE_NAME { TRACE_MESSAGE('y', ("map_type_names: size=%*s\n", yylval.data->size, NSPTR(yylval.data))); $$ = yylval.data; } ; map_resultlen : RESULTLEN ASSIGN DECIMAL { TRACE_MESSAGE('y', ("map_resultlen(%d)\n", $3)); $$ = $3; } ; map_list : map_pair { TRACE_MESSAGE('y', ("map_list: map_pair\n")); $$ = map_list_append(NULL, $1); } | map_list map_pair { TRACE_MESSAGE('y', ("map_list: map_list map_pair\n")); $$ = map_list_append($1, $2); } ; map_pair : HEXADECIMAL HEXADECIMAL { TRACE_MESSAGE('y', ("map_pair: HEXADECIMAL HEXADECIMAL\n")); $$ = malloc_vital(sizeof (itmc_map_t)); $$->data_pair.data0 = *($1); free($1); $$->data_pair.data1 = *($2); free($2); } | HEXADECIMAL ELLIPSES HEXADECIMAL HEXADECIMAL { TRACE_MESSAGE('y', ("map_pair: " "HEXADECIMAL ELLIPSES HEXADECIMAL\n")); $$ = malloc_vital(sizeof (itmc_map_t)); $$->data_pair.data0 = *($1); $$->data_pair.range = *($3); free($1); free($3); $$->data_pair.data1 = *($4); free($4); } | ITM_DEFAULT HEXADECIMAL { TRACE_MESSAGE('y', ("map_pair: default HEXADECIMAL\n")); $$ = malloc_vital(sizeof (itmc_map_t)); $$->data_pair.data0.size = 0; $$->data_pair.data1 = *($2); free($2); } | ITM_DEFAULT ITM_IDENTICAL { TRACE_MESSAGE('y', ("map_pair: default default\n")); $$ = malloc_vital(sizeof (itmc_map_t)); $$->data_pair.data0.size = 0; $$->data_pair.data1.size = 0; } | HEXADECIMAL ERROR /* NO RANGE */ { TRACE_MESSAGE('y', ("map_pair: hexadecimal error\n")); $$ = malloc_vital(sizeof (itmc_map_t)); $$->data_pair.data0 = *($1); free($1); $$->data_pair.data1.size = 0; } ; operation : OPERATION name CBO op_list CBC { TRACE_MESSAGE('y', ("operation: operation name {op_list}\n")); $$ = obj_table(ITM_TBL_OP, $2, $4, sizeof (itm_op_t)); } | OPERATION CBO op_list CBC { TRACE_MESSAGE('y', ("operation: operation {op_list}\n")); $$ = obj_table(ITM_TBL_OP, NULL, $3, sizeof (itm_op_t)); } | OPERATION ITM_INIT CBO op_list CBC { TRACE_MESSAGE('y', ("operation: operation init {op_list}\n")); $$ = obj_table(ITM_TBL_OP_INIT, NULL, $4, sizeof (itm_op_t)); } | OPERATION RESET CBO op_list CBC { TRACE_MESSAGE('y', ("operation: operation reset {op_list}\n")); $$ = obj_table(ITM_TBL_OP_RESET, NULL, $4, sizeof (itm_op_t)); } ; op_list : op_unit { TRACE_MESSAGE('y', ("op_list: op_unit\n")); $$ = obj_list_append(NULL, $1); } | op_list op_unit { TRACE_MESSAGE('y', ("op_list: op_list op_unit\n")); $$ = obj_list_append($1, $2); } ; op_unit : /* */ SC { TRACE_MESSAGE('y', ("op_unit: / *null */;\n")); $$ = NULL; } | expr SC { TRACE_MESSAGE('y', ("op_unit: expr;\n")); $$ = op_unary(ITM_OP_EXPR, $1, sizeof (itm_expr_t)); } | ERROR SC { TRACE_MESSAGE('y', ("expr: error;\n")); $$ = op_self_num(ITM_OP_ERROR_D, EINVAL); } | ERROR expr SC { TRACE_MESSAGE('y', ("expr: error;\n")); if (ITM_EXPR_INT == $2->type) { $$ = op_self_num(ITM_OP_ERROR_D, $2->data.itm_exnum); } else { $$ = op_unary(ITM_OP_ERROR, $2, sizeof (itm_expr_t)); } } | DISCARD SC { TRACE_MESSAGE('y', ("discard expr;\n")); $$ = op_self_num(ITM_OP_DISCARD_D, 1); } | DISCARD expr SC { TRACE_MESSAGE('y', ("discard expr;\n")); if (ITM_EXPR_INT == $2->type) { $$ = op_self_num(ITM_OP_DISCARD_D, $2->data.itm_exnum); } else { $$ = op_unary(ITM_OP_DISCARD, $2, sizeof (itm_expr_t)); } } | ITM_OUT ASSIGN expr SC { TRACE_MESSAGE('y', ("out = expr;\n")); switch ($3->type) { case ITM_EXPR_INT: $$ = op_unary(ITM_OP_OUT_D, $3, sizeof (itm_expr_t)); break; case ITM_EXPR_SEQ: $$ = op_unary(ITM_OP_OUT_S, $3, sizeof (itm_expr_t)); break; case ITM_EXPR_REG: $$ = op_unary(ITM_OP_OUT_R, $3, sizeof (itm_expr_t)); break; case ITM_EXPR_IN_VECTOR_D: $$ = op_unary(ITM_OP_OUT_INVD, $3, sizeof (itm_expr_t)); break; default: $$ = op_unary(ITM_OP_OUT, $3, sizeof (itm_expr_t)); break; } } | DIRECTION name SC { itm_op_t *op; TRACE_MESSAGE('y', ("direction NAME;\n")); $$ = op_unit(ITM_OP_DIRECTION, NULL, 0, NULL, 0, NULL, 0); op = (itm_op_t *)($$->obj); op->data.operand[0].itm_ptr = (itm_place2_t)($2); $$->ref[0] = obj_register(ITMC_OBJ_DIREC, $2, NULL, 0, &(op->data.operand[0]), OBJ_REG_TAIL); } | OPERATION name SC { itm_op_t *op; TRACE_MESSAGE('y', ("operation NAME;\n")); $$ = op_unit(ITM_OP_OPERATION, NULL, 0, NULL, 0, NULL, 0); op = (itm_op_t *)($$->obj); op->data.operand[0].itm_ptr = (itm_place2_t)($2); $$->ref[0] = obj_register(ITMC_OBJ_OP, $2, NULL, 0, &(op->data.operand[0]), OBJ_REG_TAIL); } | OPERATION ITM_INIT SC { itm_op_t *op; TRACE_MESSAGE('y', ("operation init;\n")); $$ = op_self(ITM_OP_INIT); } | OPERATION RESET SC { itm_op_t *op; TRACE_MESSAGE('y', ("operation reset;\n")); $$ = op_self(ITM_OP_RESET); } | MAP name SC { itm_op_t *op; TRACE_MESSAGE('y', ("map NAME;\n")); $$ = op_unit(ITM_OP_MAP, NULL, 0, NULL, 0, NULL, 0); op = (itm_op_t *)($$->obj); op->data.operand[0].itm_ptr = (itm_place2_t)($2); $$->ref[0] = obj_register(ITMC_OBJ_MAP, $2, NULL, 0, &(op->data.operand[0]), OBJ_REG_TAIL); } | MAP name expr SC { itm_op_t *op; TRACE_MESSAGE('y', ("map NAME expr;\n")); $$ = op_unit(ITM_OP_MAP, NULL, 0, $3, sizeof (itm_expr_t), NULL, 0); op = (itm_op_t *)($$->obj); op->data.operand[0].itm_ptr = (itm_place2_t)($2); $$->ref[0] = obj_register(ITMC_OBJ_MAP, $2, NULL, 0, &(op->data.operand[0]), OBJ_REG_TAIL); } | op_if_else { TRACE_MESSAGE('y', ("op_unit: op_if_else\n")); $$ = $1; } | BREAK SC { TRACE_MESSAGE('y', ("break;\n")); $$ = op_self(ITM_OP_BREAK); } | RETURN SC { TRACE_MESSAGE('y', ("return;\n")); $$ = op_self(ITM_OP_RETURN); } | PRINTCHR expr SC { TRACE_MESSAGE('y', ("printchr expr;\n")); $$ = op_unary(ITM_OP_PRINTCHR, $2, sizeof (itm_expr_t)); } | PRINTHD expr SC { TRACE_MESSAGE('y', ("printchr expr;\n")); $$ = op_unary(ITM_OP_PRINTHD, $2, sizeof (itm_expr_t)); } | PRINTINT expr SC { TRACE_MESSAGE('y', ("printint expr;\n")); $$ = op_unary(ITM_OP_PRINTINT, $2, sizeof (itm_expr_t)); } ; op_if_else : ITM_IF PO expr PC CBO op_list CBC { itm_tbl_hdr_t *tbl_hdr; TRACE_MESSAGE('y', ("op_if_else: if (expr) {op_list}\n")); tbl_hdr = obj_table(ITM_TBL_OP, NULL, $6, sizeof (itm_op_t)); $$ = op_unit(ITM_OP_IF, $3, sizeof (itm_expr_t), tbl_hdr, tbl_hdr->size, NULL, 0); } | ITM_IF PO expr PC CBO op_list CBC ITM_ELSE op_if_else { itm_tbl_hdr_t *tbl_hdr1; itm_tbl_hdr_t *tbl_hdr2; TRACE_MESSAGE('y', ("op_if_else: " "if (expr) {op_list} else op_if_else\n")); tbl_hdr1 = obj_table(ITM_TBL_OP, NULL, $6, sizeof (itm_op_t)); tbl_hdr2 = obj_table(ITM_TBL_OP, NULL, $9, sizeof (itm_op_t)); $$ = op_unit(ITM_OP_IF_ELSE, $3, sizeof (itm_expr_t), tbl_hdr1, tbl_hdr1->size, tbl_hdr2, tbl_hdr2->size); } | ITM_IF PO expr PC CBO op_list CBC ITM_ELSE CBO op_list CBC { itm_tbl_hdr_t *tbl_hdr1; itm_tbl_hdr_t *tbl_hdr2; TRACE_MESSAGE('y', ("op_if_else: " "if (expr) {op_list} else {op_list}\n")); tbl_hdr1 = obj_table(ITM_TBL_OP, NULL, $6, sizeof (itm_op_t)); tbl_hdr2 = obj_table(ITM_TBL_OP, NULL, $10, sizeof (itm_op_t)); $$ = op_unit(ITM_OP_IF_ELSE, $3, sizeof (itm_expr_t), tbl_hdr1, tbl_hdr1->size, tbl_hdr2, tbl_hdr2->size); } ; name : NAME { TRACE_MESSAGE('y', ("name: size=%*s\n", yylval.data->size, NSPTR(yylval.data))); $$ = yylval.data; } ; itm_in : ITM_IN { TRACE_MESSAGE('y', ("in\n")); $$ = expr_self(ITM_EXPR_IN, NULL); } ; expr : PO expr PC { TRACE_MESSAGE('y', ("expr: (expr)\n")); $$ = $2; } | name { TRACE_MESSAGE('y', ("expr: NAME\n")); $$ = expr_self(ITM_EXPR_NAME, $1); } | HEXADECIMAL { TRACE_MESSAGE('y', ("expr: HEXADECIMAL\n")); $$ = expr_self(ITM_EXPR_SEQ, yylval.data); } | DECIMAL { TRACE_MESSAGE('y', ("expr: DECIMAL\n")); $$ = expr_self_num(ITM_EXPR_INT, yylval.num); } | itm_in SBO expr SBC { if (ITM_EXPR_INT == $3->type) { TRACE_MESSAGE('y', ("expr: in[%ld]\n", $3->data.itm_exnum)); $$ = expr_self_num(ITM_EXPR_IN_VECTOR_D, $3->data.itm_exnum); } else { TRACE_MESSAGE('y', ("expr: in[expr]\n")); $$ = expr_unary(ITM_EXPR_IN_VECTOR, $3); } } | ITM_OUTSIZE { TRACE_MESSAGE('y', ("expr: outsize\n")); $$ = expr_self_num(ITM_EXPR_OUT, 0); } | ITM_INSIZE { TRACE_MESSAGE('y', ("expr: inputsize\n")); $$ = expr_self_num(ITM_EXPR_IN_VECTOR_D, (size_t)-1); } | ITM_TRUE { TRACE_MESSAGE('y', ("expr: true\n")); $$ = expr_self_num(ITM_EXPR_TRUE, 1); } | ITM_FALSE { TRACE_MESSAGE('y', ("expr: false\n")); $$ = expr_self_num(ITM_EXPR_FALSE, 0); } | itm_in EQ expr { TRACE_MESSAGE('y', ("expr: in == expr\n")); $$ = expr_unary(ITM_EXPR_IN_EQ, $3); } | expr EQ itm_in { TRACE_MESSAGE('y', ("expr: expr == in\n")); $$ = expr_unary(ITM_EXPR_IN_EQ, $1); } | NOT expr { TRACE_MESSAGE('y', ("expr: ! expr\n")); if (ITM_EXPR_INT == $2->type) { $$ = expr_self_num(ITM_EXPR_INT, !($2->data.itm_exnum)); } else { $$ = expr_unary(ITM_EXPR_NOT, $2); } } | NEG expr { TRACE_MESSAGE('y', ("expr: ~ expr\n")); if (ITM_EXPR_INT == $2->type) { $$ = expr_self_num(ITM_EXPR_INT, ~($2->data.itm_exnum)); } else { $$ = expr_unary(ITM_EXPR_NEG, $2); } } | MINUS expr %prec MUL { TRACE_MESSAGE('y', ("expr: - expr\n")); if (ITM_EXPR_INT == $2->type) { $$ = expr_self_num(ITM_EXPR_INT, (-1) * ($2->data.itm_exnum)); } else { $$ = expr_unary(ITM_EXPR_UMINUS, $2); } } | expr PLUS expr { TRACE_MESSAGE('y', ("expr: expr + expr\n")); $$ = expr_binary(ITM_EXPR_PLUS, $1, $3); $1 = expr_seq_to_int($1); $3 = expr_seq_to_int($3); switch ($1->type) { case ITM_EXPR_INT: switch ($3->type) { case ITM_EXPR_INT: $$ = expr_binary2(ITM_EXPR_PLUS_D_D, $1, $3); break; case ITM_EXPR_REG: $$ = expr_binary2(ITM_EXPR_PLUS_D_R, $1, $3); break; case ITM_EXPR_IN_VECTOR_D: $$ = expr_binary2(ITM_EXPR_PLUS_D_INVD, $1, $3); break; default: $$ = expr_binary2(ITM_EXPR_PLUS_D_E, $1, $3); break; } break; case ITM_EXPR_REG: switch ($3->type) { case ITM_EXPR_INT: $$ = expr_binary2(ITM_EXPR_PLUS_R_D, $1, $3); break; case ITM_EXPR_REG: $$ = expr_binary2(ITM_EXPR_PLUS_R_R, $1, $3); break; case ITM_EXPR_IN_VECTOR_D: $$ = expr_binary2(ITM_EXPR_PLUS_R_INVD, $1, $3); break; default: $$ = expr_binary2(ITM_EXPR_PLUS_R_E, $1, $3); break; } break; case ITM_EXPR_IN_VECTOR_D: switch ($3->type) { case ITM_EXPR_INT: $$ = expr_binary2(ITM_EXPR_PLUS_INVD_D, $1, $3); break; case ITM_EXPR_REG: $$ = expr_binary2(ITM_EXPR_PLUS_INVD_R, $1, $3); break; case ITM_EXPR_IN_VECTOR_D: $$ = expr_binary2(ITM_EXPR_PLUS_INVD_INVD, $1, $3); break; default: $$ = expr_binary2(ITM_EXPR_PLUS_INVD_E, $1, $3); break; } break; default: switch ($3->type) { case ITM_EXPR_INT: $$ = expr_binary2(ITM_EXPR_PLUS_E_D, $1, $3); break; case ITM_EXPR_REG: $$ = expr_binary2(ITM_EXPR_PLUS_E_R, $1, $3); break; case ITM_EXPR_IN_VECTOR_D: $$ = expr_binary2(ITM_EXPR_PLUS_E_INVD, $1, $3); break; default: $$ = expr_binary2(ITM_EXPR_PLUS, $1, $3); break; } break; } } | expr MINUS expr { TRACE_MESSAGE('y', ("expr: expr - expr\n")); $$ = expr_binary(ITM_EXPR_MINUS, $1, $3); $1 = expr_seq_to_int($1); $3 = expr_seq_to_int($3); switch ($1->type) { case ITM_EXPR_INT: switch ($3->type) { case ITM_EXPR_INT: $$ = expr_binary2(ITM_EXPR_MINUS_D_D, $1, $3); break; case ITM_EXPR_REG: $$ = expr_binary2(ITM_EXPR_MINUS_D_R, $1, $3); break; case ITM_EXPR_IN_VECTOR_D: $$ = expr_binary2(ITM_EXPR_MINUS_D_INVD, $1, $3); break; default: $$ = expr_binary2(ITM_EXPR_MINUS_D_E, $1, $3); break; } break; case ITM_EXPR_REG: switch ($3->type) { case ITM_EXPR_INT: $$ = expr_binary2(ITM_EXPR_MINUS_R_D, $1, $3); break; case ITM_EXPR_REG: $$ = expr_binary2(ITM_EXPR_MINUS_R_R, $1, $3); break; case ITM_EXPR_IN_VECTOR_D: $$ = expr_binary2(ITM_EXPR_MINUS_R_INVD, $1, $3); break; default: $$ = expr_binary2(ITM_EXPR_MINUS_R_E, $1, $3); break; } break; case ITM_EXPR_IN_VECTOR_D: switch ($3->type) { case ITM_EXPR_INT: $$ = expr_binary2(ITM_EXPR_MINUS_INVD_D, $1, $3); break; case ITM_EXPR_REG: $$ = expr_binary2(ITM_EXPR_MINUS_INVD_R, $1, $3); break; case ITM_EXPR_IN_VECTOR_D: $$ = expr_binary2(ITM_EXPR_MINUS_INVD_INVD, $1, $3); break; default: $$ = expr_binary2(ITM_EXPR_MINUS_INVD_E, $1, $3); break; } break; default: switch ($3->type) { case ITM_EXPR_INT: $$ = expr_binary2(ITM_EXPR_MINUS_E_D, $1, $3); break; case ITM_EXPR_REG: $$ = expr_binary2(ITM_EXPR_MINUS_E_R, $1, $3); break; case ITM_EXPR_IN_VECTOR_D: $$ = expr_binary2(ITM_EXPR_MINUS_E_INVD, $1, $3); break; default: $$ = expr_binary2(ITM_EXPR_MINUS, $1, $3); break; } break; } } | expr MUL expr { TRACE_MESSAGE('y', ("expr: expr *expr\n")); $$ = expr_binary(ITM_EXPR_MUL, $1, $3); $1 = expr_seq_to_int($1); $3 = expr_seq_to_int($3); switch ($1->type) { case ITM_EXPR_INT: switch ($3->type) { case ITM_EXPR_INT: $$ = expr_binary2(ITM_EXPR_MUL_D_D, $1, $3); break; case ITM_EXPR_REG: $$ = expr_binary2(ITM_EXPR_MUL_D_R, $1, $3); break; case ITM_EXPR_IN_VECTOR_D: $$ = expr_binary2(ITM_EXPR_MUL_D_INVD, $1, $3); break; default: $$ = expr_binary2(ITM_EXPR_MUL_D_E, $1, $3); break; } break; case ITM_EXPR_REG: switch ($3->type) { case ITM_EXPR_INT: $$ = expr_binary2(ITM_EXPR_MUL_R_D, $1, $3); break; case ITM_EXPR_REG: $$ = expr_binary2(ITM_EXPR_MUL_R_R, $1, $3); break; case ITM_EXPR_IN_VECTOR_D: $$ = expr_binary2(ITM_EXPR_MUL_R_INVD, $1, $3); break; default: $$ = expr_binary2(ITM_EXPR_MUL_R_E, $1, $3); break; } break; case ITM_EXPR_IN_VECTOR_D: switch ($3->type) { case ITM_EXPR_INT: $$ = expr_binary2(ITM_EXPR_MUL_INVD_D, $1, $3); break; case ITM_EXPR_REG: $$ = expr_binary2(ITM_EXPR_MUL_INVD_R, $1, $3); break; case ITM_EXPR_IN_VECTOR_D: $$ = expr_binary2(ITM_EXPR_MUL_INVD_INVD, $1, $3); break; default: $$ = expr_binary2(ITM_EXPR_MUL_INVD_E, $1, $3); break; } break; default: switch ($3->type) { case ITM_EXPR_INT: $$ = expr_binary2(ITM_EXPR_MUL_E_D, $1, $3); break; case ITM_EXPR_REG: $$ = expr_binary2(ITM_EXPR_MUL_E_R, $1, $3); break; case ITM_EXPR_IN_VECTOR_D: $$ = expr_binary2(ITM_EXPR_MUL_E_INVD, $1, $3); break; default: $$ = expr_binary2(ITM_EXPR_MUL, $1, $3); break; } break; } } | expr DIV expr { TRACE_MESSAGE('y', ("expr: expr / expr\n")); $$ = expr_binary(ITM_EXPR_DIV, $1, $3); $1 = expr_seq_to_int($1); $3 = expr_seq_to_int($3); switch ($1->type) { case ITM_EXPR_INT: switch ($3->type) { case ITM_EXPR_INT: $$ = expr_binary2(ITM_EXPR_DIV_D_D, $1, $3); break; case ITM_EXPR_REG: $$ = expr_binary2(ITM_EXPR_DIV_D_R, $1, $3); break; case ITM_EXPR_IN_VECTOR_D: $$ = expr_binary2(ITM_EXPR_DIV_D_INVD, $1, $3); break; default: $$ = expr_binary2(ITM_EXPR_DIV_D_E, $1, $3); break; } break; case ITM_EXPR_REG: switch ($3->type) { case ITM_EXPR_INT: $$ = expr_binary2(ITM_EXPR_DIV_R_D, $1, $3); break; case ITM_EXPR_REG: $$ = expr_binary2(ITM_EXPR_DIV_R_R, $1, $3); break; case ITM_EXPR_IN_VECTOR_D: $$ = expr_binary2(ITM_EXPR_DIV_R_INVD, $1, $3); break; default: $$ = expr_binary2(ITM_EXPR_DIV_R_E, $1, $3); break; } break; case ITM_EXPR_IN_VECTOR_D: switch ($3->type) { case ITM_EXPR_INT: $$ = expr_binary2(ITM_EXPR_DIV_INVD_D, $1, $3); break; case ITM_EXPR_REG: $$ = expr_binary2(ITM_EXPR_DIV_INVD_R, $1, $3); break; case ITM_EXPR_IN_VECTOR_D: $$ = expr_binary2(ITM_EXPR_DIV_INVD_INVD, $1, $3); break; default: $$ = expr_binary2(ITM_EXPR_DIV_INVD_E, $1, $3); break; } break; default: switch ($3->type) { case ITM_EXPR_INT: $$ = expr_binary2(ITM_EXPR_DIV_E_D, $1, $3); break; case ITM_EXPR_REG: $$ = expr_binary2(ITM_EXPR_DIV_E_R, $1, $3); break; case ITM_EXPR_IN_VECTOR_D: $$ = expr_binary2(ITM_EXPR_DIV_E_INVD, $1, $3); break; default: $$ = expr_binary2(ITM_EXPR_DIV, $1, $3); break; } break; } } | expr MOD expr { TRACE_MESSAGE('y', ("expr: expr % expr\n")); $$ = expr_binary(ITM_EXPR_MOD, $1, $3); $1 = expr_seq_to_int($1); $3 = expr_seq_to_int($3); switch ($1->type) { case ITM_EXPR_INT: switch ($3->type) { case ITM_EXPR_INT: $$ = expr_binary2(ITM_EXPR_MOD_D_D, $1, $3); break; case ITM_EXPR_REG: $$ = expr_binary2(ITM_EXPR_MOD_D_R, $1, $3); break; case ITM_EXPR_IN_VECTOR_D: $$ = expr_binary2(ITM_EXPR_MOD_D_INVD, $1, $3); break; default: $$ = expr_binary2(ITM_EXPR_MOD_D_E, $1, $3); break; } break; case ITM_EXPR_REG: switch ($3->type) { case ITM_EXPR_INT: $$ = expr_binary2(ITM_EXPR_MOD_R_D, $1, $3); break; case ITM_EXPR_REG: $$ = expr_binary2(ITM_EXPR_MOD_R_R, $1, $3); break; case ITM_EXPR_IN_VECTOR_D: $$ = expr_binary2(ITM_EXPR_MOD_R_INVD, $1, $3); break; default: $$ = expr_binary2(ITM_EXPR_MOD_R_E, $1, $3); break; } break; case ITM_EXPR_IN_VECTOR_D: switch ($3->type) { case ITM_EXPR_INT: $$ = expr_binary2(ITM_EXPR_MOD_INVD_D, $1, $3); break; case ITM_EXPR_REG: $$ = expr_binary2(ITM_EXPR_MOD_INVD_R, $1, $3); break; case ITM_EXPR_IN_VECTOR_D: $$ = expr_binary2(ITM_EXPR_MOD_INVD_INVD, $1, $3); break; default: $$ = expr_binary2(ITM_EXPR_MOD_INVD_E, $1, $3); break; } break; default: switch ($3->type) { case ITM_EXPR_INT: $$ = expr_binary2(ITM_EXPR_MOD_E_D, $1, $3); break; case ITM_EXPR_REG: $$ = expr_binary2(ITM_EXPR_MOD_E_R, $1, $3); break; case ITM_EXPR_IN_VECTOR_D: $$ = expr_binary2(ITM_EXPR_MOD_E_INVD, $1, $3); break; default: $$ = expr_binary2(ITM_EXPR_MOD, $1, $3); break; } break; } } | expr SHL expr { TRACE_MESSAGE('y', ("expr: expr << expr\n")); $$ = expr_binary(ITM_EXPR_SHIFT_L, $1, $3); $1 = expr_seq_to_int($1); $3 = expr_seq_to_int($3); switch ($1->type) { case ITM_EXPR_INT: switch ($3->type) { case ITM_EXPR_INT: $$ = expr_binary2(ITM_EXPR_SHIFT_L_D_D, $1, $3); break; case ITM_EXPR_REG: $$ = expr_binary2(ITM_EXPR_SHIFT_L_D_R, $1, $3); break; case ITM_EXPR_IN_VECTOR_D: $$ = expr_binary2(ITM_EXPR_SHIFT_L_D_INVD, $1, $3); break; default: $$ = expr_binary2(ITM_EXPR_SHIFT_L_D_E, $1, $3); break; } break; case ITM_EXPR_REG: switch ($3->type) { case ITM_EXPR_INT: $$ = expr_binary2(ITM_EXPR_SHIFT_L_R_D, $1, $3); break; case ITM_EXPR_REG: $$ = expr_binary2(ITM_EXPR_SHIFT_L_R_R, $1, $3); break; case ITM_EXPR_IN_VECTOR_D: $$ = expr_binary2(ITM_EXPR_SHIFT_L_R_INVD, $1, $3); break; default: $$ = expr_binary2(ITM_EXPR_SHIFT_L_R_E, $1, $3); break; } break; case ITM_EXPR_IN_VECTOR_D: switch ($3->type) { case ITM_EXPR_INT: $$ = expr_binary2(ITM_EXPR_SHIFT_L_INVD_D, $1, $3); break; case ITM_EXPR_REG: $$ = expr_binary2(ITM_EXPR_SHIFT_L_INVD_R, $1, $3); break; case ITM_EXPR_IN_VECTOR_D: $$ = expr_binary2(ITM_EXPR_SHIFT_L_INVD_INVD, $1, $3); break; default: $$ = expr_binary2(ITM_EXPR_SHIFT_L_INVD_E, $1, $3); break; } break; default: switch ($3->type) { case ITM_EXPR_INT: $$ = expr_binary2(ITM_EXPR_SHIFT_L_E_D, $1, $3); break; case ITM_EXPR_REG: $$ = expr_binary2(ITM_EXPR_SHIFT_L_E_R, $1, $3); break; case ITM_EXPR_IN_VECTOR_D: $$ = expr_binary2(ITM_EXPR_SHIFT_L_E_INVD, $1, $3); break; default: $$ = expr_binary2(ITM_EXPR_SHIFT_L, $1, $3); break; } break; } } | expr SHR expr { TRACE_MESSAGE('y', ("expr: expr >> expr\n")); $$ = expr_binary(ITM_EXPR_SHIFT_R, $1, $3); $1 = expr_seq_to_int($1); $3 = expr_seq_to_int($3); switch ($1->type) { case ITM_EXPR_INT: switch ($3->type) { case ITM_EXPR_INT: $$ = expr_binary2(ITM_EXPR_SHIFT_R_D_D, $1, $3); break; case ITM_EXPR_REG: $$ = expr_binary2(ITM_EXPR_SHIFT_R_D_R, $1, $3); break; case ITM_EXPR_IN_VECTOR_D: $$ = expr_binary2(ITM_EXPR_SHIFT_R_D_INVD, $1, $3); break; default: $$ = expr_binary2(ITM_EXPR_SHIFT_R_D_E, $1, $3); break; } break; case ITM_EXPR_REG: switch ($3->type) { case ITM_EXPR_INT: $$ = expr_binary2(ITM_EXPR_SHIFT_R_R_D, $1, $3); break; case ITM_EXPR_REG: $$ = expr_binary2(ITM_EXPR_SHIFT_R_R_R, $1, $3); break; case ITM_EXPR_IN_VECTOR_D: $$ = expr_binary2(ITM_EXPR_SHIFT_R_R_INVD, $1, $3); break; default: $$ = expr_binary2(ITM_EXPR_SHIFT_R_R_E, $1, $3); break; } break; case ITM_EXPR_IN_VECTOR_D: switch ($3->type) { case ITM_EXPR_INT: $$ = expr_binary2(ITM_EXPR_SHIFT_R_INVD_D, $1, $3); break; case ITM_EXPR_REG: $$ = expr_binary2(ITM_EXPR_SHIFT_R_INVD_R, $1, $3); break; case ITM_EXPR_IN_VECTOR_D: $$ = expr_binary2(ITM_EXPR_SHIFT_R_INVD_INVD, $1, $3); break; default: $$ = expr_binary2(ITM_EXPR_SHIFT_R_INVD_E, $1, $3); break; } break; default: switch ($3->type) { case ITM_EXPR_INT: $$ = expr_binary2(ITM_EXPR_SHIFT_R_E_D, $1, $3); break; case ITM_EXPR_REG: $$ = expr_binary2(ITM_EXPR_SHIFT_R_E_R, $1, $3); break; case ITM_EXPR_IN_VECTOR_D: $$ = expr_binary2(ITM_EXPR_SHIFT_R_E_INVD, $1, $3); break; default: $$ = expr_binary2(ITM_EXPR_SHIFT_R, $1, $3); break; } break; } } | expr OR expr { TRACE_MESSAGE('y', ("expr: expr | expr\n")); $$ = expr_binary(ITM_EXPR_OR, $1, $3); $1 = expr_seq_to_int($1); $3 = expr_seq_to_int($3); switch ($1->type) { case ITM_EXPR_INT: switch ($3->type) { case ITM_EXPR_INT: $$ = expr_binary2(ITM_EXPR_OR_D_D, $1, $3); break; case ITM_EXPR_REG: $$ = expr_binary2(ITM_EXPR_OR_D_R, $1, $3); break; case ITM_EXPR_IN_VECTOR_D: $$ = expr_binary2(ITM_EXPR_OR_D_INVD, $1, $3); break; default: $$ = expr_binary2(ITM_EXPR_OR_D_E, $1, $3); break; } break; case ITM_EXPR_REG: switch ($3->type) { case ITM_EXPR_INT: $$ = expr_binary2(ITM_EXPR_OR_R_D, $1, $3); break; case ITM_EXPR_REG: $$ = expr_binary2(ITM_EXPR_OR_R_R, $1, $3); break; case ITM_EXPR_IN_VECTOR_D: $$ = expr_binary2(ITM_EXPR_OR_R_INVD, $1, $3); break; default: $$ = expr_binary2(ITM_EXPR_OR_R_E, $1, $3); break; } break; case ITM_EXPR_IN_VECTOR_D: switch ($3->type) { case ITM_EXPR_INT: $$ = expr_binary2(ITM_EXPR_OR_INVD_D, $1, $3); break; case ITM_EXPR_REG: $$ = expr_binary2(ITM_EXPR_OR_INVD_R, $1, $3); break; case ITM_EXPR_IN_VECTOR_D: $$ = expr_binary2(ITM_EXPR_OR_INVD_INVD, $1, $3); break; default: $$ = expr_binary2(ITM_EXPR_OR_INVD_E, $1, $3); break; } break; default: switch ($3->type) { case ITM_EXPR_INT: $$ = expr_binary2(ITM_EXPR_OR_E_D, $1, $3); break; case ITM_EXPR_REG: $$ = expr_binary2(ITM_EXPR_OR_E_R, $1, $3); break; case ITM_EXPR_IN_VECTOR_D: $$ = expr_binary2(ITM_EXPR_OR_E_INVD, $1, $3); break; default: $$ = expr_binary2(ITM_EXPR_OR, $1, $3); break; } break; } } | expr XOR expr { TRACE_MESSAGE('y', ("expr: expr ^ expr\n")); $$ = expr_binary(ITM_EXPR_XOR, $1, $3); $1 = expr_seq_to_int($1); $3 = expr_seq_to_int($3); switch ($1->type) { case ITM_EXPR_INT: switch ($3->type) { case ITM_EXPR_INT: $$ = expr_binary2(ITM_EXPR_XOR_D_D, $1, $3); break; case ITM_EXPR_REG: $$ = expr_binary2(ITM_EXPR_XOR_D_R, $1, $3); break; case ITM_EXPR_IN_VECTOR_D: $$ = expr_binary2(ITM_EXPR_XOR_D_INVD, $1, $3); break; default: $$ = expr_binary2(ITM_EXPR_XOR_D_E, $1, $3); break; } break; case ITM_EXPR_REG: switch ($3->type) { case ITM_EXPR_INT: $$ = expr_binary2(ITM_EXPR_XOR_R_D, $1, $3); break; case ITM_EXPR_REG: $$ = expr_binary2(ITM_EXPR_XOR_R_R, $1, $3); break; case ITM_EXPR_IN_VECTOR_D: $$ = expr_binary2(ITM_EXPR_XOR_R_INVD, $1, $3); break; default: $$ = expr_binary2(ITM_EXPR_XOR_R_E, $1, $3); break; } break; case ITM_EXPR_IN_VECTOR_D: switch ($3->type) { case ITM_EXPR_INT: $$ = expr_binary2(ITM_EXPR_XOR_INVD_D, $1, $3); break; case ITM_EXPR_REG: $$ = expr_binary2(ITM_EXPR_XOR_INVD_R, $1, $3); break; case ITM_EXPR_IN_VECTOR_D: $$ = expr_binary2(ITM_EXPR_XOR_INVD_INVD, $1, $3); break; default: $$ = expr_binary2(ITM_EXPR_XOR_INVD_E, $1, $3); break; } break; default: switch ($3->type) { case ITM_EXPR_INT: $$ = expr_binary2(ITM_EXPR_XOR_E_D, $1, $3); break; case ITM_EXPR_REG: $$ = expr_binary2(ITM_EXPR_XOR_E_R, $1, $3); break; case ITM_EXPR_IN_VECTOR_D: $$ = expr_binary2(ITM_EXPR_XOR_E_INVD, $1, $3); break; default: $$ = expr_binary2(ITM_EXPR_XOR, $1, $3); break; } break; } } | expr AND expr { TRACE_MESSAGE('y', ("expr: expr & expr\n")); $$ = expr_binary(ITM_EXPR_AND, $1, $3); $1 = expr_seq_to_int($1); $3 = expr_seq_to_int($3); switch ($1->type) { case ITM_EXPR_INT: switch ($3->type) { case ITM_EXPR_INT: $$ = expr_binary2(ITM_EXPR_AND_D_D, $1, $3); break; case ITM_EXPR_REG: $$ = expr_binary2(ITM_EXPR_AND_D_R, $1, $3); break; case ITM_EXPR_IN_VECTOR_D: $$ = expr_binary2(ITM_EXPR_AND_D_INVD, $1, $3); break; default: $$ = expr_binary2(ITM_EXPR_AND_D_E, $1, $3); break; } break; case ITM_EXPR_REG: switch ($3->type) { case ITM_EXPR_INT: $$ = expr_binary2(ITM_EXPR_AND_R_D, $1, $3); break; case ITM_EXPR_REG: $$ = expr_binary2(ITM_EXPR_AND_R_R, $1, $3); break; case ITM_EXPR_IN_VECTOR_D: $$ = expr_binary2(ITM_EXPR_AND_R_INVD, $1, $3); break; default: $$ = expr_binary2(ITM_EXPR_AND_R_E, $1, $3); break; } break; case ITM_EXPR_IN_VECTOR_D: switch ($3->type) { case ITM_EXPR_INT: $$ = expr_binary2(ITM_EXPR_AND_INVD_D, $1, $3); break; case ITM_EXPR_REG: $$ = expr_binary2(ITM_EXPR_AND_INVD_R, $1, $3); break; case ITM_EXPR_IN_VECTOR_D: $$ = expr_binary2(ITM_EXPR_AND_INVD_INVD, $1, $3); break; default: $$ = expr_binary2(ITM_EXPR_AND_INVD_E, $1, $3); break; } break; default: switch ($3->type) { case ITM_EXPR_INT: $$ = expr_binary2(ITM_EXPR_AND_E_D, $1, $3); break; case ITM_EXPR_REG: $$ = expr_binary2(ITM_EXPR_AND_E_R, $1, $3); break; case ITM_EXPR_IN_VECTOR_D: $$ = expr_binary2(ITM_EXPR_AND_E_INVD, $1, $3); break; default: $$ = expr_binary2(ITM_EXPR_AND, $1, $3); break; } break; } } | expr EQ expr { TRACE_MESSAGE('y', ("expr: expr == expr\n")); $$ = expr_binary(ITM_EXPR_EQ, $1, $3); $1 = expr_seq_to_int($1); $3 = expr_seq_to_int($3); switch ($1->type) { case ITM_EXPR_INT: switch ($3->type) { case ITM_EXPR_INT: $$ = expr_binary2(ITM_EXPR_EQ_D_D, $1, $3); break; case ITM_EXPR_REG: $$ = expr_binary2(ITM_EXPR_EQ_D_R, $1, $3); break; case ITM_EXPR_IN_VECTOR_D: $$ = expr_binary2(ITM_EXPR_EQ_D_INVD, $1, $3); break; default: $$ = expr_binary2(ITM_EXPR_EQ_D_E, $1, $3); break; } break; case ITM_EXPR_REG: switch ($3->type) { case ITM_EXPR_INT: $$ = expr_binary2(ITM_EXPR_EQ_R_D, $1, $3); break; case ITM_EXPR_REG: $$ = expr_binary2(ITM_EXPR_EQ_R_R, $1, $3); break; case ITM_EXPR_IN_VECTOR_D: $$ = expr_binary2(ITM_EXPR_EQ_R_INVD, $1, $3); break; default: $$ = expr_binary2(ITM_EXPR_EQ_R_E, $1, $3); break; } break; case ITM_EXPR_IN_VECTOR_D: switch ($3->type) { case ITM_EXPR_INT: $$ = expr_binary2(ITM_EXPR_EQ_INVD_D, $1, $3); break; case ITM_EXPR_REG: $$ = expr_binary2(ITM_EXPR_EQ_INVD_R, $1, $3); break; case ITM_EXPR_IN_VECTOR_D: $$ = expr_binary2(ITM_EXPR_EQ_INVD_INVD, $1, $3); break; default: $$ = expr_binary2(ITM_EXPR_EQ_INVD_E, $1, $3); break; } break; default: switch ($3->type) { case ITM_EXPR_INT: $$ = expr_binary2(ITM_EXPR_EQ_E_D, $1, $3); break; case ITM_EXPR_REG: $$ = expr_binary2(ITM_EXPR_EQ_E_R, $1, $3); break; case ITM_EXPR_IN_VECTOR_D: $$ = expr_binary2(ITM_EXPR_EQ_E_INVD, $1, $3); break; default: $$ = expr_binary2(ITM_EXPR_EQ, $1, $3); break; } break; } } | expr NE expr { TRACE_MESSAGE('y', ("expr: expr != expr\n")); $$ = expr_binary(ITM_EXPR_NE, $1, $3); $1 = expr_seq_to_int($1); $3 = expr_seq_to_int($3); switch ($1->type) { case ITM_EXPR_INT: switch ($3->type) { case ITM_EXPR_INT: $$ = expr_binary2(ITM_EXPR_NE_D_D, $1, $3); break; case ITM_EXPR_REG: $$ = expr_binary2(ITM_EXPR_NE_D_R, $1, $3); break; case ITM_EXPR_IN_VECTOR_D: $$ = expr_binary2(ITM_EXPR_NE_D_INVD, $1, $3); break; default: $$ = expr_binary2(ITM_EXPR_NE_D_E, $1, $3); break; } break; case ITM_EXPR_REG: switch ($3->type) { case ITM_EXPR_INT: $$ = expr_binary2(ITM_EXPR_NE_R_D, $1, $3); break; case ITM_EXPR_REG: $$ = expr_binary2(ITM_EXPR_NE_R_R, $1, $3); break; case ITM_EXPR_IN_VECTOR_D: $$ = expr_binary2(ITM_EXPR_NE_R_INVD, $1, $3); break; default: $$ = expr_binary2(ITM_EXPR_NE_R_E, $1, $3); break; } break; case ITM_EXPR_IN_VECTOR_D: switch ($3->type) { case ITM_EXPR_INT: $$ = expr_binary2(ITM_EXPR_NE_INVD_D, $1, $3); break; case ITM_EXPR_REG: $$ = expr_binary2(ITM_EXPR_NE_INVD_R, $1, $3); break; case ITM_EXPR_IN_VECTOR_D: $$ = expr_binary2(ITM_EXPR_NE_INVD_INVD, $1, $3); break; default: $$ = expr_binary2(ITM_EXPR_NE_INVD_E, $1, $3); break; } break; default: switch ($3->type) { case ITM_EXPR_INT: $$ = expr_binary2(ITM_EXPR_NE_E_D, $1, $3); break; case ITM_EXPR_REG: $$ = expr_binary2(ITM_EXPR_NE_E_R, $1, $3); break; case ITM_EXPR_IN_VECTOR_D: $$ = expr_binary2(ITM_EXPR_NE_E_INVD, $1, $3); break; default: $$ = expr_binary2(ITM_EXPR_NE, $1, $3); break; } break; } } | expr GT expr { TRACE_MESSAGE('y', ("expr: expr > expr\n")); $$ = expr_binary(ITM_EXPR_GT, $1, $3); $1 = expr_seq_to_int($1); $3 = expr_seq_to_int($3); switch ($1->type) { case ITM_EXPR_INT: switch ($3->type) { case ITM_EXPR_INT: $$ = expr_binary2(ITM_EXPR_GT_D_D, $1, $3); break; case ITM_EXPR_REG: $$ = expr_binary2(ITM_EXPR_GT_D_R, $1, $3); break; case ITM_EXPR_IN_VECTOR_D: $$ = expr_binary2(ITM_EXPR_GT_D_INVD, $1, $3); break; default: $$ = expr_binary2(ITM_EXPR_GT_D_E, $1, $3); break; } break; case ITM_EXPR_REG: switch ($3->type) { case ITM_EXPR_INT: $$ = expr_binary2(ITM_EXPR_GT_R_D, $1, $3); break; case ITM_EXPR_REG: $$ = expr_binary2(ITM_EXPR_GT_R_R, $1, $3); break; case ITM_EXPR_IN_VECTOR_D: $$ = expr_binary2(ITM_EXPR_GT_R_INVD, $1, $3); break; default: $$ = expr_binary2(ITM_EXPR_GT_R_E, $1, $3); break; } break; case ITM_EXPR_IN_VECTOR_D: switch ($3->type) { case ITM_EXPR_INT: $$ = expr_binary2(ITM_EXPR_GT_INVD_D, $1, $3); break; case ITM_EXPR_REG: $$ = expr_binary2(ITM_EXPR_GT_INVD_R, $1, $3); break; case ITM_EXPR_IN_VECTOR_D: $$ = expr_binary2(ITM_EXPR_GT_INVD_INVD, $1, $3); break; default: $$ = expr_binary2(ITM_EXPR_GT_INVD_E, $1, $3); break; } break; default: switch ($3->type) { case ITM_EXPR_INT: $$ = expr_binary2(ITM_EXPR_GT_E_D, $1, $3); break; case ITM_EXPR_REG: $$ = expr_binary2(ITM_EXPR_GT_E_R, $1, $3); break; case ITM_EXPR_IN_VECTOR_D: $$ = expr_binary2(ITM_EXPR_GT_E_INVD, $1, $3); break; default: $$ = expr_binary2(ITM_EXPR_GT, $1, $3); break; } break; } } | expr GE expr { TRACE_MESSAGE('y', ("expr: expr >= expr\n")); $$ = expr_binary(ITM_EXPR_GE, $1, $3); $1 = expr_seq_to_int($1); $3 = expr_seq_to_int($3); switch ($1->type) { case ITM_EXPR_INT: switch ($3->type) { case ITM_EXPR_INT: $$ = expr_binary2(ITM_EXPR_GE_D_D, $1, $3); break; case ITM_EXPR_REG: $$ = expr_binary2(ITM_EXPR_GE_D_R, $1, $3); break; case ITM_EXPR_IN_VECTOR_D: $$ = expr_binary2(ITM_EXPR_GE_D_INVD, $1, $3); break; default: $$ = expr_binary2(ITM_EXPR_GE_D_E, $1, $3); break; } break; case ITM_EXPR_REG: switch ($3->type) { case ITM_EXPR_INT: $$ = expr_binary2(ITM_EXPR_GE_R_D, $1, $3); break; case ITM_EXPR_REG: $$ = expr_binary2(ITM_EXPR_GE_R_R, $1, $3); break; case ITM_EXPR_IN_VECTOR_D: $$ = expr_binary2(ITM_EXPR_GE_R_INVD, $1, $3); break; default: $$ = expr_binary2(ITM_EXPR_GE_R_E, $1, $3); break; } break; case ITM_EXPR_IN_VECTOR_D: switch ($3->type) { case ITM_EXPR_INT: $$ = expr_binary2(ITM_EXPR_GE_INVD_D, $1, $3); break; case ITM_EXPR_REG: $$ = expr_binary2(ITM_EXPR_GE_INVD_R, $1, $3); break; case ITM_EXPR_IN_VECTOR_D: $$ = expr_binary2(ITM_EXPR_GE_INVD_INVD, $1, $3); break; default: $$ = expr_binary2(ITM_EXPR_GE_INVD_E, $1, $3); break; } break; default: switch ($3->type) { case ITM_EXPR_INT: $$ = expr_binary2(ITM_EXPR_GE_E_D, $1, $3); break; case ITM_EXPR_REG: $$ = expr_binary2(ITM_EXPR_GE_E_R, $1, $3); break; case ITM_EXPR_IN_VECTOR_D: $$ = expr_binary2(ITM_EXPR_GE_E_INVD, $1, $3); break; default: $$ = expr_binary2(ITM_EXPR_GE, $1, $3); break; } break; } } | expr LT expr { TRACE_MESSAGE('y', ("expr: expr < expr\n")); $$ = expr_binary(ITM_EXPR_LT, $1, $3); $1 = expr_seq_to_int($1); $3 = expr_seq_to_int($3); switch ($1->type) { case ITM_EXPR_INT: switch ($3->type) { case ITM_EXPR_INT: $$ = expr_binary2(ITM_EXPR_LT_D_D, $1, $3); break; case ITM_EXPR_REG: $$ = expr_binary2(ITM_EXPR_LT_D_R, $1, $3); break; case ITM_EXPR_IN_VECTOR_D: $$ = expr_binary2(ITM_EXPR_LT_D_INVD, $1, $3); break; default: $$ = expr_binary2(ITM_EXPR_LT_D_E, $1, $3); break; } break; case ITM_EXPR_REG: switch ($3->type) { case ITM_EXPR_INT: $$ = expr_binary2(ITM_EXPR_LT_R_D, $1, $3); break; case ITM_EXPR_REG: $$ = expr_binary2(ITM_EXPR_LT_R_R, $1, $3); break; case ITM_EXPR_IN_VECTOR_D: $$ = expr_binary2(ITM_EXPR_LT_R_INVD, $1, $3); break; default: $$ = expr_binary2(ITM_EXPR_LT_R_E, $1, $3); break; } break; case ITM_EXPR_IN_VECTOR_D: switch ($3->type) { case ITM_EXPR_INT: $$ = expr_binary2(ITM_EXPR_LT_INVD_D, $1, $3); break; case ITM_EXPR_REG: $$ = expr_binary2(ITM_EXPR_LT_INVD_R, $1, $3); break; case ITM_EXPR_IN_VECTOR_D: $$ = expr_binary2(ITM_EXPR_LT_INVD_INVD, $1, $3); break; default: $$ = expr_binary2(ITM_EXPR_LT_INVD_E, $1, $3); break; } break; default: switch ($3->type) { case ITM_EXPR_INT: $$ = expr_binary2(ITM_EXPR_LT_E_D, $1, $3); break; case ITM_EXPR_REG: $$ = expr_binary2(ITM_EXPR_LT_E_R, $1, $3); break; case ITM_EXPR_IN_VECTOR_D: $$ = expr_binary2(ITM_EXPR_LT_E_INVD, $1, $3); break; default: $$ = expr_binary2(ITM_EXPR_LT, $1, $3); break; } break; } } | expr LE expr { TRACE_MESSAGE('y', ("expr: expr <= expr\n")); $$ = expr_binary(ITM_EXPR_LE, $1, $3); $1 = expr_seq_to_int($1); $3 = expr_seq_to_int($3); switch ($1->type) { case ITM_EXPR_INT: switch ($3->type) { case ITM_EXPR_INT: $$ = expr_binary2(ITM_EXPR_LE_D_D, $1, $3); break; case ITM_EXPR_REG: $$ = expr_binary2(ITM_EXPR_LE_D_R, $1, $3); break; case ITM_EXPR_IN_VECTOR_D: $$ = expr_binary2(ITM_EXPR_LE_D_INVD, $1, $3); break; default: $$ = expr_binary2(ITM_EXPR_LE_D_E, $1, $3); break; } break; case ITM_EXPR_REG: switch ($3->type) { case ITM_EXPR_INT: $$ = expr_binary2(ITM_EXPR_LE_R_D, $1, $3); break; case ITM_EXPR_REG: $$ = expr_binary2(ITM_EXPR_LE_R_R, $1, $3); break; case ITM_EXPR_IN_VECTOR_D: $$ = expr_binary2(ITM_EXPR_LE_R_INVD, $1, $3); break; default: $$ = expr_binary2(ITM_EXPR_LE_R_E, $1, $3); break; } break; case ITM_EXPR_IN_VECTOR_D: switch ($3->type) { case ITM_EXPR_INT: $$ = expr_binary2(ITM_EXPR_LE_INVD_D, $1, $3); break; case ITM_EXPR_REG: $$ = expr_binary2(ITM_EXPR_LE_INVD_R, $1, $3); break; case ITM_EXPR_IN_VECTOR_D: $$ = expr_binary2(ITM_EXPR_LE_INVD_INVD, $1, $3); break; default: $$ = expr_binary2(ITM_EXPR_LE_INVD_E, $1, $3); break; } break; default: switch ($3->type) { case ITM_EXPR_INT: $$ = expr_binary2(ITM_EXPR_LE_E_D, $1, $3); break; case ITM_EXPR_REG: $$ = expr_binary2(ITM_EXPR_LE_E_R, $1, $3); break; case ITM_EXPR_IN_VECTOR_D: $$ = expr_binary2(ITM_EXPR_LE_E_INVD, $1, $3); break; default: $$ = expr_binary2(ITM_EXPR_LE, $1, $3); break; } break; } } | name ASSIGN expr { TRACE_MESSAGE('y', ("expr: NAME = expr\n")); $$ = expr_assign(ITM_EXPR_ASSIGN, $1, $3); } | expr LOR expr { TRACE_MESSAGE('y', ("expr: expr || expr\n")); $$ = expr_binary(ITM_EXPR_LOR, $1, $3); } | expr LAND expr { TRACE_MESSAGE('y', ("expr: expr && expr\n")); $$ = expr_binary(ITM_EXPR_LAND, $1, $3); } ; %% /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright (c) 1999 by Sun Microsystems, Inc. * All rights reserved. * Copyright 2015 PALO, Richard. */ #include #include #include #include #include #include #include "iconv_tm.h" #include "itmcomp.h" #include "itm_util.h" #include "hash.h" #include "maptype.h" static size_t map_table_resultlen(itmc_map_t *); static int data_pair_compare(itmc_data_pair_t **, itmc_data_pair_t **); static long data_to_long(itm_data_t *); static itm_tbl_hdr_t *map_table_indexed_fixed(itmc_data_pair_t **, itm_size_t, itm_data_t *, long, itm_num_t); static itm_tbl_hdr_t *map_table_dense_encoding(itmc_data_pair_t **, itm_size_t, itm_data_t *, unsigned long, unsigned char *, unsigned char *, long, itm_num_t); static itm_tbl_hdr_t *map_table_lookup_fixed(itmc_data_pair_t **, itm_size_t, itm_data_t *, long, itm_size_t); static itm_tbl_hdr_t *map_table_hash(itmc_data_pair_t **, itm_size_t, itm_data_t *, long, long, itm_size_t, itm_num_t); static itm_tbl_hdr_t *map_table_lookup_var(); static void put_dense_encoding_default(char *, unsigned char *, unsigned char *, unsigned char *, long, long, long); static size_t map_table_resultlen(itmc_map_t *); static void map_range_adjust_byte_seq(unsigned char *, unsigned char *, long, itmc_data_pair_t *); static void map_range_make_result(char *, itm_size_t, itm_size_t, char *, itm_size_t); static size_t map_table_num_range(itmc_data_pair_t *); static itmc_map_type_t check_map_type(itmc_map_attr_t *); static itmc_name_t *name_lookup(itm_data_t *, itm_type_t); static itmc_name_t *name_refer(itm_data_t *, itm_type_t, itmc_ref_t *); static itmc_name_t *name_register(itm_data_t *, itm_type_t, itmc_ref_t *); static void op_hirarchy(itm_tbl_hdr_t *, itmc_obj_t *); static obj_array_t obj_list_to_array(itm_size_t, itmc_obj_t *, itm_size_t); void itm_def_process(itm_data_t *itm_name) { itm_hdr_t *itm_hdr; long len; TRACE_MESSAGE('y', ("itm_def_process\n")); itm_hdr = malloc_vital(sizeof (itm_hdr_t)); (void) memset(itm_hdr, 0, sizeof (itm_hdr_t)); if ((NULL != cmd_opt.interpreter) && (0 < (len = strlen(cmd_opt.interpreter)))) { itm_hdr->interpreter = *(str_to_data(len, cmd_opt.interpreter)); } if ((sizeof (itm_place_t)) < itm_hdr->interpreter.size) { (void) obj_register(ITMC_OBJ_STRING, NULL, (void *)itm_hdr->interpreter.place.itm_ptr, itm_hdr->interpreter.size, &(itm_hdr->interpreter.place), OBJ_REG_HEAD); } itm_hdr->type_id = *itm_name; if ((sizeof (itm_place_t)) < itm_hdr->type_id.size) { (void) obj_register(ITMC_OBJ_STRING, NULL, (void *)itm_hdr->type_id.place.itm_ptr, itm_hdr->type_id.size, &(itm_hdr->type_id.place), OBJ_REG_HEAD); } (void) assemble(itm_hdr); } itmc_obj_t * direction_unit( itmc_ref_t *cond, itm_data_t *cond_name, itmc_action_t *act, itm_data_t *act_name) { itmc_obj_t *du; itm_direc_t *direc; du = malloc_vital(sizeof (itmc_obj_t)); du->type = ITMC_OBJ_DIREC; du->name = NULL; du->obj = direc = malloc_vital(sizeof (itm_direc_t)); if (NULL != cond) { direc->condition.itm_ptr = (uintptr_t)NULL; cond->referencer = &(direc->condition); du->ref[0] = cond; } else if (NULL != cond_name) { direc->condition.itm_ptr = (itm_place2_t)(cond_name); du->ref[0] = obj_register(ITMC_OBJ_COND, cond_name, NULL, 0, &(direc->condition), OBJ_REG_TAIL); } else { direc->condition.itm_ptr = 0; du->ref[0] = NULL; } if (NULL != act_name) { direc->action.itm_ptr = (itm_place2_t)(act_name); du->ref[1] = obj_register(ITMC_OBJ_ACTION, act_name, NULL, 0, &(direc->action), OBJ_REG_TAIL); } else if (NULL != act && act->tbl_hdr != NULL) { direc->action.itm_ptr = (itm_place2_t)(act->tbl_hdr); du->ref[1] = obj_register(act->type, (itm_data_t *)(act->tbl_hdr->name.itm_ptr), act->tbl_hdr, act->tbl_hdr->size, &(direc->action), OBJ_REG_TAIL); } else { return (NULL); } du->ref[2] = NULL; return (du); } 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) { itm_tbl_hdr_t *tbl; obj_array_t obj_array; obj_array = obj_list_to_array(sizeof (itm_tbl_hdr_t), obj_list, obj_size); tbl = obj_array.obj; tbl->type = tbl_type; if (name) { #if !defined(_LP64) tbl->name.itm_pad = 0; #endif tbl->name.itm_ptr = (itm_place2_t)name; } else { #if !defined(_LP64) tbl->name.itm_pad = 0; #endif tbl->name.itm_ptr = (uintptr_t)NULL; } tbl->size = (sizeof (itm_tbl_hdr_t)) + (obj_array.num *obj_size); tbl->number = obj_array.num; if ((ITM_TBL_MASK&tbl->type) == ITM_TBL_OP) { op_hirarchy(tbl, obj_list); } return (tbl); } /* * */ static obj_array_t obj_list_to_array(itm_size_t hdr_size, itmc_obj_t *obj_list, itm_size_t size) { obj_array_t obj_array; itm_size_t offset; itmc_obj_t *ol; for (obj_array.num = 0, ol = obj_list; ol; obj_array.num += 1, ol = ol->next) { /* NOP */; } obj_array.obj = malloc_vital(hdr_size + (size * obj_array.num)); if (obj_array.num == 0) return (obj_array); for (offset = hdr_size, ol = obj_list; ol; offset += size, ol = ol->next) { (void) memcpy((char *)(obj_array.obj) + offset, ol->obj, size); if (ol->ref[0]) { ol->ref[0]->referencer = (void *)((char *)(ol->ref[0]->referencer) + ((char *)(obj_array.obj) - (char *)(ol->obj) + offset)); } if (ol->ref[1]) { ol->ref[1]->referencer = (void *)((char *)(ol->ref[1]->referencer) + ((char *)(obj_array.obj) - (char *)(ol->obj) + offset)); } if (ol->ref[2]) { ol->ref[2]->referencer = (void *)((char *)(ol->ref[2]->referencer) + ((char *)(obj_array.obj) - (char *)(ol->obj) + offset)); } } return (obj_array); } static void op_hirarchy(itm_tbl_hdr_t *optbl, itmc_obj_t *obj_list) { itm_op_outer_t *o; itm_op_inner_t *in; itmc_obj_t *ol; TRACE_MESSAGE('l', ("op_hirarchy (optbl=%x)\n", optbl)); o = malloc_vital(sizeof (itm_op_outer_t)); o->link = itm_op_outer; itm_op_outer = o; o->in = NULL; o->optbl = optbl; for (ol = obj_list; ol != NULL; ol = ol->next) { if ((ol->type == ITMC_OBJ_OP) && (((itm_op_t *)ol->obj)->type == ITM_OP_OPERATION)) { in = malloc_vital(sizeof (itm_op_inner_t)); in->in = o->in; o->in = in; TRACE_MESSAGE('L', ("o->in(%x) in->in(%x)\n", o->in, in->in)); in->ref = ol->ref[0]; } } #ifdef ENABLE_TRACE for (in = o->in; in != NULL; in = in->in) { TRACE_MESSAGE('L', ("o=%x in=%x in->in=%x\n", o, in, in->in)); TRACE_MESSAGE('L', ("o(table)%x->in(ref)=%x\n", o->optbl, in->ref)); } #endif } itmc_obj_t * obj_list_append(itmc_obj_t *obj_list, itmc_obj_t *obj) { if (0 == obj) { return (obj_list); } obj->next = NULL; obj->last = obj; if (obj_list) { obj_list->last->next = obj; obj_list->last = obj; return (obj_list); } else { return (obj); } } 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) { itmc_ref_t *refp; TRACE_MESSAGE('O', ("obj_register: %6ld %08p %08p %08ld %08p %ld\n", type, name, obj, size, ref, reg_place)); refp = malloc_vital(sizeof (itmc_ref_t)); refp->name = NULL; refp->referencee = obj; #if !defined(_LP64) refp->reloc.itm_pad = 0; #endif refp->reloc.itm_ptr = 0; refp->size = size; refp->referencer = ref; refp->next = NULL; if (NULL == obj) { /* reference to named object */ if (NULL == name) { if (0 == error_deferred) { /* should never happen */ itm_error( gettext("internal error: " "obj_register: (NULL == obj) " "&& (NULL == name)\n")); exit(ITMC_STATUS_SYS2); } return (NULL); } refp->name = name_refer(name, type, refp); return (refp); } else if ((NULL != name) && (0 < name->size)) { /* definition of named object */ refp->name = name_register(name, type, refp); } if ((ITMC_OBJ_FIRST <= type) && (type <= ITMC_OBJ_LAST)) { switch (reg_place) { case OBJ_REG_HEAD: refp->next = ref_first[type]; ref_first[type] = refp; if (NULL == ref_last[type]) { ref_last[type] = refp; } break; case OBJ_REG_TAIL: if (ref_first[type]) { ref_last[type]->next = refp; } else { ref_first[type] = refp; } ref_last[type] = refp; break; } } else { itm_error(gettext("obj_register: illegal object type\n")); exit(ITMC_STATUS_SYS2); } return (refp); } itm_tbl_hdr_t * range_table(itm_data_t *name, itmc_obj_t *obj_list) { itm_num_t num; itmc_obj_t *ol; itmc_data_pair_t *rp; itm_range_hdr_t *rh; itm_tbl_hdr_t *table; itm_size_t length = 0; itm_num_t i; char *p; itm_size_t table_size; /* count range, determine length */ for (num = 0, ol = obj_list; ol; ol = ol->next, num++) { rp = (itmc_data_pair_t *)(ol->obj); if (length == 0) { if (rp->data0.size == 0) { itm_error(gettext("between has null range\n")); error_deferred += 1; return (NULL); } length = rp->data0.size; } if ((rp->data0.size != length) || (rp->data1.size != length)) { itm_error(gettext( "length of source sequences must be the same\n")); error_deferred += 1; return (NULL); } } if (num == 0) { itm_error(gettext("between has no ranges\n")); error_deferred += 1; return (NULL); } table_size = ((sizeof (itm_tbl_hdr_t)) + (sizeof (itm_range_hdr_t)) + (length * num) * 2); table_size = ITMROUNDUP(table_size); table = malloc_vital(table_size); table->type = ITM_TBL_RANGE; if (NULL != name) table->name.itm_ptr = (itm_place2_t)name; table->size = table_size; table->number = num; rh = (itm_range_hdr_t *)(table + 1); rh->len = length; p = (char *)(rh + 1); for (ol = obj_list, i = 0; ol; ol = ol->next, i++) { rp = (itmc_data_pair_t *)(ol->obj); (void) memcpy(p, (NSPTR(&(rp->data0))), length); p += length; (void) memcpy(p, (NSPTR(&(rp->data1))), length); p += length; } return (table); } /* * escape sequence table for stateful code set sequence */ itm_tbl_hdr_t * escseq_table(itm_data_t *name, itmc_obj_t *obj_list) { itm_num_t num; itmc_obj_t *ol; itm_data_t *ep; itm_escapeseq_hdr_t *eh; itm_tbl_hdr_t *table; itm_size_t len_max = 0; itm_size_t len_min; itm_num_t i; itm_size_t table_size; ol = obj_list; len_min = ((itm_data_t *)(ol->obj))->size; for (num = 0; NULL != ol; ol = ol->next, num++) { ep = (itm_data_t *)(ol->obj); if (ep->size < len_min) len_min = ep->size; if (ep->size > len_max) len_max = ep->size; } if (num == 0) { itm_error(gettext ("escape sequence is defined without sequence\n")); error_deferred += 1; return (NULL); } else if (0 == len_min) { itm_error(gettext("null sequence\n")); error_deferred += 1; return (NULL); } table_size = ((sizeof (itm_tbl_hdr_t)) + (sizeof (itm_escapeseq_hdr_t)) + (sizeof (itm_data_t) * num)); table_size = ITMROUNDUP(table_size); table = malloc_vital(table_size); table->type = ITM_TBL_ESCAPESEQ; if (NULL != name) table->name.itm_ptr = (itm_place2_t)name; table->size = table_size; table->number = num; eh = (itm_escapeseq_hdr_t *)(table + 1); eh->len_max = len_max; eh->len_min = len_min; for (ol = obj_list, ep = (itm_data_t *)(eh + 1); ol != NULL; ol = ol->next, ep++) { *ep = *((itm_data_t *)(ol->obj)); if ((sizeof (itm_place_t)) < ep->size) { (void) obj_register(ITMC_OBJ_DATA, NULL, (void *)(ep->place.itm_ptr), ep->size, &(ep->place), OBJ_REG_TAIL); } } (void) qsort((itm_data_t *)(eh + 1), num, sizeof (itm_data_t), (int (*)(const void *, const void *))data_compare); for (i = 0, ep = (itm_data_t *)(eh + 1); i < num - 1; i++, ep++) { if (0 <= data_compare(ep, (ep + 1))) { itm_error( gettext( "same escape sequences are defined: " "0x%1$s 0x%2$s\n"), data_to_hexadecimal(ep), data_to_hexadecimal(ep + 1)); error_deferred += 1; return (NULL); } } return (table); } itm_tbl_hdr_t * map_table(itm_data_t *name, itmc_map_t *map_list, itmc_map_attr_t *attr) { itm_size_t num; itm_size_t num2; itmc_map_t *ml; itmc_data_pair_t **tpp; itm_tbl_hdr_t *table; long source_len = 0; long result_len = 0; long source_fixed_len = 1; long pass_through = 0; long default_count = 0; itm_data_t *default_data = NULL; long error_deferred_local = 0; unsigned long dense_encoded_map_ent; unsigned long simple_indexed_map_ent; itm_size_t source_start; itm_size_t source_end; unsigned long u; unsigned char *byte_seq_min; unsigned char *byte_seq_max; unsigned char *p; long i; itmc_map_type_t map_type = ITMC_MAP_UNKNOWN; itmc_map_name_type_t *map_name_type; long hash_factor; long result_len_specfied = 0; size_t j; long n; itmc_data_pair_t **dp1; itm_num_t error_count = 0; if (attr != NULL) { map_type = check_map_type(attr); } if (ITMC_MAP_UNKNOWN == map_type) { map_type = ITMC_MAP_AUTOMATIC; } hash_factor = ((NULL != attr) && (attr->hash_factor != 0)) ? attr->hash_factor : 200; map_name_type = cmd_opt.map_name_type; for (; map_name_type; map_name_type = map_name_type->next) { if ('\0' == *(map_name_type->name)) { map_type = map_name_type->type; hash_factor = map_name_type->hash_factor; break; } } map_name_type = cmd_opt.map_name_type; if ((NULL != name) && (NULL != cmd_opt.map_name_type)) { p = NSPTR(name); for (; map_name_type; map_name_type = map_name_type->next) { if (0 == strcmp(map_name_type->name, (char *)p)) { map_type = map_name_type->type; hash_factor = map_name_type->hash_factor; break; } } } if (NULL != attr) { if (MAXSEQUENCE < attr->resultlen) { itm_error( gettext("output_byte_length must be less than %1$d\n"), MAXSEQUENCE); error_deferred += 1; return (NULL); } result_len_specfied = attr->resultlen; } else { result_len_specfied = 0; } for (num = 0, ml = map_list; ml; ml = ml->next, num++) { /* default */ if (0 == ml->data_pair.data0.size) { if (0 == ml->data_pair.data1.size) { pass_through += 1; default_data = (itm_data_t *)(-1); } else { default_count += 1; default_data = &(ml->data_pair.data1); } --num; } else if (0 == ml->data_pair.data1.size) { /* error source sequence */ continue; } /* fixed length */ if ((0 < source_len) && (0 < ml->data_pair.data0.size) && (source_len != ml->data_pair.data0.size)) { source_fixed_len = 0; } /* maximum length */ if (source_len < ml->data_pair.data0.size) { source_len = ml->data_pair.data0.size; } if (result_len < ml->data_pair.data1.size) { result_len = ml->data_pair.data1.size; } /* map source has range */ if (0 < ml->data_pair.range.size) { if (ml->data_pair.range.size != ml->data_pair.data0.size) { itm_error( gettext("length of source range must be " "the same: 0x%1$s 0x%2$s\n"), data_to_hexadecimal(&(ml->data_pair.data0)), data_to_hexadecimal( &(ml->data_pair.range))); error_deferred += 1; return (NULL); } if (0 <= data_compare(&(ml->data_pair.data0), &((ml->data_pair.range)))) { itm_error( gettext("source range error: 0x%1$s 0x%2$s\n"), data_to_hexadecimal( &(ml->data_pair.data0)), data_to_hexadecimal( &(ml->data_pair.range))); error_deferred += 1; return (NULL); } j = map_table_resultlen(ml); if (result_len < j) { result_len = j; } } } if (num == 0) { itm_error( gettext("no mapping pair\n")); error_deferred += 1; return (NULL); } if (0 != result_len_specfied) { if (result_len > result_len_specfied) { itm_error( gettext("result value length is " "over specifed output_byte_length(%1$ld)\n"), result_len_specfied); error_deferred += 1; return (NULL); } result_len = result_len_specfied; } byte_seq_min = malloc_vital((sizeof (unsigned char)) * source_len); byte_seq_max = malloc_vital((sizeof (unsigned char)) * source_len); for (num = 0, ml = map_list; ml; ml = ml->next, num++) { if (0 == ml->data_pair.data0.size) { continue; } p = (unsigned char *)(NSPTR(&((ml->data_pair).data0))); for (i = 0; i < source_len; i++) { *(byte_seq_min + i) = *(p + i); *(byte_seq_max + i) = *(p + i); } break; } for (num = 0, ml = map_list; ml; ml = ml->next, num++) { if (0 == ml->data_pair.data0.size) { num--; continue; } if (ml->data_pair.range.size > 0) { map_range_adjust_byte_seq(byte_seq_min, byte_seq_max, source_len, &(ml->data_pair)); } else { p = (unsigned char *)(NSPTR(&((ml->data_pair).data0))); for (i = 0; i < source_len; i++) { if (*(p + i) < *(byte_seq_min + i)) { *(byte_seq_min + i) = *(p + i); } if (*(byte_seq_max + i) < *(p + i)) { *(byte_seq_max + i) = *(p + i); } } } } for (dense_encoded_map_ent = 1, i = 0; i < source_len; i++) { u = dense_encoded_map_ent; dense_encoded_map_ent *= (*(byte_seq_max + i) - *(byte_seq_min + i) + 1); if (dense_encoded_map_ent < u) { dense_encoded_map_ent = (ulong_t)(~0); break; } } #if defined(DEBUG) if (TRACE('m')) { int i; TRACE_MESSAGE('m', ("map_table: ent=%lu num=%lu ", dense_encoded_map_ent, num)); TRACE_MESSAGE('m', ("byte_seq_min=0x")); for (i = 0; i < source_len; i++) { TRACE_MESSAGE('m', ("%02x", *(byte_seq_min + i))); } TRACE_MESSAGE('m', (" byte_seq_max=0x")); for (i = 0; i < source_len; i++) { TRACE_MESSAGE('m', ("%02x", *(byte_seq_max + i))); } TRACE_MESSAGE('m', ("\n")); } #endif /* DEBUG */ tpp = malloc_vital((sizeof (itmc_data_pair_t *)) * num); for (num = 0, num2 = 0, ml = map_list; ml; ml = ml->next) { if (0 < ml->data_pair.data0.size) { itm_num_t range_num; *(tpp + num) = &(ml->data_pair); num++; range_num = 1; if (ml->data_pair.range.size > 0) { range_num += map_table_num_range(&(ml->data_pair)); } num2 += range_num; if (0 == ml->data_pair.data1.size) { /* specified error sequence */ error_count += range_num; } } } (void) qsort(tpp, num, sizeof (itmc_data_pair_t *), (int (*)(const void *, const void *))data_pair_compare); /* check if map_pair range and next map_pair are overrapped */ for (n = 0, dp1 = tpp; n < (num-1); n++, dp1++) { if (((*(dp1+0))->range.size != 0) && (0 <= data_compare(&((*(dp1+0))->range), &((*(dp1+1))->data0)))) { itm_error( gettext("ranges of source sequences " "overrapped: %1$s %2$s\n"), data_to_hexadecimal(&((*(dp1+0))->range)), data_to_hexadecimal(&((*(dp1+1))->data0))); error_deferred += 1; return (NULL); } } if (1 < default_count) { itm_error( gettext("default is specified %1$d times in a map\n"), default_count); error_deferred_local += 1; } if ((1 == default_count) && (!source_fixed_len)) { itm_error( gettext("default is specified," " but length of source data is not fixed\n")); error_deferred_local += 1; } if ((1 <= pass_through) && (source_len != result_len)) { itm_error( gettext("\"default no_change_copy\" is " "specified, but size does not match\n")); error_deferred_local += 1; } if (error_deferred_local) { error_deferred += error_deferred_local; return (NULL); } if (source_fixed_len) { source_start = data_to_long(&((*(tpp + 0))->data0)); source_end = data_to_long(&((*(tpp + num - 1))->data0)); if (0 < (*(tpp + num - 1))->range.size) { source_end = data_to_long(&((*(tpp + num - 1))->range)); } simple_indexed_map_ent = source_end - source_start + 1; TRACE_MESSAGE('m', ("map_table: simple_indexed_map_ent=%lu\n", simple_indexed_map_ent)); switch (map_type) { case ITMC_MAP_AUTOMATIC: if ((source_len <= 2) && (((ulong_t)(~0) == dense_encoded_map_ent) || (simple_indexed_map_ent < (dense_encoded_map_ent * 2)))) { /* * for small source sequence, * if dense table is not so large * compared with simple table, * use simple. */ map_type = ITMC_MAP_SIMPLE_INDEX; } else if (cmd_opt.large_table) { if ((sizeof (long)) < source_len) { itm_error( gettext("length of source is too long " "for large table: %ld\n"), source_len); error_deferred += 1; return (NULL); } map_type = ITMC_MAP_SIMPLE_INDEX; } else if (((ulong_t)(~0) == dense_encoded_map_ent) || ((0xffff < dense_encoded_map_ent) && ((num2 * 8) < dense_encoded_map_ent))) { /* * if dense can be used and not too large * ( less than (hash table entry * 8), * use dense. */ map_type = ITMC_MAP_SIMPLE_HASH; } else { map_type = ITMC_MAP_DENSE_ENCODING; } break; case ITMC_MAP_SIMPLE_INDEX: if ((sizeof (long)) < source_len) { itm_error( gettext("length of source is too long " "for index lookup: %ld\n"), source_len); error_deferred += 1; return (NULL); } break; case ITMC_MAP_SIMPLE_HASH: for (i = 2, u = 256; i < (sizeof (long)); i++) { u *= 256; } if (u < num2) { itm_error( gettext("map is too large for hashing: %lu\n"), num2); error_deferred += 1; return (NULL); } break; case ITMC_MAP_DENSE_ENCODING: for (i = 2, u = 256; i < (sizeof (long)); i++) { u *= 256; } if (u < dense_encoded_map_ent) { itm_error( gettext( "map is too large for dense encoding: " "%lu\n"), dense_encoded_map_ent); error_deferred += 1; return (NULL); } break; case ITMC_MAP_BINARY_SEARCH: for (i = 2, u = 256; i < (sizeof (long)); i++) { u *= 256; } if (u < num2) { itm_error( gettext("length of source is too long for " "binary search: %ld\n"), source_len); error_deferred += 1; return (NULL); } break; default: break; } switch (map_type) { case ITMC_MAP_SIMPLE_INDEX: table = map_table_indexed_fixed( tpp, num, default_data, result_len, error_count); break; case ITMC_MAP_SIMPLE_HASH: table = map_table_hash(tpp, num, default_data, hash_factor, result_len, num2, error_count); break; case ITMC_MAP_DENSE_ENCODING: table = map_table_dense_encoding(tpp, num, default_data, dense_encoded_map_ent, byte_seq_min, byte_seq_max, result_len, error_count); break; case ITMC_MAP_BINARY_SEARCH: table = map_table_lookup_fixed(tpp, num, default_data, result_len, num2); break; } } else { table = map_table_lookup_var(); } if ((NULL != name) && (NULL != table)) { table->name.itm_ptr = (itm_place2_t)name; } return (table); } static itmc_map_type_t check_map_type(itmc_map_attr_t *attr) { int i; if (NULL == attr->type) { return (0); } for (i = 0; NULL != map_type_name[i].name; i++) { if (0 == strncmp(((char *)&(attr->type->place)), map_type_name[i].name, attr->type->size)) { return (map_type_name[i].type); } } return (0); } 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) { itm_tbl_hdr_t *header; itm_map_idx_fix_hdr_t *sub_hdr; char *table; char *error_table; itm_size_t source_start; itm_size_t source_end; itm_size_t entry_num; itm_size_t table_size; itm_size_t j; itm_size_t i; itm_size_t k; char *p; itm_data_t *source; TRACE_MESSAGE('m', ("map_table_range : %ld\n", num)); source = &((*(tpp + 0))->data0); assert((sizeof (itm_place_t)) >= source->size); if ((1 == source->size) && (1 == resultlen)) { source_start = 0; source_end = 255; } else { source_start = data_to_long(&((*(tpp + 0))->data0)); source_end = data_to_long(&((*(tpp + num - 1))->data0)); if (0 < (*(tpp + num - 1))->range.size) source_end = data_to_long(&((*(tpp + num - 1))->range)); } entry_num = source_end - source_start + 1; table_size = ((sizeof (itm_tbl_hdr_t)) + (sizeof (itm_map_idx_fix_hdr_t)) + (resultlen * entry_num)); if (0 < error_count) { table_size += entry_num; } if (NULL == default_data) { if ((num < entry_num) || (error_count <= 0)) { table_size += entry_num; } } else if ((itm_data_t *)(-1) != default_data) { table_size += resultlen; } table_size = ITMROUNDUP(table_size); header = malloc_vital(table_size); sub_hdr = (itm_map_idx_fix_hdr_t *)(header + 1); table = (char *)(sub_hdr + 1); if ((1 == (*tpp)->data0.size) && (1 == (*tpp)->data1.size)) { header->type = ITM_TBL_MAP_INDEX_FIXED_1_1; } else { header->type = ITM_TBL_MAP_INDEX_FIXED; } header->name.itm_ptr = 0; header->size = table_size; header->number = entry_num; sub_hdr->source_len = (*tpp)->data0.size; sub_hdr->result_len = resultlen; sub_hdr->start.itm_ptr = source_start; sub_hdr->end.itm_ptr = source_end; sub_hdr->error_num = error_count; /* > 0; so pad4 = 0 */ if (NULL != default_data) { if ((itm_data_t *)(-1) == default_data) { sub_hdr->default_error = -1; #if !defined(_LP64) sub_hdr->pad3_num = (pad_t)(~0); #endif } else { sub_hdr->default_error = 0; } } else { if (num < entry_num) { sub_hdr->default_error = 1; } else { sub_hdr->default_error = 2; } } error_table = (table + (resultlen * entry_num)); if (-1 == sub_hdr->default_error) { if (source->size != resultlen) { itm_error( gettext("\"default no_change_copy\" is " "specified, but size does not match\n")); exit(ITMC_STATUS_BT); } for (i = 0, j = 0; i < (entry_num); i++, j += resultlen) { for (k = 0; k < resultlen; k++) { *(table + j + k) = (((source_start + i) >> ((resultlen - k - 1) * 8)) & 0x00ff); } } } else if (0 == sub_hdr->default_error) { error_table += resultlen; if (default_data->size <= (sizeof (itm_place_t))) { for (i = 0, j = 0; i < (entry_num + 1); /* last one is for default */ i++, j += resultlen) { (void) memcpy(table + j + (resultlen - default_data->size), (void *)(&(default_data->place.itm_64d)), default_data->size); } } else { for (i = 0, j = 0; i < (entry_num + 1); /* last one is for default */ i++, j += resultlen) { (void) memcpy(table + j + (resultlen - default_data->size), (void *)(default_data->place.itm_ptr), default_data->size); } } } if (1 == sub_hdr->default_error) { (void) memset(error_table, 1, entry_num); for (i = 0; i < num; i++) { if (0 == (*(tpp + i))->data1.size) { continue; /* error sequence */ } j = data_to_long(&((*(tpp + i))->data0)) - source_start; k = ((*(tpp + i))->range.size) == 0 ? j : data_to_long(&((*(tpp + i))->range)) - source_start; for (; j <= k; j++) { *(error_table + j) = 0; } } } else if (0 < error_count) { (void) memset(error_table, 0, entry_num); for (i = 0; i < num; i++) { if (0 == (*(tpp + i))->data1.size) { /* error sequence */ j = data_to_long(&((*(tpp + i))->data0)) - source_start; k = ((*(tpp + i))->range.size) == 0 ? j : data_to_long(&((*(tpp + i))->range)) - source_start; for (; j <= k; j++) { *(error_table + j) = 1; } } } } p = malloc_vital(sizeof (uchar_t *) * resultlen); for (i = 0; i < num; i++) { j = data_to_long(&((*(tpp + i))->data0)) - source_start; if (0 != (*(tpp + i))->range.size) k = data_to_long(&((*(tpp + i))->range)) - source_start; else k = j; (void) memset(p, 0, sizeof (uchar_t *) * resultlen); (void) memcpy(p + (resultlen - (*(tpp + i))->data1.size), ((caddr_t)NSPTR(&((*(tpp + i))->data1))), (*(tpp + i))->data1.size); map_range_make_result(table, j, k, p, resultlen); } free(p); return (header); } 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) { itm_tbl_hdr_t *header; itm_map_lookup_hdr_t *sub_hdr; char *table; itm_size_t table_size; itm_size_t j; itm_size_t i; itm_size_t k; itm_size_t h; itm_data_t *source; uchar_t *source_data; uchar_t *result_data; TRACE_MESSAGE('m', ("map_table_lookup_fixed : %ld(%ld) 0x%lx\n", num, num2, default_data)); source = &((*(tpp + 0))->data0); table_size = ((sizeof (itm_tbl_hdr_t)) + (sizeof (itm_map_idx_fix_hdr_t)) + ((source->size + 1 + resultlen) * num2)); if ((NULL != default_data) && (((itm_data_t *)(-1)) != default_data)) { table_size += (source->size + 1 + resultlen); } table_size = ITMROUNDUP(table_size); header = malloc_vital(table_size); sub_hdr = (itm_map_lookup_hdr_t *)(header + 1); table = (char *)(sub_hdr + 1); header->type = ITM_TBL_MAP_LOOKUP; header->name.itm_ptr = 0; header->size = table_size; header->number = num2; if (NULL != default_data) { if ((itm_data_t *)(-1) == default_data) { #if !defined(_LP64) sub_hdr->pad3_num = (pad_t)(~0); #endif sub_hdr->default_error = -1; } else { sub_hdr->default_error = 0; } } else { sub_hdr->default_error = 2; } sub_hdr->source_len = source->size; sub_hdr->result_len = resultlen; /* specified map */ source_data = malloc_vital(source->size); result_data = malloc_vital(resultlen); for (i = 0, j = 0; i < num; i++) { (void) memcpy(table + j, NSPTR(&((*(tpp + i))->data0)), source->size); j += source->size; if (0 == (*(tpp + i))->data1.size) { *(table + j) = 1; /* specified error */ j += 1; } else { /* *(table + j) = 0; ** valid */ j += 1; (void) memcpy(table + j + (resultlen - (*(tpp + i))->data1.size), NSPTR(&((*(tpp + i))->data1)), (*(tpp + i))->data1.size); } j += resultlen; if ((*(tpp + i))->range.size != 0) { (void) memcpy(source_data, NSPTR(&((*(tpp + i))->data0)), source->size); (void) memset(result_data, 0, resultlen); (void) memcpy(result_data + (resultlen - (*(tpp + i))->data1.size), NSPTR(&((*(tpp + i))->data1)), (*(tpp + i))->data1.size); h = map_table_num_range((*(tpp + i))); for (k = 0; k < h; k++) { uchar_t *dp; itm_size_t m; for (m = 0, dp = (uchar_t *) (source_data + source->size - 1); m < source->size; m++, dp--) { if (0xff != *dp) { (*dp) += (char)1; for (++dp; m > 0; m--, dp++) { (*dp) = 0x00; } break; } } (void) memcpy(table + j, source_data, source->size); j += source->size; if (0 == (*(tpp + i))->data1.size) { *(table + j) = 1; /* specified error */ j += 1; } else { /* *(table + j) = 0; ** valid */ j += 1; for (m = 0, dp = (uchar_t *) (result_data + resultlen - 1); m < resultlen; m++, dp--) { if (0xff != *dp) { (*dp) += 1; for (++dp; m > 0; m--, dp++) { (*dp) = 0x00; } break; } } (void) memcpy(table + j, result_data, resultlen); } j += resultlen; } } } free(source_data); free(result_data); /* default */ if ((NULL != default_data) && (((itm_data_t *)(-1)) != default_data)) { (void) memset(table + j, 0, source->size + 1 + resultlen); (void) memcpy(table + j + source->size + 1 + (resultlen - default_data->size), NSPTR(default_data), default_data->size); } return (header); } 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) { itm_tbl_hdr_t *header; itm_map_hash_hdr_t *sub_hdr; itm_size_t table_size; char *error_table; char *hash_table; itm_size_t hash_table_num; char *of_table; itm_size_t of_table_num; itm_size_t pair_size; itm_size_t i; itm_size_t j; itm_size_t k; char *p; itm_data_t *source; long hash_value; #if defined(DEBUG) long hash_none; long hash_one; long hash_conflict; #endif /* DEBUG */ uchar_t *source_data; uchar_t *result_data; uchar_t *dp; itm_size_t m; itm_size_t n; itm_size_t h; TRACE_MESSAGE('m', ("map_table_hash : %ld(%ld) 0x%lx\n", num, num2, default_data)); source = &((*(tpp + 0))->data0); pair_size = (source->size + 1 + resultlen); if (100 <= hash_factor) { hash_table_num = (num2 * (hash_factor / 100.0)); } else { hash_table_num = (num2 * 2); } if (hash_table_num < 256) { hash_table_num = 256; } source_data = malloc_vital(source->size); result_data = malloc_vital(resultlen); hash_table = malloc_vital(hash_table_num); for (i = 0, of_table_num = 0; i < num; i++) { hash_value = hash(NSPTR(&((*(tpp + i))->data0)), (*(tpp + i))->data0.size, hash_table_num); if (0 == *(hash_table + hash_value)) { *(hash_table + hash_value) = 1; } else { *(hash_table + hash_value) = 2; of_table_num += 1; } if ((*(tpp + i))->range.size != 0) { (void) memcpy(source_data, NSPTR(&((*(tpp + i))->data0)), source->size); h = map_table_num_range((*(tpp + i))); for (n = 0; n < h; n++) { for (m = 0, dp = (uchar_t *) (source_data + source->size - 1); m < source->size; m++, dp--) { if (0xff != *dp) { (*dp) += 1; for (++dp; m > 0; m--, dp++) { (*dp) = 0x00; } break; } } hash_value = hash((char *)source_data, source->size, hash_table_num); if (0 == *(hash_table + hash_value)) { *(hash_table + hash_value) = 1; } else { *(hash_table + hash_value) = 2; of_table_num += 1; } } } } #if defined(DEBUG) if (TRACE('s')) { hash_none = 0; hash_one = 0; hash_conflict = 0; j = 0; for (i = 0; i < hash_table_num; i++) { if (2 == *(hash_table + i)) { (void) putchar('2'); hash_conflict += 1; } else if (1 == *(hash_table + i)) { (void) putchar('1'); hash_one += 1; } else if (0 == *(hash_table + i)) { (void) putchar('-'); hash_none += 1; } else { (void) putchar('*'); } if (63 <= j) { j = 0; (void) putchar('\n'); } else { j += 1; } } (void) putchar('\n'); (void) printf("null=%ld one=%ld conflict=%ld\n", hash_none, hash_one, hash_conflict); } #endif /* DEBUG */ free(hash_table); table_size = ((sizeof (itm_tbl_hdr_t)) + (sizeof (itm_map_hash_hdr_t)) + (hash_table_num) + (pair_size * hash_table_num) + (pair_size * of_table_num)); if ((NULL != default_data) && (((itm_data_t *)(-1)) != default_data)) { table_size += pair_size; } table_size = ITMROUNDUP(table_size); header = malloc_vital(table_size); sub_hdr = (itm_map_hash_hdr_t *)(header + 1); error_table = (char *)(sub_hdr + 1); hash_table = error_table + hash_table_num; of_table = hash_table + (pair_size * hash_table_num); header->type = ITM_TBL_MAP_HASH; header->name.itm_ptr = 0; header->size = table_size; header->number = num2; if (NULL != default_data) { if ((itm_data_t *)(-1) == default_data) { sub_hdr->default_error = -1; #if !defined(_LP64) sub_hdr->pad7_num = (pad_t)(~0); #endif } else { sub_hdr->default_error = 0; } } else { sub_hdr->default_error = 2; } sub_hdr->source_len = source->size; sub_hdr->result_len = resultlen; sub_hdr->hash_tbl_size = (pair_size * hash_table_num); sub_hdr->hash_tbl_num = hash_table_num; sub_hdr->hash_of_size = (pair_size * of_table_num); sub_hdr->hash_of_num = of_table_num; sub_hdr->error_num = error_count; /* > 0; so pad4 = 0 */ /* specified map */ for (i = 0, j = 0, k = 0; i < num; i++) { hash_value = hash(NSPTR(&((*(tpp + i))->data0)), (*(tpp + i))->data0.size, hash_table_num); p = error_table + hash_value; if (*p) { /* conflict */ if (*p < 63) { *p += 1; } p = of_table + k; k += pair_size; } else { *p = 1; p = hash_table + (pair_size * hash_value); } (void) memcpy(p, NSPTR(&((*(tpp + i))->data0)), source->size); p += source->size; if (0 == (*(tpp + i))->data1.size) { (*p) = 1; /* specified error */ p++; } else { /* (*p) = 0; ** valid */ p++; (void) memset(p, 0, (resultlen - (*(tpp + i))->data1.size)); (void) memcpy(p + (resultlen - (*(tpp + i))->data1.size), NSPTR(&((*(tpp + i))->data1)), (*(tpp + i))->data1.size); } if ((*(tpp + i))->range.size != 0) { (void) memcpy(source_data, NSPTR(&((*(tpp + i))->data0)), source->size); (void) memset(result_data, 0, (resultlen - (*(tpp + i))->data1.size)); (void) memcpy(result_data + (resultlen - (*(tpp + i))->data1.size), NSPTR(&((*(tpp + i))->data1)), (*(tpp + i))->data1.size); h = map_table_num_range((*(tpp + i))); for (n = 0; n < h; n++) { for (m = 0, dp = (uchar_t *) (source_data + source->size - 1); m < source->size; m++, dp--) { if (0xff != *dp) { (*dp) += 1; for (++dp; m > 0; m--, dp++) { (*dp) = 0x00; } break; } } hash_value = hash((char *)source_data, source->size, hash_table_num); p = error_table + hash_value; if (*p) { /* conflict */ if (*p < 63) { *p += 1; } p = of_table + k; k += pair_size; } else { *p = 1; p = hash_table + (pair_size * hash_value); } (void) memcpy(p, source_data, source->size); p += source->size; if (0 == (*(tpp + i))->data1.size) { (*p) = 1; /* specified error */ p += 1; } else { /* (*p) = 0; ** valid */ p += 1; for (m = 0, dp = (uchar_t *) (result_data + resultlen - 1); m < resultlen; m++, dp--) { if (0xff != *dp) { (*dp) += 1; for (++dp; m > 0; m--, dp++) { (*dp) = 0x00; } break; } } (void) memcpy(p, result_data, resultlen); } } } } free(source_data); free(result_data); /* default */ if ((NULL != default_data) && (((itm_data_t *)(-1)) != default_data)) { j = ((pair_size * hash_table_num) + (pair_size * of_table_num)); (void) memcpy(hash_table + j + (resultlen - default_data->size), NSPTR(default_data), default_data->size); } #if defined(ENABLE_TRACE) for (i = 0, p = of_table; i < of_table_num; i++, p += 5) { (void) printf("0x%02x%02x%02x%02x 0x%02x\n", ((unsigned char)(*(p + 0))), ((unsigned char)(*(p + 1))), ((unsigned char)(*(p + 2))), ((unsigned char)(*(p + 3))), ((unsigned char)(*(p + 4)))); } #endif return (header); } 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) { itm_tbl_hdr_t *header; itm_map_dense_enc_hdr_t *sub_hdr; char *table; char *error_table; itm_size_t table_size; itm_size_t j; itm_size_t i; itm_size_t k; char *p; itm_data_t *source; unsigned char *byte_seq_def; TRACE_MESSAGE('m', ("map_table_dense_encoding : %ld\n", num)); source = &((*(tpp + 0))->data0); table_size = ((sizeof (itm_tbl_hdr_t)) + (sizeof (itm_map_dense_enc_hdr_t)) + (source->size + source->size) + (resultlen * entry_num)); if (0 < error_count) { table_size += entry_num; } if (NULL == default_data) { if ((num < entry_num) || (error_count <= 0)) { table_size += entry_num; } } else if ((itm_data_t *)(-1) != default_data) { table_size += resultlen; } table_size = ITMROUNDUP(table_size); header = malloc_vital(table_size); sub_hdr = (itm_map_dense_enc_hdr_t *)(header + 1); table = (char *)(sub_hdr + 1) + source->size + source->size; header->type = ITM_TBL_MAP_DENSE_ENC; header->name.itm_ptr = 0; header->size = table_size; header->number = entry_num; sub_hdr->source_len = (*tpp)->data0.size; sub_hdr->result_len = resultlen; sub_hdr->error_num = error_count; /* > 0; so pad4 = 0 */ if (NULL != default_data) { if ((itm_data_t *)(-1) == default_data) { sub_hdr->default_error = -1; #if !defined(_LP64) sub_hdr->pad3_num = (pad_t)(~0); #endif } else { sub_hdr->default_error = 0; } } else { if (num < entry_num) { sub_hdr->default_error = 1; } else { sub_hdr->default_error = 2; } } (void) memcpy((char *)(sub_hdr + 1), byte_seq_min, source->size); (void) memcpy((char *)(sub_hdr + 1) + source->size, byte_seq_max, source->size); if (-1 == sub_hdr->default_error) { byte_seq_def = malloc_vital((sizeof (unsigned char *)) * resultlen); if (source->size != resultlen) { itm_error( gettext("\"default no_change_copy\" is " "specified, but size does not match\n")); exit(ITMC_STATUS_BT); } put_dense_encoding_default( table, byte_seq_min, byte_seq_max, byte_seq_def, resultlen - 1, 0, 0); free(byte_seq_def); } else if (0 == sub_hdr->default_error) { if (default_data->size <= (sizeof (itm_place_t))) { for (i = 0, j = 0; i < (entry_num + 1); /* 1:default data */ i++, j += resultlen) { (void) memcpy(table + j + (resultlen - default_data->size), (void *)(&(default_data->place.itm_64d)), default_data->size); } } else { for (i = 0, j = 0; i < (entry_num + 1); /* 1:default data */ i++, j += resultlen) { (void) memcpy(table + j + (resultlen - default_data->size), (void *)(default_data->place.itm_ptr), default_data->size); } } } if (1 == sub_hdr->default_error) { (void) memset(table + (resultlen * entry_num), 1, entry_num); error_table = (table + (resultlen * entry_num)); for (i = 0; i < num; i++) { if (0 == (*(tpp + i))->data1.size) { continue; /* error sequence */ } j = hash_dense_encoding(NSPTR(&((*(tpp + i))->data0)), (*(tpp + i))->data0.size, byte_seq_min, byte_seq_max); k = ((*(tpp + i))->range.size) == 0 ? j : hash_dense_encoding(NSPTR(&((*(tpp + i))->range)), (*(tpp + i))->data0.size, byte_seq_min, byte_seq_max); for (; j <= k; j++) { *(error_table + j) = 0; } } } else if (0 < error_count) { error_table = (table + (resultlen * entry_num)); if (0 == sub_hdr->default_error) { error_table += resultlen; } (void) memset(error_table, 0, entry_num); for (i = 0; i < num; i++) { if (0 == (*(tpp + i))->data1.size) { j = hash_dense_encoding( NSPTR(&((*(tpp + i))->data0)), (*(tpp + i))->data0.size, byte_seq_min, byte_seq_max); k = ((*(tpp + i))->range.size) == 0 ? j : hash_dense_encoding( NSPTR(&((*(tpp + i))->range)), (*(tpp + i))->data0.size, byte_seq_min, byte_seq_max); for (; j <= k; j++) { *(error_table + j) = 1; /* specified */ } } } } p = malloc_vital(resultlen); for (i = 0; i < num; i++) { j = hash_dense_encoding(NSPTR(&((*(tpp + i))->data0)), (*(tpp + i))->data0.size, byte_seq_min, byte_seq_max); if (0 != (*(tpp + i))->range.size) k = hash_dense_encoding( NSPTR(&((*(tpp + i))->range)), (*(tpp + i))->range.size, byte_seq_min, byte_seq_max); else k = j; (void) memset(p, 0, (resultlen - (*(tpp + i))->data1.size)); (void) memcpy(p + (resultlen - (*(tpp + i))->data1.size), ((caddr_t)NSPTR(&((*(tpp + i))->data1))), (*(tpp + i))->data1.size); map_range_make_result(table, j, k, p, resultlen); } free(p); return (header); } 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) { uchar_t i; if (position < pos_max) { for (i = *(byte_seq_min + position); i <= *(byte_seq_max + position); i++) { *(byte_seq_def + position) = i; put_dense_encoding_default( table, byte_seq_min, byte_seq_max, byte_seq_def, pos_max, position + 1, ((dense_encoded_value + i) * (*(byte_seq_max + position) - *(byte_seq_min + position) + 1))); } return; } for (i = *(byte_seq_min + position); i <= *(byte_seq_max + position); i++) { *(byte_seq_def + position) = i; (void) memcpy(table + ((pos_max + 1) * (dense_encoded_value + i - 1)), byte_seq_def, pos_max + 1); } } char * dense_enc_index_to_byte_seq( long value, long length, unsigned char *byte_seq_min, unsigned char *byte_seq_max) { static char *buf; static long buf_len; char *p; int i; int l; int residue; if (buf_len < (2 + (length * 2) + 1)) { free(buf); buf_len = (2 + (length * 2) + 1) + 16; buf = malloc_vital(buf_len); } *(buf + (length * 2)) = '\0'; *(buf + 0) = '0'; *(buf + 1) = 'x'; p = buf + 2; for (i = length - 1; 0 <= i; --i) { residue = value % (*(byte_seq_max + i) - *(byte_seq_min + i) + 1); value /= (*(byte_seq_max + i) - *(byte_seq_min + i) + 1); residue += *(byte_seq_min + i); l = ((0xf0 & residue) >> 4); if (l < 10) { *(p + (i * 2)) = ('0' + l); } else { *(p + (i * 2)) = ('a' + l - 10); } l = (0x0f & residue); if (l < 10) { *(p + (i * 2) + 1) = ('0' + l); } else { *(p + (i * 2) + 1) = ('a' + l - 10); } } return (buf); } itm_tbl_hdr_t * map_table_lookup_var() { itm_error(gettext( "length of all source sequences must be the same\n")); error_deferred += 1; return (NULL); } 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) { unsigned char *p, *p2; int i; int flag; p = (unsigned char *)(NSPTR(&((pair)->data0))); p2 = (unsigned char *)(NSPTR(&((pair)->range))); flag = 0; for (i = 0; i < source_len; i++) { if (flag != 0) { break; } if (*(p + i) != *(p2 + i)) flag = 1; if (*(p + i) < *(byte_seq_min + i)) { *(byte_seq_min + i) = *(p + i); } if (*(byte_seq_max + i) < *(p2 + i)) { *(byte_seq_max + i) = *(p2 + i); } } for (; i < source_len; i++) { *(byte_seq_min + i) = 0x00; *(byte_seq_max + i) = 0xff; } } /* * result value + (source range value - source base value) * and just caluculate its length */ static size_t map_table_resultlen(itmc_map_t *ml) { size_t j; size_t len; int m; uchar_t *c1; uchar_t *c2; uchar_t *c3; j = ml->data_pair.data0.size; if (j < ml->data_pair.data1.size) j = ml->data_pair.data1.size; if (j < ml->data_pair.range.size) j = ml->data_pair.range.size; c1 = (uchar_t *)(NSPTR(&((ml->data_pair).data0))) + ml->data_pair.data0.size - 1; c2 = (uchar_t *)(NSPTR(&((ml->data_pair).data1))) + ml->data_pair.data1.size - 1; c3 = (uchar_t *)(NSPTR(&((ml->data_pair.range)))) + ml->data_pair.range.size - 1; m = 0; for (len = 0; len < j; len++, c1--, c2--, c3--) { if (len < ml->data_pair.data0.size) m -= *c1; if (len < ml->data_pair.data1.size) m += *c2; if (len < ml->data_pair.range.size) m += *c3; m >>= 8; } if (m > 0) { len += 1; } TRACE_MESSAGE('g', ("map_table_resutlen: source(0x%s..0x%s), " "result(0x%s.... len= %ld)\n", data_to_hexadecimal(&(ml->data_pair.data0)), data_to_hexadecimal(&(ml->data_pair.range)), data_to_hexadecimal(&(ml->data_pair.data1)), len)); return (len); } /* * */ 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) { itm_size_t i; itm_size_t j; itm_size_t p; uchar_t *dp; /* unsigned for ++ operation */ for (i = range_start, p = i * result_size; i <= range_end; i++, p += result_size) { (void) memcpy(table + p, result_data, result_size); for (j = 0, dp = (uchar_t *)(result_data + result_size - 1); j < result_size; j++, dp--) { if (0xff != *dp) { (*dp) += 1; for (++dp; j > 0; j--, dp++) { (*dp) = 0x00; } break; } } } } /* * */ static size_t map_table_num_range(itmc_data_pair_t *pair) { size_t i, j; itm_num_t num; itm_num_t num2; uchar_t *c1; uchar_t *c2; assert(0 < pair->range.size); j = pair->data0.size; if (j < pair->range.size) j = pair->range.size; c1 = ((uchar_t *)(NSPTR(&(pair->data0)))) + pair->data0.size - 1; c2 = ((uchar_t *)(NSPTR(&(pair->range)))) + pair->range.size - 1; num = 0; for (i = 0; i < j; i++, c1--, c2--) { if (i < pair->range.size) num2 = *c2; if (i < pair->data0.size) num2 -= *c1; TRACE_MESSAGE('G', (" num += %d(=%d-%d)\n ", *c2 - *c1, *c2, *c1)); num2 <<= (i*8); num += num2; } TRACE_MESSAGE('g', ("map_table_num_range: source(0x%s..0x%s), " "num= %ld\n", data_to_hexadecimal(&(pair->data0)), data_to_hexadecimal(&(pair->range)), num)); return (num); } /* * */ itmc_map_t * map_list_append(itmc_map_t *map_list, itmc_map_t *map_pair) { if (0 == map_pair) { return (map_list); } map_pair->next = NULL; map_pair->last = map_pair; if (map_list) { map_list->last->next = map_pair; map_list->last = map_pair; return (map_list); } else { return (map_pair); } } itmc_obj_t * op_self(itm_op_type_t type) { return (op_unit(type, NULL, 0, NULL, 0, NULL, 0)); } itmc_obj_t * op_unary(itm_op_type_t type, void *data, size_t data_size) { return (op_unit(type, data, data_size, NULL, 0, NULL, 0)); } 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) { itm_op_t *op; itmc_obj_t *obj; op = malloc_vital(sizeof (itm_op_t)); op->type = type; op->data.operand[0].itm_ptr = (itm_place2_t)(data0); op->data.operand[1].itm_ptr = (itm_place2_t)(data1); op->data.operand[2].itm_ptr = (itm_place2_t)(data2); obj = malloc_vital(sizeof (itmc_obj_t)); obj->type = ITMC_OBJ_OP; obj->name = NULL; obj->obj = op; obj->ref[0] = obj->ref[1] = obj->ref[2] = NULL; if (NULL != data0) { obj->ref[0] = obj_register(ITMC_OBJ_EXPR, NULL, data0, data0_size, &(op->data.operand[0]), OBJ_REG_TAIL); } if (NULL != data1) { obj->ref[1] = obj_register(ITMC_OBJ_EXPR, NULL, data1, data1_size, &(op->data.operand[1]), OBJ_REG_TAIL); } if (NULL != data2) { obj->ref[2] = obj_register(ITMC_OBJ_EXPR, NULL, data2, data2_size, &(op->data.operand[2]), OBJ_REG_TAIL); } obj->next = NULL; obj->last = NULL; return (obj); } itmc_obj_t * op_self_num(itm_op_type_t type, itm_num_t data) { itm_op_t *op; itmc_obj_t *obj; op = malloc_vital(sizeof (itm_op_t)); op->type = type; op->data.itm_opnum = data; #if !defined(_LP64) op->data.itm_oppad = (data < 0) ? (pad_t)(~0) : 0; #endif obj = malloc_vital(sizeof (itmc_obj_t)); obj->type = ITMC_OBJ_OP; obj->name = NULL; obj->obj = op; obj->ref[0] = obj->ref[1] = obj->ref[2] = NULL; return (obj); } itm_expr_t * expr_self_num(itm_expr_type_t type, itm_num_t data) { itm_expr_t *expr; expr = malloc_vital(sizeof (itm_expr_t)); expr->type = type; expr->data.itm_exnum = data; #if !defined(_LP64) expr->data.itm_expad = (data < 0) ? (pad_t)(~0) : 0; #endif return (expr); } itm_expr_t * expr_self(itm_expr_type_t type, itm_data_t *data) { itm_expr_t *expr; itmc_name_t *name; expr = malloc_vital(sizeof (itm_expr_t)); expr->type = type; if (NULL == data) { expr->data.value.size = 0; expr->data.value.place.itm_ptr = 0; } else { expr->data.value = *(data); } switch (type) { case ITM_EXPR_NAME: /* register */ name = name_lookup(data, ITMC_OBJ_REGISTER); if (&name_lookup_error == name) { return (NULL); } else if (NULL == name) { if (reg_id >= MAXREGID) { itm_error( gettext( "more than %d variables are used\n"), MAXREGID); exit(ITMC_STATUS_BT2); } name = name_register(data, ITMC_OBJ_REGISTER, NULL); name->reg_id = (reg_id++); } expr->type = ITM_EXPR_REG; expr->data.itm_exnum = name->reg_id; #if !defined(_LP64) expr->data.itm_expad = (expr->data.itm_exnum < 0) ? (pad_t)(~0) : 0; #endif break; case ITM_EXPR_SEQ: if ((sizeof (itm_place_t)) < data->size) { (void) obj_register(ITMC_OBJ_DATA, NULL, (void *)(data->place.itm_ptr), data->size, &(expr->data.value.place), OBJ_REG_TAIL); } break; } return (expr); } itm_expr_t * expr_unary(itm_expr_type_t type, itm_expr_t *data0) { itm_expr_t *expr; expr = malloc_vital(sizeof (itm_expr_t)); expr->type = type; expr->data.operand[0].itm_ptr = (itm_place2_t)(data0); (void) obj_register(ITMC_OBJ_EXPR, NULL, data0, sizeof (itm_expr_t), &(expr->data.operand[0]), OBJ_REG_TAIL); return (expr); } itm_expr_t * expr_binary(itm_expr_type_t type, itm_expr_t *data0, itm_expr_t *data1) { itm_expr_t *expr; itm_num_t num; unsigned char *p; int i; expr = malloc_vital(sizeof (itm_expr_t)); expr->type = type; if (ITM_EXPR_SEQ == data0->type) { p = (unsigned char *)NSPTR(&(data0->data.value)); for (i = 0, num = 0; i < data0->data.value.size; i++, p++) { num = ((num << 8) | *p); } data0 = expr_self_num(ITM_EXPR_INT, num); } if (ITM_EXPR_SEQ == data1->type) { p = (unsigned char *)NSPTR(&(data1->data.value)); for (i = 0, num = 0; i < data1->data.value.size; i++, p++) { num = ((num << 8) | *p); } data1 = expr_self_num(ITM_EXPR_INT, num); } expr->data.operand[0].itm_ptr = (itm_place2_t)(data0); expr->data.operand[1].itm_ptr = (itm_place2_t)(data1); (void) obj_register(ITMC_OBJ_EXPR, NULL, data0, sizeof (itm_expr_t), &(expr->data.operand[0]), OBJ_REG_TAIL); (void) obj_register(ITMC_OBJ_EXPR, NULL, data1, sizeof (itm_expr_t), &(expr->data.operand[1]), OBJ_REG_TAIL); return (expr); } itm_expr_t * expr_binary2(itm_expr_type_t type, itm_expr_t *data0, itm_expr_t *data1) { itm_expr_t *expr; itm_num_t num; unsigned char *p; int i; if ((NULL == data0) || (NULL == data1)) { return (NULL); } expr = malloc_vital(sizeof (itm_expr_t)); expr->type = type; switch (data0->type) { case ITM_EXPR_SEQ: p = (unsigned char *)NSPTR(&(data0->data.value)); for (i = 0, num = 0; i < data0->data.value.size; i++, p++) { num = ((num << 8) | *p); } data0 = expr_self_num(ITM_EXPR_INT, num); expr->data.operand[0].itm_ptr = (itm_place2_t)(data0); (void) obj_register(ITMC_OBJ_EXPR, NULL, data0, sizeof (itm_expr_t), &(expr->data.operand[0]), OBJ_REG_TAIL); break; case ITM_EXPR_INT: case ITM_EXPR_REG: case ITM_EXPR_IN_VECTOR_D: expr->data.operand[0] = data0->data.operand[0]; break; default: expr->data.operand[0].itm_ptr = (itm_place2_t)(data0); (void) obj_register(ITMC_OBJ_EXPR, NULL, data0, sizeof (itm_expr_t), &(expr->data.operand[0]), OBJ_REG_TAIL); break; } switch (data1->type) { case ITM_EXPR_SEQ: p = (unsigned char *)NSPTR(&(data1->data.value)); for (i = 0, num = 0; i < data1->data.value.size; i++, p++) { num = ((num << 8) | *p); } data1 = expr_self_num(ITM_EXPR_INT, num); expr->data.operand[1].itm_ptr = (itm_place2_t)(data1); (void) obj_register(ITMC_OBJ_EXPR, NULL, data1, sizeof (itm_expr_t), &(expr->data.operand[1]), OBJ_REG_TAIL); break; case ITM_EXPR_INT: case ITM_EXPR_REG: case ITM_EXPR_IN_VECTOR_D: expr->data.operand[1] = data1->data.operand[0]; break; default: expr->data.operand[1].itm_ptr = (itm_place2_t)(data1); (void) obj_register(ITMC_OBJ_EXPR, NULL, data1, sizeof (itm_expr_t), &(expr->data.operand[1]), OBJ_REG_TAIL); break; } return (expr); } itm_expr_t * expr_assign(itm_expr_type_t type, itm_data_t *data0, itm_expr_t *data1) { itm_expr_t *expr; itmc_name_t *name; expr = malloc_vital(sizeof (itm_expr_t)); expr->type = type; expr->data.operand[1].itm_ptr = (itm_place2_t)(data1); name = name_lookup(data0, ITMC_OBJ_REGISTER); if (&name_lookup_error == name) { free(expr); exit(ITMC_STATUS_BT); } else if (NULL == name) { name = name_register(data0, ITMC_OBJ_REGISTER, NULL); name->reg_id = (reg_id++); } expr->data.operand[0].itm_ptr = name->reg_id; (void) obj_register(ITMC_OBJ_EXPR, NULL, data1, sizeof (itm_expr_t), &(expr->data.operand[1]), OBJ_REG_TAIL); return (expr); } itm_expr_t * expr_seq_to_int(itm_expr_t *expr) { itm_num_t num; unsigned char *p; int i; if (ITM_EXPR_SEQ == expr->type) { if ((sizeof (itm_place_t)) < expr->data.value.size) { p = (unsigned char *)(expr->data.value.place.itm_ptr); } else { p = (unsigned char *)&(expr->data.value.place.itm_64d); } for (i = 0, num = 0; i < expr->data.value.size; i++, p++) { num = ((num << 8) | *p); } free(expr); expr = expr_self_num(ITM_EXPR_INT, num); } return (expr); } itmc_name_t * name_lookup(itm_data_t *name, itm_type_t type) { itmc_name_t *p; TRACE_MESSAGE('N', ("name_lookup\t: \"%-16s\" %2ld %2ld %2ld\n", name_to_str(name), name->size, type, name_id)); if (0 == name->size) return (NULL); for (p = name_first; p; p = p->next) { if ((name->size != p->name.size) || (memcmp(NSPTR(name), NSPTR(&(p->name)), name->size))) { continue; } if ((type != p->type) && (((ITMC_OBJ_ACTION != type) && (ITMC_OBJ_ACTION != p->type)) || ((ITMC_OBJ_ACTION == type) && (ITMC_OBJ_DIREC != p->type) && (ITMC_OBJ_OP != p->type) && (ITMC_OBJ_MAP != p->type)) || ((ITMC_OBJ_ACTION == p->type) && (ITMC_OBJ_DIREC != type) && (ITMC_OBJ_OP != type) && (ITMC_OBJ_MAP != type)))) { itm_error( gettext("name type conflict: \"%1$s\" " "%2$s %3$s\n"), name_to_str(name), itm_name_type_name[type], itm_name_type_name[p->type]); error_deferred += 1; return (&name_lookup_error); } else { return (p); } } return (NULL); } itmc_name_t * name_refer(itm_data_t *name, itm_type_t type, itmc_ref_t *refp) { itmc_name_t *p; itmc_ref_link_t *rl; p = name_lookup(name, type); TRACE_MESSAGE('N', ("name_refer\t: \"%-16s\" %2ld %2ld %08p %2d %08p\n", name_to_str(name), name->size, type, refp, name_id, p)); if (&name_lookup_error == p) { return (NULL); } rl = malloc_vital(sizeof (itmc_ref_link_t)); rl->ref = refp; rl->next = NULL; if (NULL != p) { if (p->ref_last) { p->ref_last->next = rl; } else { p->ref_first = rl; } p->ref_last = rl; } else { p = malloc_vital(sizeof (itmc_name_t)); p->id = (name_id++); p->reg_id = 0; p->name = *name; p->type = type; #if !defined(_LP64) p->reloc.itm_pad = 0; #endif p->reloc.itm_ptr = 0; p->ref_first = rl; p->ref_last = rl; p->next = NULL; if (name_last) { name_last->next = p; } else { name_first = p; } name_last = p; } return (p); } itmc_name_t * name_register(itm_data_t *name, itm_type_t type, itmc_ref_t *refp) { itmc_name_t *p; TRACE_MESSAGE('N', ("name_register\t: \"%-16s\" %2ld %2ld %08p %2ld\n", name_to_str(name), name->size, type, refp, name_id)); p = name_lookup(name, type); if (&name_lookup_error == p) { return (NULL); } if (NULL != p) { if (NULL != p->object) { itm_error(gettext( "same names are specified: %1$s\n"), name_to_str(name)); error_deferred += 1; return (NULL); } p->object = refp; } else { p = malloc_vital(sizeof (itmc_name_t)); p->id = (name_id++); p->reg_id = 0; p->name = *name; p->type = type; p->object = refp; p->reloc.itm_ptr = 0; #if !defined(_LP64) p->reloc.itm_pad = 0; #endif p->ref_first = NULL; p->ref_last = NULL; p->next = NULL; if (name_last) { name_last->next = p; } else { name_first = p; } name_last = p; } return (p); } int data_compare(const itm_data_t *d0, const itm_data_t *d1) { if (d0->size < d1->size) { if (memcmp(NSPTR(d0), NSPTR(d1), d0->size) < 0) { return (-1); } else { return (1); } } else if (d0->size == d1->size) { return (memcmp(NSPTR(d0), NSPTR(d1), d0->size)); } else /* (d0->size > d1->size) */ { if (memcmp(NSPTR(d0), NSPTR(d1), d1->size) <= 0) { return (-1); } else { return (1); } } } int data_pair_compare(itmc_data_pair_t **p0, itmc_data_pair_t **p1) { int r; itm_data_t *d0; itm_data_t *d1; uchar_t *c0; uchar_t *c1; size_t s; int i; d0 = &((*p0)->data0); d1 = &((*p1)->data0); c0 = NSPTR(d0); c1 = NSPTR(d1); if (d0->size == d1->size) { s = d0->size; } else if (d0->size < d1->size) { s = d1->size - d0->size; for (i = 0; i < s; i++, c1++) { if (0x00 != *c1) { return (-1); } } s = d0->size; } else { assert(d0->size > d1->size); s = d0->size - d1->size; for (i = 0; i < s; i++, c0++) { if (0x00 != *c0) { return (1); } } s = d1->size; } r = memcmp(c0, c1, s); if (0 == r) { itm_data_t *d; if (c0 == NSPTR(d0)) { d = d0; } else { assert(c1 == NSPTR(d0)); d = d1; } itm_error(gettext( "distinct source values are specified: 0x%1$s\n"), data_to_hexadecimal(d)); error_deferred += 1; } return (r); } static long data_to_long(itm_data_t *data) { long l; int i; unsigned char *p; if ((sizeof (itm_place_t)) < data->size) { return (0); } for (l = 0, i = 0, p = (unsigned char *)&(data->place); i < data->size; i++, p++) { l <<= 8; l |= *p; } return (l); } /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright (c) 1999 by Sun Microsystems, Inc. * All rights reserved. */ #ifndef _ITM_UTIL_H #define _ITM_UTIL_H #ifdef __cplusplus extern "C" { #endif #include "iconv_tm.h" #include "itmcomp.h" /* * function prototype */ void itm_def_process(itm_data_t *); itmc_obj_t *direction_unit(itmc_ref_t *, itm_data_t *, itmc_action_t *, itm_data_t *); itm_tbl_hdr_t *obj_table(itm_type_t, itm_data_t *, itmc_obj_t *, itm_size_t); itmc_ref_t *obj_register(itm_type_t, itm_data_t *, void *, size_t, itm_place_t *, itm_type_t); itmc_obj_t *obj_list_append(itmc_obj_t *, itmc_obj_t *); /* conditions: range, escape sequence */ itm_tbl_hdr_t *range_table(itm_data_t *, itmc_obj_t *); itm_tbl_hdr_t *escseq_table(itm_data_t *, itmc_obj_t *); /* action: map, operation */ itm_tbl_hdr_t *map_table(itm_data_t *, itmc_map_t *, itmc_map_attr_t *); itmc_map_t *map_list_append(itmc_map_t *, itmc_map_t *); itmc_obj_t *op_self(itm_op_type_t); itmc_obj_t *op_unary(itm_op_type_t, void *, size_t); itmc_obj_t *op_unit(itm_op_type_t, void *, size_t, void *, size_t, void *, size_t); itmc_obj_t *op_self_num(itm_op_type_t, itm_num_t); /* expressions */ itm_expr_t *expr_self_num(itm_expr_type_t, itm_num_t); itm_expr_t *expr_self(itm_expr_type_t, itm_data_t *); itm_expr_t *expr_unary(itm_expr_type_t, itm_expr_t *); itm_expr_t *expr_binary(itm_expr_type_t, itm_expr_t *, itm_expr_t *); itm_expr_t *expr_binary2(itm_expr_type_t, itm_expr_t *, itm_expr_t *); itm_expr_t *expr_assign(itm_expr_type_t, itm_data_t *, itm_expr_t *); itm_expr_t *expr_seq_to_int(itm_expr_t *); extern int data_compare(const itm_data_t *, const itm_data_t *); extern char *dense_enc_index_to_byte_seq(long, long, unsigned char *, unsigned char *); #define OBJ_REG_HEAD (0) #define OBJ_REG_TAIL (1) #ifdef __cplusplus } #endif #endif /* !_ITM_UTIL_H */ /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright (c) 1999 by Sun Microsystems, Inc. * All rights reserved. */ #include #include #include #include #include #include #include #include #include #include #include #include "itmcomp.h" #include "maptype.h" #if !defined(TEXT_DOMAIN) #define TEXT_DOMAIN "SYS_TEST" #endif #define ITMSUFFIX ".bt" #define ME_DEFAULT "geniconvtbl" #define CPP_PATH "/usr/lib/cpp" itmc_ref_t *ref_first[ITMC_OBJ_LAST + 1]; itmc_ref_t *ref_last[ITMC_OBJ_LAST + 1]; itmc_name_t *name_first; itmc_name_t *name_last; char *itm_input_file; /* referred in itm_comp.l */ char *itm_output_file; cmd_opt_t cmd_opt; itm_num_t name_id; itm_num_t reg_id; itmc_name_t name_lookup_error; int error_deferred; char *itm_name_type_name[] = { "UNKNOWN", "ITM", "STRING", "DIRECTION", "CONDITION", "MAP", "OPERATION", "EXPRESSION", "DATA", "NAME", "RANGE", "REGISTER", }; static void usage(int status); static int cpp_opt_append(char *opt, char *arg); static void cpp_opt_trunc(int num); static int parse_opts(int argc, char **argv); static char *prog_path_expand(const char *base_name); static void map_name_type_append(char *optarg); static char *map_type_name_str(itmc_map_type_t); static char *strdup_vital(const char *); #if defined(ENABLE_TRACE) static void trace_option(void); #endif /* ENABLE_TRACE */ static FILE *cpp_open(void); static void cpp_close(FILE *fp); static int itm_compile(char *file); static void wait_child(pid_t pid); static int fork_error(void); int main(int argc, char **argv) { char **pp; pid_t pid; (void) setlocale(LC_ALL, ""); (void) textdomain(TEXT_DOMAIN); (void) parse_opts(argc, argv); #if defined(ENABLE_TRACE) trace_option(); #endif /* ENABLE_TRACE */ if (NULL != cmd_opt.disassemble) { disassemble(cmd_opt.disassemble); } else if (NULL == cmd_opt.input_file) { (void) itm_compile(NULL); } else { if (1 < cmd_opt.input_file_num) { for (pp = cmd_opt.input_file; *pp; pp++) { (void) printf("%s:\n", *pp); pid = fork(); switch (pid) { case 0: exit(itm_compile(*pp)); break; case -1: (void) fork_error(); break; default: wait_child(pid); } } } else { (void) itm_compile(*(cmd_opt.input_file)); } } return (0); } static int itm_compile(char *file) { char *cmd_line; char *command; char *p; size_t length; FILE *fp; extern int yyparse(); extern FILE *yyin; if (NULL == file) { itm_input_file = gettext("*stdin*"); } else { if (0 != access(file, R_OK)) { int e = errno; itm_error(gettext("%1$s: can not access %2$s: "), cmd_opt.my_name, file); errno = e; PERROR(NULL); exit(ITMC_STATUS_CMD2); } itm_input_file = file; } if ((NULL == cmd_opt.output_file) && (0 == cmd_opt.no_output)) { p = strrchr(file, '.'); if (NULL == p) { length = strlen(file); } else { length = p - file; } itm_output_file = malloc_vital(length + 5); (void) memcpy(itm_output_file, file, length); (void) memcpy(itm_output_file + length, ITMSUFFIX, 5); } else { itm_output_file = cmd_opt.output_file; } if (0 != cmd_opt.preprocess) { if (NULL == file) { fp = cpp_open(); cmd_line = cmd_opt.preprocess; } else { (void) cpp_opt_append(file, NULL); fp = cpp_open(); cpp_opt_trunc(1); } if (NULL == fp) { p = strchr(cmd_line, ' '); if (NULL == p) { length = strlen(cmd_line); } else { length = (p - cmd_line); } command = malloc_vital((sizeof (char)) * (length + 1)); (void) memcpy(command, cmd_line, length); *(command + length) = '\0'; PERROR(command); itm_error(gettext("%1$s: can not start " "%2$s on %3$s\n"), cmd_opt.my_name, command, itm_input_file); exit(ITMC_STATUS_SYS); } else { yyin = fp; } (void) yyparse(); if (NULL == cmd_opt.preprocess_specified) { cpp_close(fp); } } else { if ((NULL == file) || (0 != strcmp("-", file))) { yyin = stdin; } else { yyin = fopen(file, "r"); if (NULL == yyin) { itm_error(gettext("%1$s: can not open %2$s\n"), cmd_opt.my_name, itm_input_file); exit(ITMC_STATUS_CMD2); } } (void) yyparse(); if (stdin != yyin) { (void) fclose(yyin); } } return (ITMC_STATUS_SUCCESS); } static void wait_child(pid_t pid) { int stat_loc; char *msgstr; (void) waitpid(pid, &stat_loc, 0); if (WTERMSIG(stat_loc)) { if (WCOREDUMP(stat_loc)) { msgstr = gettext("signal received: %s, core dumped\n"); } else { msgstr = gettext("signal received: %s\n"); } itm_error(msgstr, strsignal(WTERMSIG(stat_loc))); } } static int fork_error(void) { PERROR(gettext("fork")); exit(ITMC_STATUS_SYS); return (0); /* never return */ } static int parse_opts(int argc, char **argv) { int c; int i; char *p; int error_num = 0; #ifdef YYDEBUG extern int yydebug; #endif /* YYDEBUG */ extern char *optarg; extern int optind; cmd_opt.my_name = basename(*(argv + 0)); if ('\0' == *(cmd_opt.my_name)) { cmd_opt.my_name = ME_DEFAULT; } cmd_opt.preprocess_default = CPP_PATH; cmd_opt.preprocess = cmd_opt.preprocess_default; cmd_opt.strip = 1; /* stripped by default */ while ((c = getopt(argc, argv, "d:i:p:W:D:I:U:fnsM:lo:qX:h")) != EOF) { switch (c) { case 'd': cmd_opt.disassemble = optarg; break; case 'i': cmd_opt.interpreter = optarg; break; case 'p': if (NULL != cmd_opt.preprocess_specified) { (void) fprintf(stderr, gettext("multiple -p options are specified\n")); error_num += 1; } cmd_opt.preprocess_specified = prog_path_expand(optarg); cmd_opt.preprocess = cmd_opt.preprocess_specified; if (NULL == cmd_opt.preprocess) { (void) fprintf(stderr, gettext("cannot find preprocessor \"%s\"\n"), optarg); error_num += 1; } (void) cpp_opt_append(NULL, NULL); p = basename(optarg); if (NULL == p) { *(cmd_opt.cpp_opt + 0) = strdup_vital(optarg); } else { *(cmd_opt.cpp_opt + 0) = strdup_vital(p); } break; case 'W': if (cpp_opt_append(optarg, NULL)) { error_num += 1; } break; case 'I': if (cpp_opt_append("-I", optarg)) { error_num += 1; } break; case 'D': if (cpp_opt_append("-D", optarg)) { error_num += 1; } break; case 'U': if (cpp_opt_append("-U", optarg)) { error_num += 1; } break; case 'f': cmd_opt.force_overwrite = 1; break; case 'n': cmd_opt.no_output = 1; break; case 'M': map_name_type_append(optarg); break; case 'l': cmd_opt.large_table = 1; break; case 'o': cmd_opt.output_file = optarg; break; case 's': cmd_opt.strip = 0; break; case 'q': cmd_opt.quiet = 1; break; #if defined(ENABLE_TRACE) case 'X': cmd_opt.trace = malloc_vital((sizeof (char)) * 128); (void) memset(cmd_opt.trace, 0, (sizeof (char)) * 128); for (p = optarg; *p; p++) { *(cmd_opt.trace + ((*p) & 0x007f)) = 1; } #ifdef YYDEBUG if (TRACE('Y')) yydebug = 1; #endif /* YYDEBUG */ break; #endif /* ENABLE_TRACE */ case 'h': usage(ITMC_STATUS_SUCCESS); break; default: usage(ITMC_STATUS_CMD); } } if (optind < argc) { cmd_opt.input_file_num = (argc - optind); cmd_opt.input_file = malloc_vital((sizeof (char *)) * (argc - optind + 1)); *(cmd_opt.input_file + (argc - optind)) = NULL; } for (i = 0; optind < argc; optind++, i++) { *(cmd_opt.input_file + i) = argv[optind]; } /* check conflict */ if ((1 < cmd_opt.input_file_num) && (NULL != cmd_opt.output_file)) { itm_error(gettext("use -o with single input file\n")); error_num++; } if ((cmd_opt.input_file_num <= 0) && (NULL == cmd_opt.output_file) && (NULL == cmd_opt.disassemble) && (0 == cmd_opt.no_output)) { itm_error(gettext("output file is unnamed. " "use -o to specify output file\n")); error_num++; } if (cmd_opt.disassemble && (cmd_opt.interpreter || cmd_opt.cpp_opt || cmd_opt.preprocess_specified || cmd_opt.input_file || cmd_opt.force_overwrite || cmd_opt.no_output || cmd_opt.map_name_type || cmd_opt.large_table || cmd_opt.output_file)) { itm_error(gettext("-d may not be specified with " "other options\n")); error_num++; } if (error_num) { usage(ITMC_STATUS_CMD); } /* * do not move upward * may conflict with -d option */ if ((NULL == cmd_opt.preprocess_specified) && (NULL != cmd_opt.preprocess_default)) { (void) cpp_opt_append(NULL, NULL); p = basename(cmd_opt.preprocess_default); if (NULL == p) { *(cmd_opt.cpp_opt + 0) = strdup_vital(cmd_opt.preprocess_default); } else { *(cmd_opt.cpp_opt + 0) = strdup_vital(p); } } return (0); } static FILE * cpp_open(void) { pid_t pid; int filedes[2]; int i; for (i = 0; i < cmd_opt.cpp_opt_num; i++) { TRACE_MESSAGE('C', ("%s\n", *(cmd_opt.cpp_opt + i))); } if (pipe(filedes)) { PERROR(gettext("pipe")); itm_error(gettext("failed to open pipe\n")); exit(ITMC_STATUS_SYS); } pid = fork(); if (pid == 0) { /* child */ (void) close(filedes[0]); (void) close(1); (void) dup2(filedes[1], 1); (void) execv(cmd_opt.preprocess, cmd_opt.cpp_opt); exit(0); } else if (pid == (pid_t)(-1)) { /* error */ return (NULL); } else { (void) close(filedes[1]); return (fdopen(filedes[0], "r")); } return (NULL); /* NEVER */ } static int cpp_opt_append(char *opt, char *arg) { size_t opt_len; size_t arg_len; char *new_opt; char **new_opt_list; opt_len = ((NULL == opt) ? 0 : strlen(opt)); arg_len = ((NULL == arg) ? 0 : strlen(arg)); if (0 < (opt_len + arg_len)) { new_opt = malloc_vital(opt_len + arg_len + 1); if (NULL != opt) { (void) memcpy(new_opt, opt, opt_len + 1); } if (NULL != arg) { (void) memcpy(new_opt + opt_len, arg, arg_len + 1); } } else { new_opt = NULL; } if (0 == cmd_opt.cpp_opt_reserved) { cmd_opt.cpp_opt_reserved = 32; cmd_opt.cpp_opt = malloc_vital((sizeof (char *)) * 32); *(cmd_opt.cpp_opt + 0) = strdup_vital("cpp"); cmd_opt.cpp_opt_num = 1; } else if ((cmd_opt.cpp_opt_reserved - 2) <= cmd_opt.cpp_opt_num) { cmd_opt.cpp_opt_reserved += 32; new_opt_list = malloc_vital((sizeof (char *)) * cmd_opt.cpp_opt_reserved); (void) memcpy(new_opt_list, cmd_opt.cpp_opt, (sizeof (char *)) * cmd_opt.cpp_opt_num); (void) memset(new_opt_list + cmd_opt.cpp_opt_num, 0, 32); free(cmd_opt.cpp_opt); cmd_opt.cpp_opt = new_opt_list; } if (NULL != new_opt) { *(cmd_opt.cpp_opt + cmd_opt.cpp_opt_num) = new_opt; cmd_opt.cpp_opt_num += 1; } return (0); } static void cpp_opt_trunc(int num) { if (cmd_opt.cpp_opt_num < num) { num = cmd_opt.cpp_opt_num; } for (; 0 < num; --num) { free(*(cmd_opt.cpp_opt + cmd_opt.cpp_opt_num - 1)); --(cmd_opt.cpp_opt_num); } } static void cpp_close(FILE *fp) { (void) fclose(fp); (void) wait_child(0); } static char * prog_path_expand(const char *base_name) { size_t base_len; size_t dir_len; char path[MAXPATHLEN]; char *p; char *pe; base_len = strlen(base_name); path[0] = '\0'; if (NULL != strchr(base_name, '/')) { if (0 == access(base_name, X_OK)) { return (strdup_vital(base_name)); } else { return (NULL); } } for (p = getenv("PATH"); p; ) { pe = strchr(p, ':'); dir_len = ((NULL == pe) ? strlen(p) : (pe - p)); (void) memcpy(path, p, dir_len); if ((0 != dir_len) && ('/' != path[dir_len - 1])) { path[dir_len] = '/'; dir_len += 1; } if ((dir_len + base_len) < MAXPATHLEN) { (void) memcpy(path + dir_len, base_name, base_len + 1); if (0 == access(path, X_OK)) { return (strdup_vital(path)); } } p = ((NULL == pe) ? NULL : (pe + 1)); } return (NULL); } static void usage(int status) { if (ITMC_STATUS_SUCCESS == status) { (void) fprintf(stdout, gettext("Usage: %1$s [-n] [-f] [-q]\n" " [-p preprocessor] [-W argument]\n" " [-Dname] [-Dname=def] [-Idirectory] [-Uname]\n" " [file ...]\n %2$s -h\n"), cmd_opt.my_name, cmd_opt.my_name); } else { (void) itm_error( gettext("Usage: %1$s [-n] [-f] [-q]\n" " [-p preprocessor] [-W argument]\n" " [-Dname] [-Dname=def] [-Idirectory] [-Uname]\n" " [file ...]\n %2$s -h\n"), cmd_opt.my_name, cmd_opt.my_name); } exit(status); } static char * map_type_name_str(itmc_map_type_t type) { int i; for (i = 0; NULL != map_type_name[i].name; i++) { if (type == map_type_name[i].type) { return (map_type_name[i].name); } } return (""); } static void map_name_type_append(char *optarg) { char *oa; char *oa_save; char *name; char *p; char *phf; int hash_factor = 0; itmc_map_type_t type; itmc_map_name_type_t *m; int i; oa = oa_save = strdup_vital(optarg); while ((NULL != oa) && ('\0' != *oa)) { name = oa; oa = strchr(oa, ','); if (NULL != oa) { *(oa++) = '\0'; } p = strchr(name, '='); if (NULL == p) { type = ITMC_MAP_AUTOMATIC; } else { *(p++) = '\0'; if ('\0' == *p) { type = ITMC_MAP_AUTOMATIC; } else { phf = strchr(p, ':'); if (NULL != phf) { *(phf++) = '\0'; hash_factor = atoi(phf); if (hash_factor < 0) { itm_error(gettext("invalid " "hash factor is " "specified: %s\n"), phf); hash_factor = 0; error_deferred += 1; } } for (i = 0; NULL != map_type_name[i].name; i++) { if (0 == strcmp(p, map_type_name[i].name)) { type = map_type_name[i].type; break; } } if (NULL == map_type_name[i].name) { itm_error(gettext("unknown map type " "is specified: %s\n"), p); error_deferred += 1; continue; } } } if (0 == strcmp(name, "default")) { *name = '\0'; } m = cmd_opt.map_name_type; if (NULL == m) { m = malloc_vital(sizeof (itmc_map_name_type_t)); m->name = strdup_vital(name); m->type = type; m->hash_factor = hash_factor; m->next = NULL; cmd_opt.map_name_type = m; continue; } for (; ; m = m->next) { if (0 == strcmp(name, m->name)) { if (type == m->type) { m = NULL; break; } if ('\0' == *name) { itm_error(gettext("multiple default " "types are specified:" " \"%1$s\" and \"%2$s\"\n"), map_type_name_str(type), map_type_name_str(m->type)); } else { itm_error(gettext("map \"%1$s\" is " "specified as two types \"%2$s\" " "and \"%3$s\"\n"), name, map_type_name_str(type), map_type_name_str(m->type)); } error_deferred += 1; m = NULL; break; } if (NULL == m->next) { break; } } if (NULL != m) { m->next = malloc_vital(sizeof (itmc_map_name_type_t)); m = m->next; m->name = strdup_vital(name); m->type = type; m->hash_factor = hash_factor; m->next = NULL; } } free(oa_save); } void * malloc_vital(size_t size) { void *p; TRACE_MESSAGE('M', ("malloc_vital: %d\n", size)); size = ITMROUNDUP(size); p = (void*) malloc(size); if (NULL == p) { PERROR(gettext("malloc")); exit(ITMC_STATUS_SYS); } (void) memset(p, 0, size); return (p); } static char * strdup_vital(const char *str) { char *p; size_t len; if (NULL == str) { return (NULL); } len = strlen(str) + 1; p = malloc_vital(len); (void) memcpy(p, str, len); return (p); } itm_data_t * str_to_data(int size, char *seq) { itm_data_t *data; data = malloc_vital(sizeof (itm_data_t)); data->size = size; if (size <= sizeof (data->place)) { (void) memmove(&(data->place), seq, size); } else { data->place.itm_ptr = (itm_place2_t)malloc_vital(size); (void) memmove((char *)(data->place.itm_ptr), seq, size); } return (data); } char * name_to_str(itm_data_t *name) { static char *ptr = NULL; static size_t len = 0; size_t req_len; char *p; if (NULL == name) { p = gettext("(no name)"); req_len = strlen(p) + 1; } else { req_len = name->size + 1; } if (len <= req_len) { len += 512; free(ptr); ptr = malloc_vital(len); } if (NULL == name) { (void) memcpy(ptr, p, req_len); *(ptr + req_len) = '\0'; } else if (name->size <= (sizeof (name->place))) { (void) memcpy(ptr, (char *)(&(name->place)), name->size); *(ptr + name->size) = '\0'; } else { (void) memcpy(ptr, (char *)(name->place.itm_ptr), name->size); *(ptr + name->size) = '\0'; } return (ptr); } #define ARGUMENTSMAX (8) char * data_to_hexadecimal(itm_data_t *data) { static int index = 0; static char *ptr[ARGUMENTSMAX] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}; static long len[ARGUMENTSMAX] = { 0, 0, 0, 0, 0, 0, 0, 0}; char *hdp; char *p; long i; int val; size_t req_len; if (ARGUMENTSMAX <= index) index = 0; req_len = (2 * data->size) + 1; if (len[index] <= req_len) { len[index] += 512; free(ptr[index]); ptr[index] = malloc_vital(len[index]); } hdp = ptr[index]; if (data->size <= (sizeof (itm_place_t))) { p = (char *)&(data->place); } else { p = (char *)(data->place.itm_ptr); } for (i = 0; i < data->size; i++, p++) { val = ((*p & 0x00f0) >> 4); if ((0 <= val) && (val <= 9)) { *hdp = '0' + val; } else { *hdp = 'a' + val - 10; } hdp++; val = (*p & 0x000f); if ((0 <= val) && (val <= 9)) { *hdp = '0' + val; } else { *hdp = 'a' + val - 10; } hdp++; } *hdp = '\0'; return (ptr[index++]); } void itm_error(char *format, ...) { va_list ap; va_start(ap, format); if (0 == cmd_opt.quiet) { (void) vfprintf(stderr, format, ap); } va_end(ap); } #if defined(ENABLE_TRACE) static void trace_option(void) { char **pp; int i; if (!(TRACE('o'))) return; itm_error("my_name = %s\n", cmd_opt.my_name); if (NULL == cmd_opt.input_file) { (void) fprintf(stdout, "input_file = (stdin)\n"); } else { for (pp = cmd_opt.input_file; *pp; pp++) { (void) fprintf(stdout, "input_file = %s\n", *pp); } } itm_error("output_file = %s\n", cmd_opt.output_file ? cmd_opt.output_file : "(stdout)"); itm_error("interpreter = %s\n", cmd_opt.interpreter ? cmd_opt.interpreter : "(default)"); if (cmd_opt.cpp_opt) { itm_error("cpp_opt = %s\n", *(cmd_opt.cpp_opt)); for (i = 1; i < cmd_opt.cpp_opt_num; i++) { itm_error("\t%s\n", *(cmd_opt.cpp_opt + i)); } } else { itm_error("cpp_opt = %s\n", "(none)"); } itm_error("preprocess_default = %s\n", cmd_opt.preprocess_default ? cmd_opt.preprocess_default : "(no)"); itm_error("preprocess_specified = %s\n", cmd_opt.preprocess_specified ? cmd_opt.preprocess_specified : "(no)"); itm_error("preprocess = %s\n", cmd_opt.preprocess ? cmd_opt.preprocess : "(no)"); itm_error("disassemble = %s\n", cmd_opt.disassemble ? "yes" : "no"); itm_error("map type ="); if (NULL == cmd_opt.map_name_type) { itm_error("\n"); } else { itmc_map_name_type_t *m; itm_error(" "); m = cmd_opt.map_name_type; itm_error("%s=%s", (((NULL == m->name) || ('\0' == *(m->name))) ? "default" : m->name), map_type_name_str(m->type)); if (0 != m->hash_factor) { itm_error(":%ld\n", m->hash_factor); } else { (void) fputc('\n', stderr); } for (m = m->next; NULL != m; m = m->next) { itm_error(" %s=%s", (((NULL == m->name) || ('\0' == *(m->name))) ? "default" : m->name), map_type_name_str(m->type)); if (0 != m->hash_factor) { itm_error(":%ld\n", m->hash_factor); } else { (void) fputc('\n', stderr); } } } itm_error("large table = %s\n", cmd_opt.large_table ? "true" : "false"); itm_error("overwrite = %s\n", cmd_opt.force_overwrite ? "true" : "false"); itm_error("strip = %s\n", cmd_opt.strip ? "true" : "false"); itm_error("no_output = %s\n", cmd_opt.no_output ? "true" : "false"); itm_error("trace = "); if (NULL == cmd_opt.trace) { itm_error("(no)\n"); } else { for (i = 0x21; i < 0x7f; i++) { if (TRACE(i)) { (void) fputc(i, stderr); } } (void) fputc('\n', stderr); } } #endif /* ENABLE_TRACE */ #if defined(ENABLE_TRACE) extern void trace_message(char *format, ...) { va_list ap; va_start(ap, format); (void) vfprintf(stderr, format, ap); va_end(ap); } #endif /* ENABLE_TRACE */ /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright (c) 1999 by Sun Microsystems, Inc. * All rights reserved. */ #ifndef _ITMCOMP_H #define _ITMCOMP_H #ifdef __cplusplus extern "C" { #endif #include #include "iconv_tm.h" #define ITMC_STATUS_SUCCESS (0) #define ITMC_STATUS_CMD (1) #define ITMC_STATUS_CMD2 (2) #define ITMC_STATUS_BT (3) #define ITMC_STATUS_BT2 (4) #define ITMC_STATUS_SYS (5) #define ITMC_STATUS_SYS2 (6) #define MAXOPNEST 16 /* * exit status: * ITMC_STATUS_SUCCESS * ITMC_STATUS_CMD specified options are wrong * ITMC_STATUS_CMD2 cannot access specified file * ITMC_STATUS_BT Binary Table format error * ITMC_STATUS_BT2 Binary Table against limitation * ITMC_STATUS_SYS resource shortage (e.g.: malloc ) * ITMC_STATUS_SYS2 internal error: never happen */ /* * used later */ struct _itmc_ref; /* * command line option */ typedef enum { ITMC_MAP_UNKNOWN = 0, ITMC_MAP_AUTOMATIC, ITMC_MAP_SIMPLE_INDEX, ITMC_MAP_SIMPLE_HASH, ITMC_MAP_BINARY_SEARCH, ITMC_MAP_DENSE_ENCODING } itmc_map_type_t; typedef struct _itmc_map_name_type { char *name; itmc_map_type_t type; int hash_factor; struct _itmc_map_name_type *next; } itmc_map_name_type_t; typedef struct { char *my_name; char **input_file; int input_file_num; char *output_file; char *interpreter; char **cpp_opt; int cpp_opt_num; int cpp_opt_reserved; char *preprocess_default; char *preprocess_specified; char *preprocess; char *disassemble; int binary_search; itmc_map_name_type_t * map_name_type; int large_table; int force_overwrite; int strip; int quiet; int no_output; char *trace; } cmd_opt_t; /* * data list */ typedef struct { void *obj; itm_num_t num; } obj_array_t; typedef struct _itmc_obj { itm_type_t type; itm_data_t *name; void *obj; struct _itmc_ref *ref[3]; struct _itmc_obj *next; struct _itmc_obj *last; } itmc_obj_t; /* * data pair: used for map and range */ typedef itm_data_t itmc_map_range_t; typedef struct { itm_data_t data0; itm_data_t data1; itmc_map_range_t range; } itmc_data_pair_t; /* * map pair list */ typedef struct _itmc_map { itmc_data_pair_t data_pair; struct _itmc_map *next; struct _itmc_map *last; } itmc_map_t; /* * cross reference: used for relocation */ typedef struct _itmc_ref_link { struct _itmc_ref *ref; struct _itmc_ref_link *next; } itmc_ref_link_t; typedef struct _itmc_name { itm_num_t id; itm_num_t reg_id; itm_data_t name; itm_type_t type; struct _itmc_ref *object; itm_place_t reloc; itmc_ref_link_t *ref_first; itmc_ref_link_t *ref_last; struct _itmc_name *next; } itmc_name_t; typedef struct _itmc_ref { itmc_name_t *name; void *referencee; itm_place_t reloc; itm_size_t size; itm_place_t *referencer; struct _itmc_ref *next; int vertex_index; } itmc_ref_t; /* * action */ typedef struct { itm_type_t type; itm_tbl_hdr_t *tbl_hdr; } itmc_action_t; /* * map attribute */ typedef struct { itm_size_t resultlen; itm_data_t *type; int hash_factor; } itmc_map_attr_t; /* * operation hierarchy */ typedef struct itm_opt_outer { struct itm_opt_outer *link; struct itm_opt_inner *in; itm_tbl_hdr_t *optbl; /* operation object address */ itmc_ref_t *ref; /* corresponding object's ref */ } itm_op_outer_t; typedef struct itm_opt_inner { struct itm_opt_inner *in; itmc_ref_t *ref; /* corresponding object's ref */ } itm_op_inner_t; /* * itm compiler object type */ #define ITMC_OBJ_NONE (0) #define ITMC_OBJ_FIRST (1) #define ITMC_OBJ_ITM (1) #define ITMC_OBJ_STRING (2) #define ITMC_OBJ_DIREC (3) #define ITMC_OBJ_COND (4) #define ITMC_OBJ_MAP (5) #define ITMC_OBJ_OP (6) #define ITMC_OBJ_EXPR (7) #define ITMC_OBJ_DATA (8) #define ITMC_OBJ_ACTION (9) #define ITMC_OBJ_RANGE (10) #define ITMC_OBJ_REGISTER (11) #define ITMC_OBJ_ESCAPESEQ (12) #define ITMC_OBJ_LAST (12) /* * global variable */ extern itmc_ref_t *ref_first[ITMC_OBJ_LAST + 1]; extern itmc_ref_t *ref_last[ITMC_OBJ_LAST + 1]; extern itmc_name_t *name_first; extern itmc_name_t *name_last; extern itm_num_t name_id; extern itm_num_t reg_id; extern itmc_name_t name_lookup_error; extern int error_deferred; extern cmd_opt_t cmd_opt; extern char *itm_input_file; extern char *itm_output_file; extern struct itm_opt_outer *itm_op_outer; /* * macro definition */ #define NSPTR(n) (((n)->size <= (sizeof ((n)->place))) ? \ ((void *)(&((n)->place.itm_64d))) : \ ((void *)((n)->place.itm_ptr))) #if !defined(ROUNDUP) #define ROUNDUP(a, n) (((a) + ((n) - 1)) & ~((n) - 1)) #endif #define ITMROUNDUP(i) ROUNDUP(i, sizeof (uint64_t)) /* * trace */ #if defined(ENABLE_TRACE) #define TRACE(c) ((cmd_opt.trace != 0) && \ (0 != *(cmd_opt.trace + (c & 0x007f)))) #define TRACE_MESSAGE(c, args) ((TRACE(c))? trace_message args: (void)0) #else #define TRACE(c) #define TRACE_MESSAGE(c, args) #endif /* * error */ #define PERROR(s) if (cmd_opt.quiet == 0) perror(s) /* * function prototype */ extern int assemble(itm_hdr_t *); extern void disassemble(char *); extern void *malloc_vital(size_t); extern char *name_to_str(itm_data_t *); extern char *data_to_hexadecimal(itm_data_t *); extern itm_data_t *str_to_data(int, char *); #if defined(ENABLE_TRACE) extern void dump_itm_header(itm_hdr_t *, itm_info_hdr_t *); extern void trace_message(char *, ...); #endif extern char *itm_name_type_name[]; extern void itm_error(char *format, ...); #ifdef __cplusplus } #endif #endif /* !_ITMCOMP_H */ # ident "%Z%%M% %I% %E% SMI" # Copyright 2005 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # CDDL HEADER START # # The contents of this file are subject to the terms of the # Common Development and Distribution License, Version 1.0 only # (the "License"). You may not use this file except in compliance # with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. # See the License for the specific language governing permissions # and limitations under the License. # # When distributing Covered Code, include this CDDL HEADER in each # file and include the License file at usr/src/OPENSOLARIS.LICENSE. # If applicable, add the following below this CDDL HEADER, with the # fields enclosed by brackets "[]" replaced with your own identifying # information: Portions Copyright [yyyy] [name of copyright owner] # # CDDL HEADER END # s;\("Input string too long, limit %d\\n"\);gettext(\1);g s;\("Cannot realloc yytext\\n"\);gettext(\1);g # Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. # # CDDL HEADER START # # The contents of this file are subject to the terms of the # Common Development and Distribution License (the "License"). # You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. # See the License for the specific language governing permissions # and limitations under the License. # # When distributing Covered Code, include this CDDL HEADER in each # file and include the License file at usr/src/OPENSOLARIS.LICENSE. # If applicable, add the following below this CDDL HEADER, with the # fields enclosed by brackets "[]" replaced with your own identifying # information: Portions Copyright [yyyy] [name of copyright owner] # # CDDL HEADER END # # # MAPFILE HEADER START # # WARNING: STOP NOW. DO NOT MODIFY THIS FILE. # Object versioning must comply with the rules detailed in # # usr/src/lib/README.mapfiles # # You should not be making modifications here until you've read the most current # copy of that file. If you need help, contact a gatekeeper for guidance. # # MAPFILE HEADER END # $mapfile_version 2 SYMBOL_SCOPE { global: _icv_open; _icv_close; _icv_iconv; local: *; }; /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright (c) 1999 by Sun Microsystems, Inc. * All rights reserved. */ #ifndef _ICONV_TM_MAPTYPE_H #define _ICONV_TM_MAPTYPE_H #ifdef __cplusplus extern "C" { #endif #include "itmcomp.h" static struct { char *name; itmc_map_type_t type; } map_type_name[] = { {"automatic", ITMC_MAP_AUTOMATIC}, {"index", ITMC_MAP_SIMPLE_INDEX}, {"hash", ITMC_MAP_SIMPLE_HASH}, {"binary", ITMC_MAP_BINARY_SEARCH}, {"dense", ITMC_MAP_DENSE_ENCODING}, {NULL, ITMC_MAP_UNKNOWN}, }; #ifdef __cplusplus } #endif #endif /* !_ICONV_TM_MAPTYPE_H */ // ident "%Z%%M% %I% %E% SMI" // Copyright 2005 Sun Microsystems, Inc. All rights reserved. // Use is subject to license terms. // // CDDL HEADER START // // The contents of this file are subject to the terms of the // Common Development and Distribution License, Version 1.0 only // (the "License"). You may not use this file except in compliance // with the License. // // You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE // or http://www.opensolaris.org/os/licensing. // See the License for the specific language governing permissions // and limitations under the License. // // When distributing Covered Code, include this CDDL HEADER in each // file and include the License file at usr/src/OPENSOLARIS.LICENSE. // If applicable, add the following below this CDDL HEADER, with the // fields enclosed by brackets "[]" replaced with your own identifying // information: Portions Copyright [yyyy] [name of copyright owner] // // CDDL HEADER END // // // ISO-2022-JP to eucJP // #include ISO-2022-JP%eucJP { operation init { cs = 0; }; operation reset { if (cs != 0) { // Emit state reset sequence, ESC ( J, for // ISO-2022-JP. output = 0x1b284a; } operation init; }; direction { condition { // JIS X 0201 Latin (ASCII) between 0x00...0x7f; } operation { if (cs != 0) { // We will emit four bytes. if (outputsize <= 3) { error E2BIG; } // Emit state reset sequence, ESC ( J. output = 0x1b284a; cs = 0; } else { if (outputsize <= 0) { error E2BIG; } } output = input[0]; // Move input buffer pointer one byte. discard; }; condition { // JIS X 0208 between 0xa1a1...0xfefe; } operation { if (cs != 1) { if (outputsize <= 4) { error E2BIG; } // Emit JIS X 0208 sequence, ESC $ B. output = 0x1b2442; cs = 1; } else { if (outputsize <= 1) { error E2BIG; } } output = (input[0] & 0x7f); output = (input[1] & 0x7f); // Move input buffer pointer two bytes. discard 2; }; condition { // JIS X 0201 Kana between 0x8ea1...0x8edf; } operation { if (cs != 2) { if (outputsize <= 3) { error E2BIG; } // Emit JIS X 0201 Kana sequence, // ESC ( I. output = 0x1b2849; cs = 2; } else { if (outputsize <= 0) { error E2BIG; } } output = (input[1] & 127); // Move input buffer pointer two bytes. discard 2; }; condition { // JIS X 0212 between 0x8fa1a1...0x8ffefe; } operation { if (cs != 3) { if (outputsize <= 5) { error E2BIG; } // Emit JIS X 0212 sequence, ESC $ ( D. output = 0x1b242844; cs = 3; } else { if (outputsize <= 1) { error E2BIG; } } output = (input[1] & 127); output = (input[2] & 127); discard 3; }; true operation { // error error EILSEQ; }; }; } // ident "%Z%%M% %I% %E% SMI" // Copyright 2005 Sun Microsystems, Inc. All rights reserved. // Use is subject to license terms. // // CDDL HEADER START // // The contents of this file are subject to the terms of the // Common Development and Distribution License, Version 1.0 only // (the "License"). You may not use this file except in compliance // with the License. // // You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE // or http://www.opensolaris.org/os/licensing. // See the License for the specific language governing permissions // and limitations under the License. // // When distributing Covered Code, include this CDDL HEADER in each // file and include the License file at usr/src/OPENSOLARIS.LICENSE. // If applicable, add the following below this CDDL HEADER, with the // fields enclosed by brackets "[]" replaced with your own identifying // information: Portions Copyright [yyyy] [name of copyright owner] // // CDDL HEADER END // // // from ISO646 to ISO8859-1 // ISO646%ISO8859_1 { map { 0x00...0x7f 0x00 // default error // if no input sequence match, it occur EILSEQ. }; } // ident "%Z%%M% %I% %E% SMI" // Copyright 2005 Sun Microsystems, Inc. All rights reserved. // Use is subject to license terms. // // CDDL HEADER START // // The contents of this file are subject to the terms of the // Common Development and Distribution License, Version 1.0 only // (the "License"). You may not use this file except in compliance // with the License. // // You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE // or http://www.opensolaris.org/os/licensing. // See the License for the specific language governing permissions // and limitations under the License. // // When distributing Covered Code, include this CDDL HEADER in each // file and include the License file at usr/src/OPENSOLARIS.LICENSE. // If applicable, add the following below this CDDL HEADER, with the // fields enclosed by brackets "[]" replaced with your own identifying // information: Portions Copyright [yyyy] [name of copyright owner] // // CDDL HEADER END // // // from ISO8859-1 to ISO646 // ISO8859_1%ISO646 { map { default 0x3f 0x00...0x7f 0x00 }; } // ident "%Z%%M% %I% %E% SMI" // Copyright 2005 Sun Microsystems, Inc. All rights reserved. // Use is subject to license terms. // // CDDL HEADER START // // The contents of this file are subject to the terms of the // Common Development and Distribution License, Version 1.0 only // (the "License"). You may not use this file except in compliance // with the License. // // You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE // or http://www.opensolaris.org/os/licensing. // See the License for the specific language governing permissions // and limitations under the License. // // When distributing Covered Code, include this CDDL HEADER in each // file and include the License file at usr/src/OPENSOLARIS.LICENSE. // If applicable, add the following below this CDDL HEADER, with the // fields enclosed by brackets "[]" replaced with your own identifying // information: Portions Copyright [yyyy] [name of copyright owner] // // CDDL HEADER END // // // ISO8859-1 to UTF-8 mapping: // ISO8859-1%UTF-8 { direction { condition { between 0x0...0x7f; } map { 0x0...0x7f 0x0 }; condition { between 0x80...0xff; } map { 0x80 0xc280 0x81 0xc281 0x82 0xc282 0x83 0xc283 0x84 0xc284 0x85 0xc285 0x86 0xc286 0x87 0xc287 0x88 0xc288 0x89 0xc289 0x8a 0xc28a 0x8b 0xc28b 0x8c 0xc28c 0x8d 0xc28d 0x8e 0xc28e 0x8f 0xc28f 0x90 0xc290 0x91 0xc291 0x92 0xc292 0x93 0xc293 0x94 0xc294 0x95 0xc295 0x96 0xc296 0x97 0xc297 0x98 0xc298 0x99 0xc299 0x9a 0xc29a 0x9b 0xc29b 0x9c 0xc29c 0x9d 0xc29d 0x9e 0xc29e 0x9f 0xc29f 0xa0 0xc2a0 0xa1 0xc2a1 0xa2 0xc2a2 0xa3 0xc2a3 0xa4 0xc2a4 0xa5 0xc2a5 0xa6 0xc2a6 0xa7 0xc2a7 0xa8 0xc2a8 0xa9 0xc2a9 0xaa 0xc2aa 0xab 0xc2ab 0xac 0xc2ac 0xad 0xc2ad 0xae 0xc2ae 0xaf 0xc2af 0xb0 0xc2b0 0xb1 0xc2b1 0xb2 0xc2b2 0xb3 0xc2b3 0xb4 0xc2b4 0xb5 0xc2b5 0xb6 0xc2b6 0xb7 0xc2b7 0xb8 0xc2b8 0xb9 0xc2b9 0xba 0xc2ba 0xbb 0xc2bb 0xbc 0xc2bc 0xbd 0xc2bd 0xbe 0xc2be 0xbf 0xc2bf 0xc0 0xc380 0xc1 0xc381 0xc2 0xc382 0xc3 0xc383 0xc4 0xc384 0xc5 0xc385 0xc6 0xc386 0xc7 0xc387 0xc8 0xc388 0xc9 0xc389 0xca 0xc38a 0xcb 0xc38b 0xcc 0xc38c 0xcd 0xc38d 0xce 0xc38e 0xcf 0xc38f 0xd0 0xc390 0xd1 0xc391 0xd2 0xc392 0xd3 0xc393 0xd4 0xc394 0xd5 0xc395 0xd6 0xc396 0xd7 0xc397 0xd8 0xc398 0xd9 0xc399 0xda 0xc39a 0xdb 0xc39b 0xdc 0xc39c 0xdd 0xc39d 0xde 0xc39e 0xdf 0xc39f 0xe0 0xc3a0 0xe1 0xc3a1 0xe2 0xc3a2 0xe3 0xc3a3 0xe4 0xc3a4 0xe5 0xc3a5 0xe6 0xc3a6 0xe7 0xc3a7 0xe8 0xc3a8 0xe9 0xc3a9 0xea 0xc3aa 0xeb 0xc3ab 0xec 0xc3ac 0xed 0xc3ad 0xee 0xc3ae 0xef 0xc3af 0xf0 0xc3b0 0xf1 0xc3b1 0xf2 0xc3b2 0xf3 0xc3b3 0xf4 0xc3b4 0xf5 0xc3b5 0xf6 0xc3b6 0xf7 0xc3b7 0xf8 0xc3b8 0xf9 0xc3b9 0xfa 0xc3ba 0xfb 0xc3bb 0xfc 0xc3bc 0xfd 0xc3bd 0xfe 0xc3be 0xff 0xc3bf }; }; } # # CDDL HEADER START # # The contents of this file are subject to the terms of the # Common Development and Distribution License (the "License"). # You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. # See the License for the specific language governing permissions # and limitations under the License. # # When distributing Covered Code, include this CDDL HEADER in each # file and include the License file at usr/src/OPENSOLARIS.LICENSE. # If applicable, add the following below this CDDL HEADER, with the # fields enclosed by brackets "[]" replaced with your own identifying # information: Portions Copyright [yyyy] [name of copyright owner] # # CDDL HEADER END # # Copyright 2006 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # INPUTFILES = ISO8859-1_to_UTF-8.src UTF-8_to_ISO8859-1.src\ eucJP_to_ISO-2022-JP.src ISO-2022-JP_to_eucJP.src \ ISO646_to_ISO8859-1.src ISO8859-1_to_ISO646.src OUTPUTFILES = ISO646%ISO8859-1.bt ISO8859-1%ISO646.bt # ONLY TWO binarytables are deliverables # ISO8859-1%UTF-8.bt UTF-8%ISO8859-1.bt # eucJP%ISO-2022-JP.bt ISO-2022-JP%eucJP.bt \ # ISO646%ISO8859-1.bt ISO8859-1%ISO646.bt # OUTPUTFILES = $(INPUTFILES:%.src=%.bt) NEVER USE ( WATCH OUT FILE NAME ) # include ../../../lib/Makefile.lib include ../../Makefile.cmd ROOTICONVDIRS = $(ROOTLIB)/iconv ROOTDIRS = $(ROOTICONVDIRS)/geniconvtbl SRCSDIRS = $(ROOTDIRS)/srcs BTSDIRS = $(ROOTDIRS)/binarytables ROOTINPUTFILES = $(INPUTFILES:%=$(SRCSDIRS)/%) ROOTOUTPUTFILES = $(OUTPUTFILES:%=$(BTSDIRS)/%) $(ROOTINPUTFILES) : FILEMODE = 444 $(ROOTOUTPUTFILES) : FILEMODE = 444 .KEEP_STATE: .PARALLEL: $(OUTPUTFILES) all: $(OUTPUTFILES) install: all $(ROOTOUTPUTFILES) $(ROOTINPUTFILES) clean clobber: $(RM) $(OUTPUTFILES) ISO8859-1%UTF-8.bt: ISO8859-1_to_UTF-8.src $(GENICONVTBL) -o $@ -f ISO8859-1_to_UTF-8.src UTF-8%ISO8859_1.bt: UTF-8_to_ISO8859_1.src $(GENICONVTBL) -o $@ -f UTF-8_to_ISO8859_1.src eucJP%ISO-2022-JP.bt: eucJP_to_ISO-2022-JP.src $(GENICONVTBL) -o $@ -f eucJP_to_ISO-2022-JP.src ISO-2022-JP%eucJP.bt: ISO-2022-JP_to_eucJP.src $(GENICONVTBL) -o $@ -f ISO-2022-JP_to_eucJP.src ISO646%ISO8859-1.bt: ISO646_to_ISO8859-1.src $(GENICONVTBL) -o $@ -f ISO646_to_ISO8859-1.src ISO8859-1%ISO646.bt: ISO8859-1_to_ISO646.src $(GENICONVTBL) -o $@ -f ISO8859-1_to_ISO646.src # install rule # $(SRCSDIRS)/%: % $(SRCSDIRS) $(INS.file) $(BTSDIRS)/%: % $(BTSDIRS) $(INS.file) $(SRCSDIRS) $(BTSDIRS): $(ROOTDIRS) $(INS.dir) $(ROOTDIRS): $(ROOTICONVDIRS) $(INS.dir) $(ROOTICONVDIRS): $(INS.dir) $(SRCSDIRS)/%: $(SRCSDIRS) % $(INS.file) $(BTSDIRS)/%: $(BTSDIRS) % $(INS.file) # rule of making BinaryTable # ( must be placed after install rule ) # # .SUFFIXES: $(SUFFIXES) .src # .SUFFIXES: $(SUFFIXES) .bt # # %.bt: %.src # $(GENICONVTBL) -o $@ -f $< # include ../../Makefile.targ // ident "%Z%%M% %I% %E% SMI" // Copyright 2005 Sun Microsystems, Inc. All rights reserved. // Use is subject to license terms. // // CDDL HEADER START // // The contents of this file are subject to the terms of the // Common Development and Distribution License, Version 1.0 only // (the "License"). You may not use this file except in compliance // with the License. // // You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE // or http://www.opensolaris.org/os/licensing. // See the License for the specific language governing permissions // and limitations under the License. // // When distributing Covered Code, include this CDDL HEADER in each // file and include the License file at usr/src/OPENSOLARIS.LICENSE. // If applicable, add the following below this CDDL HEADER, with the // fields enclosed by brackets "[]" replaced with your own identifying // information: Portions Copyright [yyyy] [name of copyright owner] // // CDDL HEADER END // // // UTF-8 to ISO8859-1 mapping: // UTF-8%ISO8859-1 { direction { condition { between 0x0...0x7f; } map { 0x0...0x7f 0x0 }; condition { between 0xc280...0xc3bf; } map { 0xc280 0x80 0xc281 0x81 0xc282 0x82 0xc283 0x83 0xc284 0x84 0xc285 0x85 0xc286 0x86 0xc287 0x87 0xc288 0x88 0xc289 0x89 0xc28a 0x8a 0xc28b 0x8b 0xc28c 0x8c 0xc28d 0x8d 0xc28e 0x8e 0xc28f 0x8f 0xc290 0x90 0xc291 0x91 0xc292 0x92 0xc293 0x93 0xc294 0x94 0xc295 0x95 0xc296 0x96 0xc297 0x97 0xc298 0x98 0xc299 0x99 0xc29a 0x9a 0xc29b 0x9b 0xc29c 0x9c 0xc29d 0x9d 0xc29e 0x9e 0xc29f 0x9f 0xc2a0 0xa0 0xc2a1 0xa1 0xc2a2 0xa2 0xc2a3 0xa3 0xc2a4 0xa4 0xc2a5 0xa5 0xc2a6 0xa6 0xc2a7 0xa7 0xc2a8 0xa8 0xc2a9 0xa9 0xc2aa 0xaa 0xc2ab 0xab 0xc2ac 0xac 0xc2ad 0xad 0xc2ae 0xae 0xc2af 0xaf 0xc2b0 0xb0 0xc2b1 0xb1 0xc2b2 0xb2 0xc2b3 0xb3 0xc2b4 0xb4 0xc2b5 0xb5 0xc2b6 0xb6 0xc2b7 0xb7 0xc2b8 0xb8 0xc2b9 0xb9 0xc2ba 0xba 0xc2bb 0xbb 0xc2bc 0xbc 0xc2bd 0xbd 0xc2be 0xbe 0xc2bf 0xbf 0xc380 0xc0 0xc381 0xc1 0xc382 0xc2 0xc383 0xc3 0xc384 0xc4 0xc385 0xc5 0xc386 0xc6 0xc387 0xc7 0xc388 0xc8 0xc389 0xc9 0xc38a 0xca 0xc38b 0xcb 0xc38c 0xcc 0xc38d 0xcd 0xc38e 0xce 0xc38f 0xcf 0xc390 0xd0 0xc391 0xd1 0xc392 0xd2 0xc393 0xd3 0xc394 0xd4 0xc395 0xd5 0xc396 0xd6 0xc397 0xd7 0xc398 0xd8 0xc399 0xd9 0xc39a 0xda 0xc39b 0xdb 0xc39c 0xdc 0xc39d 0xdd 0xc39e 0xde 0xc39f 0xdf 0xc3a0 0xe0 0xc3a1 0xe1 0xc3a2 0xe2 0xc3a3 0xe3 0xc3a4 0xe4 0xc3a5 0xe5 0xc3a6 0xe6 0xc3a7 0xe7 0xc3a8 0xe8 0xc3a9 0xe9 0xc3aa 0xea 0xc3ab 0xeb 0xc3ac 0xec 0xc3ad 0xed 0xc3ae 0xee 0xc3af 0xef 0xc3b0 0xf0 0xc3b1 0xf1 0xc3b2 0xf2 0xc3b3 0xf3 0xc3b4 0xf4 0xc3b5 0xf5 0xc3b6 0xf6 0xc3b7 0xf7 0xc3b8 0xf8 0xc3b9 0xf9 0xc3ba 0xfa 0xc3bb 0xfb 0xc3bc 0xfc 0xc3bd 0xfd 0xc3be 0xfe 0xc3bf 0xff }; // We convert every other character to '?', i.e., non-identical // character. true operation { output = 0x3f; discard 1; }; }; } // Copyright 2005 Sun Microsystems, Inc. All rights reserved. // Use is subject to license terms. // // CDDL HEADER START // // The contents of this file are subject to the terms of the // Common Development and Distribution License, Version 1.0 only // (the "License"). You may not use this file except in compliance // with the License. // // You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE // or http://www.opensolaris.org/os/licensing. // See the License for the specific language governing permissions // and limitations under the License. // // When distributing Covered Code, include this CDDL HEADER in each // file and include the License file at usr/src/OPENSOLARIS.LICENSE. // If applicable, add the following below this CDDL HEADER, with the // fields enclosed by brackets "[]" replaced with your own identifying // information: Portions Copyright [yyyy] [name of copyright owner] // // CDDL HEADER END // // ident "%Z%%M% %I% %E% SMI" // // eucJP to SJIS // #include #define SS2 0x008e #define SS3 0x008f eucJP%SJIS { operation init { cs = 0; offset = 0; }; direction { condition { cs == 2; } operation { output = input[0]; cs = 0; discard; }; condition { cs == 1; } operation { var_input = input[0] & 0x7f; var_input = var_input + offset; if (var_input >= 0x7f) { var_input = var_input + 0x01; } output = var_input; cs = 0; discard; }; condition { between 0x00 ... 0x7f ; } operation { if ( outputsize < 1 ) { error E2BIG; } output = input[0]; discard; }; condition { between SS2 ... SS2 ; } operation { // Note this, in the .c file check is made // against ileft > 0 , but it's since the // ileft is already decremented. if ( inputsize > 1 ) { if ( ( input[1] >= 0xa1 ) && ( input[1] <= 0xfe )) { if (outputsize < 1 ) { error E2BIG; } cs = 2; } else { error EILSEQ; } } else { error EINVAL; } }; condition { between 0xa1 ... 0xfe; } operation { if ( inputsize > 1 ) { if ( ( input[1] >= 0xa1 ) && ( input[1] <= 0xfe)) { if ( outputsize < 2 ) { error E2BIG; } cs = 1; var_input = input[0] & 0x7f; if ( var_input & 0x01) { offset = 0x1f; } else { offset = 0x7d; } var_input = ((var_input - 0x21 ) >> 1) + 0x81; if ( var_input > 0x9f ) { var_input = var_input + 0x40; } output = var_input; discard; } else { error EINVAL; } } else { error EILSEQ; } }; true operation { error EILSEQ; }; }; } # ident "%Z%%M% %I% %E% SMI" # Copyright 2005 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # CDDL HEADER START # # The contents of this file are subject to the terms of the # Common Development and Distribution License, Version 1.0 only # (the "License"). You may not use this file except in compliance # with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. # See the License for the specific language governing permissions # and limitations under the License. # # When distributing Covered Code, include this CDDL HEADER in each # file and include the License file at usr/src/OPENSOLARIS.LICENSE. # If applicable, add the following below this CDDL HEADER, with the # fields enclosed by brackets "[]" replaced with your own identifying # information: Portions Copyright [yyyy] [name of copyright owner] # # CDDL HEADER END # # s;\("syntax error - cannot backup"\);gettext(\1);g s;\("yacc stack overflow"\);gettext(\1);g s;\("syntax error"\);gettext(\1);g