4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright (c) 1999 by Sun Microsystems, Inc.
24 * All rights reserved.
27 #pragma ident "%Z%%M% %I% %E% SMI"
37 #include <sys/types.h>
43 struct itm_opt_outer
*itm_op_outer
= NULL
;
45 #if defined(ENABLE_TRACE)
46 static char *itmc_obj_names
[] = {
58 "ITMC_OBJ_RAGISTER(11)",
59 "ITMC_OBJ_ESCAPESEQ(12)"
63 #define TRACE_FMT(comment) \
64 comment ## " size=%4ld(0x%4lx); 64d=0x%16" PRIx64 "; ptr=%4p(%c...)\n"
65 #define TRACE_DT(data, refer) \
66 data.size, data.size, data.place.itm_64d, \
68 (((refer) == 0) ? (not_refer): \
69 (((sizeof (itm_place_t) < data.size))? \
70 *((char *)(((char *)itm_header) + data.place.itm_ptr)): \
76 #define NAMETRACE(comment) \
78 TRACE_MESSAGE('p', (#comment "\n")); \
79 for (name = name_first; name; name = name->next) {\
82 TRACE_DT(name->name, NOREFER)));\
86 /* static int not_refer = (~0); */
90 static void relocation_I(itm_hdr_t
*, itm_info_hdr_t
*);
91 static void relocation_II(itm_hdr_t
*, itm_info_hdr_t
*);
93 static void fix_itmc_ref_reloc(itmc_ref_t
*, itm_place2_t
);
94 static void analysis(itm_info_hdr_t
*);
95 static void analysis2(void);
96 static void output(itm_hdr_t
*, itm_info_hdr_t
*);
102 * Assemble main function
106 assemble(itm_hdr_t
*itm_header
)
111 itm_info_hdr_t
*info_header
;
117 if (0 < error_deferred
) {
118 itm_error(gettext("number of deferred error: %d\n"),
120 exit(ITMC_STATUS_BT
);
123 itm_header
->ident
[0] = ITM_IDENT_0
;
124 itm_header
->ident
[1] = ITM_IDENT_1
;
125 itm_header
->ident
[2] = ITM_IDENT_2
;
126 itm_header
->ident
[3] = ITM_IDENT_3
;
128 itm_header
->spec
[0] = ITM_SPEC_0
;
129 itm_header
->spec
[1] = ITM_SPEC_1
;
130 itm_header
->spec
[2] = ITM_SPEC_2
;
131 mach_spec
.longval
= 1;
132 switch (sizeof (long)) {
134 if (0 == mach_spec
.charval
[0]) {
135 itm_header
->spec
[3] = ITM_SPEC_3_32_BIG_ENDIAN
;
137 itm_header
->spec
[3] = ITM_SPEC_3_32_LITTLE_ENDIAN
;
141 if (0 == mach_spec
.charval
[0]) {
142 itm_header
->spec
[3] = ITM_SPEC_3_64_BIG_ENDIAN
;
144 itm_header
->spec
[3] = ITM_SPEC_3_64_LITTLE_ENDIAN
;
149 itm_header
->version
[0] = ITM_VER_0
;
150 itm_header
->version
[1] = ITM_VER_1
;
151 itm_header
->version
[2] = ITM_VER_2
;
152 itm_header
->version
[3] = ITM_VER_3
;
154 itm_header
->itm_size
.itm_ptr
= 0;
156 itm_header
->reg_num
= reg_id
;
158 itm_header
->itm_hdr_size
= (sizeof (itm_hdr_t
));
160 info_header
= malloc_vital(sizeof (itm_info_hdr_t
));
161 (void) memset(info_header
, 0, sizeof (itm_info_hdr_t
));
163 relocation_I(itm_header
, info_header
);
164 relocation_II(itm_header
, info_header
);
167 (" ref name referencee reloc(10)"
168 "size(10) referencer next\n"));
169 for (i
= ITMC_OBJ_FIRST
; i
<= ITMC_OBJ_LAST
; i
++) {
170 TRACE_MESSAGE('r', ("%s\n", itmc_obj_names
[i
]));
171 for (ref
= ref_first
[i
], j
= 0; ref
; ref
= ref
->next
, j
++) {
173 (" %2d:%08p:%08p:%08p:%8p:%8ld:%08p:%08p\n",
175 ref
->name
, ref
->referencee
,
176 ref
->reloc
.itm_ptr
, ref
->size
,
177 ref
->referencer
, ref
->next
));
181 analysis(info_header
);
183 if (0 < error_deferred
) {
184 itm_error(gettext("number of deferred error: %d\n"),
186 exit(ITMC_STATUS_BT
);
189 output(itm_header
, info_header
);
195 * Fix reloc of itmc_ref_t, and fix reloc of itmc_name_t
199 relocation_I(itm_hdr_t
*itm_header
, itm_info_hdr_t
*info_header
)
208 * determin section size
212 for (sec_num
= 0, sec_size
= 0, ref
= ref_first
[ITMC_OBJ_STRING
];
213 ref
; sec_num
+= 1, sec_size
+= ref
->size
, ref
= ref
->next
) {}
214 sec_size
= ITMROUNDUP(sec_size
);
215 info_header
->str_plc_tbl
.size
= ((sizeof (itm_data_t
)) * sec_num
);
216 info_header
->str_plc_tbl
.number
= sec_num
;
217 info_header
->str_sec
.size
= sec_size
;
218 info_header
->str_sec
.number
= sec_num
;
221 for (sec_num
= 0, sec_size
= 0, ref
= ref_first
[ITMC_OBJ_DIREC
];
222 ref
; sec_num
+= 1, sec_size
+= ref
->size
, ref
= ref
->next
) {}
223 sec_size
= ITMROUNDUP(sec_size
);
224 info_header
->direc_plc_tbl
.size
= sec_num
* (sizeof (itm_place_t
));
225 info_header
->direc_plc_tbl
.number
= sec_num
;
226 info_header
->direc_tbl_sec
.size
= sec_size
;
227 info_header
->direc_tbl_sec
.number
= sec_num
;
230 for (sec_num
= 0, sec_size
= 0, ref
= ref_first
[ITMC_OBJ_COND
];
231 ref
; sec_num
+= 1, sec_size
+= ref
->size
, ref
= ref
->next
) {}
232 sec_size
= ITMROUNDUP(sec_size
);
233 info_header
->cond_plc_tbl
.size
= sec_num
* (sizeof (itm_place_t
));
234 info_header
->cond_plc_tbl
.number
= sec_num
;
235 info_header
->cond_tbl_sec
.size
= sec_size
;
236 info_header
->cond_tbl_sec
.number
= sec_num
;
239 for (sec_num
= 0, sec_size
= 0, ref
= ref_first
[ITMC_OBJ_MAP
];
240 ref
; sec_num
+= 1, sec_size
+= ref
->size
, ref
= ref
->next
) {
242 sec_size
= ITMROUNDUP(sec_size
);
243 info_header
->map_plc_tbl
.size
= sec_num
* (sizeof (itm_place_t
));
244 info_header
->map_plc_tbl
.number
= sec_num
;
245 info_header
->map_tbl_sec
.size
= sec_size
;
246 info_header
->map_tbl_sec
.number
= sec_num
;
249 for (sec_num
= 0, sec_size
= 0, ref
= ref_first
[ITMC_OBJ_OP
];
250 ref
; sec_num
+= 1, sec_size
+= ref
->size
, ref
= ref
->next
) {
252 sec_size
= ITMROUNDUP(sec_size
);
253 info_header
->op_plc_tbl
.size
= sec_num
* (sizeof (itm_place_t
));
254 info_header
->op_plc_tbl
.number
= sec_num
;
255 info_header
->op_tbl_sec
.size
= sec_size
;
256 info_header
->op_tbl_sec
.number
= sec_num
;
259 for (sec_num
= 0, sec_size
= 0, ref
= ref_first
[ITMC_OBJ_RANGE
];
260 ref
; sec_num
+= 1, sec_size
+= ref
->size
, ref
= ref
->next
) {}
261 sec_size
= ITMROUNDUP(sec_size
);
262 info_header
->range_plc_tbl
.size
= sec_num
* (sizeof (itm_place_t
));
263 info_header
->range_plc_tbl
.number
= sec_num
;
264 info_header
->range_tbl_sec
.size
= sec_size
;
265 info_header
->range_tbl_sec
.number
= sec_num
;
267 /* escapeseq section */
268 for (sec_num
= 0, sec_size
= 0, ref
= ref_first
[ITMC_OBJ_ESCAPESEQ
];
269 ref
; sec_num
+= 1, sec_size
+= ref
->size
, ref
= ref
->next
) {}
270 sec_size
= ITMROUNDUP(sec_size
);
271 info_header
->escapeseq_plc_tbl
.size
= sec_num
* (sizeof (itm_place_t
));
272 info_header
->escapeseq_plc_tbl
.number
= sec_num
;
273 info_header
->escapeseq_tbl_sec
.size
= sec_size
;
274 info_header
->escapeseq_tbl_sec
.number
= sec_num
;
277 for (sec_num
= 0, sec_size
= 0, ref
= ref_first
[ITMC_OBJ_DATA
];
278 ref
; sec_num
+= 1, sec_size
+= ref
->size
, ref
= ref
->next
) {}
279 for (ref
= ref_first
[ITMC_OBJ_EXPR
];
280 ref
; sec_num
+= 1, sec_size
+= ref
->size
, ref
= ref
->next
) {}
281 sec_size
= ITMROUNDUP(sec_size
);
282 info_header
->data_plc_tbl
.size
= ((sizeof (itm_place_t
)) * sec_num
);
283 info_header
->data_plc_tbl
.number
= sec_num
;
284 info_header
->data_sec
.size
= sec_size
;
285 info_header
->data_sec
.number
= sec_num
;
290 for (sec_num
= 0, sec_size
= 0, name
= name_first
;
291 name
; name
= name
->next
) {
292 if ((ITMC_OBJ_REGISTER
!= name
->type
) &&
293 (0 != name
->name
.size
)) {
294 if ((sizeof (itm_place_t
)) < name
->name
.size
) {
295 sec_size
+= name
->name
.size
;
301 info_header
->name_plc_tbl
.size
= ((sizeof (itm_data_t
)) * sec_num
);
302 info_header
->name_plc_tbl
.number
= sec_num
;
304 for (sec_num
= 0, name
= name_first
; name
; name
= name
->next
) {
305 if ((ITMC_OBJ_REGISTER
== name
->type
) &&
306 (0 != name
->name
.size
)) {
307 if ((sizeof (itm_place_t
)) < name
->name
.size
) {
308 sec_size
+= name
->name
.size
;
314 sec_size
= ITMROUNDUP(sec_size
);
315 info_header
->reg_plc_tbl
.size
=
316 ((sizeof (itm_data_t
)) * (itm_header
->reg_num
));
317 info_header
->reg_plc_tbl
.number
= itm_header
->reg_num
;
319 info_header
->name_sec
.size
= sec_size
;
320 info_header
->name_sec
.number
= sec_num2
;
325 info_header
->str_sec
.place
.itm_ptr
=
327 (sizeof (itm_hdr_t
));
328 info_header
->direc_tbl_sec
.place
.itm_ptr
=
329 info_header
->str_sec
.place
.itm_ptr
+
330 info_header
->str_sec
.size
;
331 info_header
->cond_tbl_sec
.place
.itm_ptr
=
332 info_header
->direc_tbl_sec
.place
.itm_ptr
+
333 info_header
->direc_tbl_sec
.size
;
334 info_header
->map_tbl_sec
.place
.itm_ptr
=
335 info_header
->cond_tbl_sec
.place
.itm_ptr
+
336 info_header
->cond_tbl_sec
.size
;
337 info_header
->op_tbl_sec
.place
.itm_ptr
=
338 info_header
->map_tbl_sec
.place
.itm_ptr
+
339 info_header
->map_tbl_sec
.size
;
341 info_header
->range_tbl_sec
.place
.itm_ptr
=
342 info_header
->op_tbl_sec
.place
.itm_ptr
+
343 info_header
->op_tbl_sec
.size
;
345 info_header
->escapeseq_tbl_sec
.place
.itm_ptr
=
346 info_header
->range_tbl_sec
.place
.itm_ptr
+
347 info_header
->range_tbl_sec
.size
;
349 info_header
->data_sec
.place
.itm_ptr
=
350 info_header
->escapeseq_tbl_sec
.place
.itm_ptr
+
351 info_header
->escapeseq_tbl_sec
.size
;
354 * adjust place: optional
357 if (0 == cmd_opt
.strip
) {
358 itm_header
->info_hdr
.itm_ptr
=
359 info_header
->data_sec
.place
.itm_ptr
+
360 info_header
->data_sec
.size
;
362 info_header
->direc_plc_tbl
.place
.itm_ptr
=
363 itm_header
->info_hdr
.itm_ptr
+
364 (sizeof (itm_info_hdr_t
));
365 info_header
->cond_plc_tbl
.place
.itm_ptr
=
366 info_header
->direc_plc_tbl
.place
.itm_ptr
+
367 info_header
->direc_plc_tbl
.size
;
368 info_header
->map_plc_tbl
.place
.itm_ptr
=
369 info_header
->cond_plc_tbl
.place
.itm_ptr
+
370 info_header
->cond_plc_tbl
.size
;
371 info_header
->op_plc_tbl
.place
.itm_ptr
=
372 info_header
->map_plc_tbl
.place
.itm_ptr
+
373 info_header
->map_plc_tbl
.size
;
375 info_header
->str_plc_tbl
.place
.itm_ptr
=
376 info_header
->op_plc_tbl
.place
.itm_ptr
+
377 info_header
->op_plc_tbl
.size
;
378 info_header
->range_plc_tbl
.place
.itm_ptr
=
379 info_header
->str_plc_tbl
.place
.itm_ptr
+
380 info_header
->str_plc_tbl
.size
;
381 info_header
->escapeseq_plc_tbl
.place
.itm_ptr
=
382 info_header
->range_plc_tbl
.place
.itm_ptr
+
383 info_header
->range_plc_tbl
.size
;
384 info_header
->data_plc_tbl
.place
.itm_ptr
=
385 info_header
->escapeseq_plc_tbl
.place
.itm_ptr
+
386 info_header
->escapeseq_plc_tbl
.size
;
387 info_header
->name_plc_tbl
.place
.itm_ptr
=
388 info_header
->data_plc_tbl
.place
.itm_ptr
+
389 info_header
->data_plc_tbl
.size
;
390 info_header
->reg_plc_tbl
.place
.itm_ptr
=
391 info_header
->name_plc_tbl
.place
.itm_ptr
+
392 info_header
->name_plc_tbl
.size
;
395 info_header
->name_sec
.place
.itm_ptr
=
396 info_header
->reg_plc_tbl
.place
.itm_ptr
+
397 info_header
->reg_plc_tbl
.size
;
404 if (0 == cmd_opt
.strip
) {
405 itm_header
->itm_size
.itm_ptr
=
406 info_header
->name_sec
.place
.itm_ptr
+
407 info_header
->name_sec
.size
;
409 itm_header
->itm_size
.itm_ptr
=
410 info_header
->data_sec
.place
.itm_ptr
+
411 info_header
->data_sec
.size
;
419 #if defined(ENABLE_TRACE)
420 dump_itm_header(itm_header
, info_header
);
426 * Fix referencer of itmc_ref_t
430 relocation_II(itm_hdr_t
*itm_header
, itm_info_hdr_t
*info_header
)
443 TRACE_MESSAGE('3', ("string section\n"));
444 place
= info_header
->str_sec
.place
.itm_ptr
;
445 for (ref
= ref_first
[ITMC_OBJ_STRING
];
446 ref
; place
+= ref
->size
, ref
= ref
->next
) {
447 fix_itmc_ref_reloc(ref
, place
);
451 TRACE_MESSAGE('3', ("direction\n"));
452 place
= info_header
->direc_tbl_sec
.place
.itm_ptr
;
453 for (ref
= ref_first
[ITMC_OBJ_DIREC
];
454 ref
; place
+= ref
->size
, ref
= ref
->next
) {
455 fix_itmc_ref_reloc(ref
, place
);
459 TRACE_MESSAGE('3', ("condition\n"));
460 place
= info_header
->cond_tbl_sec
.place
.itm_ptr
;
461 for (ref
= ref_first
[ITMC_OBJ_COND
];
462 ref
; place
+= ref
->size
, ref
= ref
->next
) {
463 fix_itmc_ref_reloc(ref
, place
);
467 TRACE_MESSAGE('3', ("map\n"));
468 place
= info_header
->map_tbl_sec
.place
.itm_ptr
;
469 for (ref
= ref_first
[ITMC_OBJ_MAP
];
470 ref
; place
+= ref
->size
, ref
= ref
->next
) {
471 fix_itmc_ref_reloc(ref
, place
);
475 TRACE_MESSAGE('3', ("operation\n"));
476 place
= info_header
->op_tbl_sec
.place
.itm_ptr
;
477 for (ref
= ref_first
[ITMC_OBJ_OP
];
478 ref
; place
+= ref
->size
, ref
= ref
->next
) {
479 fix_itmc_ref_reloc(ref
, place
);
483 place
= info_header
->range_tbl_sec
.place
.itm_ptr
;
484 for (ref
= ref_first
[ITMC_OBJ_RANGE
];
485 ref
; place
+= ref
->size
, ref
= ref
->next
) {
486 fix_itmc_ref_reloc(ref
, place
);
489 /* escape sequence */
490 place
= info_header
->escapeseq_tbl_sec
.place
.itm_ptr
;
491 for (ref
= ref_first
[ITMC_OBJ_ESCAPESEQ
];
492 ref
; place
+= ref
->size
, ref
= ref
->next
) {
493 fix_itmc_ref_reloc(ref
, place
);
496 TRACE_MESSAGE('3', ("data section\n"));
497 place
= info_header
->data_sec
.place
.itm_ptr
;
498 for (ref
= ref_first
[ITMC_OBJ_DATA
];
499 ref
; place
+= ref
->size
, ref
= ref
->next
) {
500 fix_itmc_ref_reloc(ref
, place
);
502 for (ref
= ref_first
[ITMC_OBJ_EXPR
];
503 ref
; place
+= ref
->size
, ref
= ref
->next
) {
504 fix_itmc_ref_reloc(ref
, place
);
508 TRACE_MESSAGE('3', ("name section\n"));
509 place
= info_header
->name_plc_tbl
.place
.itm_ptr
;
510 n_plc
= info_header
->name_sec
.place
.itm_ptr
;
511 for (name
= name_first
; name
; name
= name
->next
) {
512 if ((NULL
== name
->object
) ||
513 (ITMC_OBJ_REGISTER
== name
->type
) ||
514 (0 == name
->name
.size
)) {
517 if ((sizeof (itm_place_t
)) < name
->name
.size
) {
518 name
->reloc
.itm_ptr
= n_plc
;
519 n_plc
+= name
->name
.size
;
521 if (name
->object
->referencee
) {
522 ((itm_tbl_hdr_t
*)(name
->object
->referencee
))->
523 name
.itm_ptr
= place
;
525 place
+= (intptr_t)(sizeof (itm_data_t
));
527 place
= info_header
->reg_plc_tbl
.place
.itm_ptr
;
528 for (name
= name_first
; name
; name
= name
->next
) {
529 if ((ITMC_OBJ_REGISTER
!= name
->type
) ||
530 (0 == name
->name
.size
)) {
533 if ((sizeof (itm_place_t
)) < name
->name
.size
) {
535 name
->reloc
.itm_pad
= 0;
537 name
->reloc
.itm_ptr
= n_plc
;
538 n_plc
+= name
->name
.size
;
540 place
+= (sizeof (itm_data_t
));
542 for (name
= name_first
; name
; name
= name
->next
) {
543 if (ITMC_OBJ_REGISTER
== name
->type
) {
544 assert(NULL
== name
->object
);
547 if (NULL
== name
->object
) {
550 "reference to %1$s \"%2$s\" is not resolved\n"),
551 itm_name_type_name
[name
->type
],
552 name_to_str(&(name
->name
)));
556 assert(0 != name
->name
.size
);
557 for (rl
= name
->ref_first
; rl
; rl
= rl
->next
) {
558 fix_itmc_ref_reloc(rl
->ref
,
559 name
->object
->reloc
.itm_ptr
);
561 if (NULL
== name
->object
->referencee
) {
564 "reference to %1$s \"%2$s\" is not resolved\n"),
565 itm_name_type_name
[name
->type
],
566 name_to_str(&(name
->name
)));
569 if (((ITMC_OBJ_REGISTER
!= name
->type
) &&
570 (ITMC_OBJ_DIREC
!= name
->type
) &&
571 ((ITMC_OBJ_MAP
!= name
->type
) ||
572 (NULL
!= ref_first
[ITMC_OBJ_DIREC
]))) &&
573 (NULL
== name
->ref_first
)) {
576 "%1$s \"%2$s\" is defined, but not referred\n"),
577 itm_name_type_name
[name
->type
],
578 name_to_str(&(name
->name
)));
585 * initial direction table
587 TRACE_MESSAGE('3', ("initial direction table\n"));
588 if (NULL
!= ref_first
[ITMC_OBJ_DIREC
]) {
589 itm_header
->direc_init_tbl
= ref_first
[ITMC_OBJ_DIREC
]->reloc
;
590 } else if (NULL
!= ref_first
[ITMC_OBJ_MAP
]) {
591 itm_header
->direc_init_tbl
= ref_first
[ITMC_OBJ_MAP
]->reloc
;
593 itm_error(gettext("No direction nor map\n"));
594 exit(ITMC_STATUS_BT
);
598 * init operation and reset operation
600 for (ref
= ref_first
[ITMC_OBJ_OP
];
601 ref
; place
+= ref
->size
, ref
= ref
->next
) {
602 switch (((itm_tbl_hdr_t
*)(ref
->referencee
))->type
) {
603 case ITM_TBL_OP_INIT
:
604 itm_header
->op_init_tbl
= ref
->reloc
;
606 case ITM_TBL_OP_RESET
:
607 itm_header
->op_reset_tbl
= ref
->reloc
;
617 * Fix reloc and referencer
620 fix_itmc_ref_reloc(itmc_ref_t
*ref
, itm_place2_t place
)
624 ref
->reloc
.itm_ptr
= place
;
626 ref
->reloc
.itm_pad
= 0;
629 if (NULL
!= ref
->referencer
) {
630 ref
->referencer
->itm_ptr
= place
;
633 TRACE_MESSAGE('f', ("fix_itmc_ref_reloc: 0x%08p 0x%08p %p\n",
634 ref
, ref
->referencer
, place
));
635 TRACE_MESSAGE('F', ("fix_itmc_ref_reloc: \"%s\"\n",
636 name_to_str(ref
->name
? &(ref
->name
->name
) : NULL
)));
638 if (NULL
!= ref
->name
) {
639 for (rl
= ref
->name
->ref_first
; rl
; rl
= rl
->next
) {
640 if ((NULL
!= rl
->ref
) &&
641 (NULL
!= rl
->ref
->referencer
)) {
642 rl
->ref
->referencer
->itm_ptr
= place
;
644 ("fix_itmc_ref_reloc: "
646 rl
->ref
, rl
->ref
->referencer
));
648 ("fix_itmc_ref_reloc: \"%s\"\n",
649 name_to_str(ref
->name
?
661 analysis(itm_info_hdr_t
*info_header
)
666 enum { ONEMAP
, ZEROMAP
} onemap
= ZEROMAP
;
668 TRACE_MESSAGE('4', ("Analysis\n"));
670 place
= info_header
->str_sec
.place
.itm_ptr
;
671 for (obj_type
= ITMC_OBJ_FIRST
; obj_type
<= ITMC_OBJ_LAST
; obj_type
++) {
672 if (ITMC_OBJ_DIREC
== obj_type
) {
676 for (ref
= ref_first
[obj_type
];
677 ref
; place
+= ref
->size
, ref
= ref
->next
) {
678 if ((NULL
== ref
->name
) &&
679 (NULL
== ref
->referencer
)) {
680 itm_tbl_hdr_t
*tbl_hdr
;
682 tbl_hdr
= (itm_tbl_hdr_t
*)(ref
->referencee
);
683 if ((ITM_TBL_OP_RESET
== tbl_hdr
->type
) ||
684 (ITM_TBL_OP_INIT
== tbl_hdr
->type
)) {
686 } else if ((ITM_TBL_MAP
==
687 (ITM_TBL_MASK
& tbl_hdr
->type
)) &&
688 (NULL
== ref_first
[ITMC_OBJ_DIREC
])) {
689 if (ZEROMAP
== onemap
) {
694 gettext("multiple unamed map's "
700 switch (ITM_TBL_MASK
& tbl_hdr
->type
) {
703 itm_name_type_name
[ITMC_OBJ_ITM
];
707 itm_name_type_name
[ITMC_OBJ_DIREC
];
711 itm_name_type_name
[ITMC_OBJ_COND
];
715 itm_name_type_name
[ITMC_OBJ_OP
];
719 itm_name_type_name
[ITMC_OBJ_MAP
];
723 itm_name_type_name
[ITMC_OBJ_RANGE
];
725 case ITM_TBL_ESCAPESEQ
:
727 itm_name_type_name
[ITMC_OBJ_ESCAPESEQ
];
731 itm_name_type_name
[ITMC_OBJ_NONE
];
735 gettext("unnamed %1$s-type object is "
736 "defined, but not referenced\n"),
745 * Analysis2 (check #nest of operation)
753 itm_op_outer_t
*o
, *o_prev
;
754 itm_op_inner_t
*in
, *in_prev
;
756 struct op_nest_vertex
{
757 itmc_ref_t
*ref
; /* corresponding object's ref */
758 int indegree
; /* indegree */
759 struct op_nest_edge
*e
; /* link of edge list */
760 int z_link
; /* index of indegree zero */
763 struct op_nest_edge
{
764 struct op_nest_edge
*e
; /* link of edge list */
765 int index
; /* index of edge */
767 struct op_nest_vertex
*vertexes
;
768 struct op_nest_edge
*e
, *e_prev
;
770 TRACE_MESSAGE('5', ("Analysis2\n"));
773 for (o
= itm_op_outer
; o
!= NULL
; o
= o
->link
) {
774 TRACE_MESSAGE('L', ("op(table)%x\n", o
->optbl
));
778 for (o
= itm_op_outer
; o
!= NULL
; o
= o
->link
) {
779 for (ref
= ref_first
[ITMC_OBJ_OP
]; ref
!= NULL
;
781 if (o
->optbl
== ref
->referencee
) {
782 if (ref
->name
!= NULL
) {
783 o
->ref
= ref
->name
->object
;
787 TRACE_MESSAGE('l', ("op(table)%x<-ref(%x)\n",
789 o
->ref
->vertex_index
= i
;
799 vertexes
= (struct op_nest_vertex
*)(malloc_vital(
800 sizeof (struct op_nest_vertex
) * n_op
));
802 for (o
= itm_op_outer
; o
!= NULL
; o
= o
->link
) {
803 if (o
->ref
== NULL
) {
806 vertexes
[o
->ref
->vertex_index
].ref
= o
->ref
;
807 vertexes
[o
->ref
->vertex_index
].e
= NULL
;
810 for (o
= itm_op_outer
; o
!= NULL
; o_prev
= o
,
811 o
= o
->link
, free(o_prev
)) {
812 if (o
->ref
== NULL
) {
815 TRACE_MESSAGE('l', ("vertexes[%d].ref=%x (optbl=%x(%s))\n",
816 o
->ref
->vertex_index
, o
->ref
, o
->ref
->referencee
,
817 name_to_str(o
->ref
->name
== NULL
? NULL
:
818 &(o
->ref
->name
->name
))));
819 for (in
= o
->in
; in
!= NULL
;
820 in_prev
= in
, in
= in
->in
, free(in_prev
)) {
822 i
= o
->ref
->vertex_index
;
823 j
= in
->ref
->name
->object
->vertex_index
;
824 e
= malloc_vital(sizeof (struct op_nest_edge
));
826 e
->e
= vertexes
[i
].e
;
828 vertexes
[j
].indegree
++;
830 (" edge: vertexes[%d]:(%s) ->vertex[%d]:(%s)\n",
833 (vertexes
[i
].ref
->name
== NULL
) ? NULL
:
834 &(vertexes
[i
].ref
->name
->name
)),
837 (vertexes
[j
].ref
->name
== NULL
) ? NULL
:
838 &(vertexes
[j
].ref
->name
->name
))));
843 for (i
= 0; i
< n_op
; i
++) {
844 if (vertexes
[i
].indegree
== 0) {
845 vertexes
[i
].z_link
= indegree_zero
;
850 for (i
= 0; i
< n_op
; i
++) {
851 if (indegree_zero
== NIL
) {
853 gettext("operation loop detected\n"));
854 exit(ITMC_STATUS_BT2
);
857 indegree_zero
= vertexes
[indegree_zero
].z_link
;
859 if (vertexes
[k
].n_nest
> MAXOPNEST
) {
861 gettext("operation nested more than %d\n"),
863 exit(ITMC_STATUS_BT2
);
866 ("take out first vertex: vertexes[%d] (i.e.%s) "
867 "#depth=%d\n", k
, name_to_str(
868 (vertexes
[k
].ref
->name
== NULL
) ? NULL
:
869 &(vertexes
[k
].ref
->name
->name
)),
870 vertexes
[k
].n_nest
));
872 for (e
= vertexes
[k
].e
; e
!= NULL
;
873 e_prev
= e
, e
= e
->e
, free(e_prev
)) {
875 if (vertexes
[j
].n_nest
< vertexes
[k
].n_nest
+ 1) {
877 vertexes
[k
].n_nest
+ 1;
879 TRACE_MESSAGE('l', (" +->vertexes[%d]:(%s) "
880 "(#indegree=%d,#depth = %d)\n",
881 j
, name_to_str(&(vertexes
[j
].ref
->name
->name
)),
882 vertexes
[j
].indegree
, vertexes
[j
].n_nest
));
883 vertexes
[j
].indegree
--;
884 if (vertexes
[j
].indegree
== 0) {
885 vertexes
[j
].z_link
= indegree_zero
;
895 * Output ITM compiled data
898 output(itm_hdr_t
*itm_header
, itm_info_hdr_t
*info_header
)
907 if (cmd_opt
.no_output
) {
909 } else if (NULL
== itm_output_file
) {
911 TRACE_MESSAGE('o', ("file=(stdout)\n"));
913 TRACE_MESSAGE('o', ("file=%s\n", itm_output_file
));
914 switch (stat(itm_output_file
, &st_buf
)) {
916 if (0 == cmd_opt
.force_overwrite
) {
918 gettext("target file exists\n"));
919 exit(ITMC_STATUS_CMD2
);
923 if (ENOENT
!= errno
) {
924 PERROR(gettext("stat"));
925 exit(ITMC_STATUS_CMD2
);
929 PERROR(gettext("stat"));
930 exit(ITMC_STATUS_SYS
);
934 fd
= open(itm_output_file
, O_CREAT
|O_WRONLY
|O_TRUNC
, 0666);
936 PERROR(gettext("open"));
937 exit(ITMC_STATUS_SYS
);
940 fp
= fdopen(fd
, "w");
942 PERROR(gettext("fdopen"));
943 exit(ITMC_STATUS_SYS
);
946 if (1 == cmd_opt
.strip
) {
947 itm_header
->info_hdr
.itm_ptr
= 0;
951 (void) fseek(fp
, 0, SEEK_SET
);
952 (void) fwrite(itm_header
, sizeof (itm_hdr_t
), 1, fp
);
955 (void) fseek(fp
, info_header
->str_sec
.place
.itm_ptr
, SEEK_SET
);
956 TRACE_MESSAGE('P', ("str_sec.place.place=%p:\n",
957 info_header
->str_sec
.place
.itm_ptr
));
958 for (ref
= ref_first
[ITMC_OBJ_STRING
]; ref
; ref
= ref
->next
) {
959 (void) fwrite((void *)(ref
->referencee
), 1, ref
->size
, fp
);
963 (void) fseek(fp
, info_header
->direc_tbl_sec
.place
.itm_ptr
, SEEK_SET
);
964 TRACE_MESSAGE('P', ("direc_tbl_sec.place=%p:\n",
965 info_header
->direc_tbl_sec
.place
.itm_ptr
));
966 for (ref
= ref_first
[ITMC_OBJ_DIREC
]; ref
; ref
= ref
->next
) {
967 (void) fwrite((void *)(ref
->referencee
), ref
->size
, 1, fp
);
971 (void) fseek(fp
, info_header
->cond_tbl_sec
.place
.itm_ptr
, SEEK_SET
);
972 TRACE_MESSAGE('P', ("cond_tbl_sec.place=%p:\n",
973 info_header
->cond_tbl_sec
.place
.itm_ptr
));
974 for (ref
= ref_first
[ITMC_OBJ_COND
]; ref
; ref
= ref
->next
) {
975 (void) fwrite((void *)(ref
->referencee
), ref
->size
, 1, fp
);
979 (void) fseek(fp
, info_header
->map_tbl_sec
.place
.itm_ptr
, SEEK_SET
);
980 TRACE_MESSAGE('P', ("map_tbl_sec.place=%p:\n",
981 info_header
->map_tbl_sec
.place
.itm_ptr
));
982 for (ref
= ref_first
[ITMC_OBJ_MAP
]; ref
; ref
= ref
->next
) {
983 (void) fwrite((void *)(ref
->referencee
), ref
->size
, 1, fp
);
987 (void) fseek(fp
, info_header
->op_tbl_sec
.place
.itm_ptr
, SEEK_SET
);
988 TRACE_MESSAGE('P', ("op_tbl_sec.place=%p:\n",
989 info_header
->op_tbl_sec
.place
.itm_ptr
));
990 for (ref
= ref_first
[ITMC_OBJ_OP
]; ref
; ref
= ref
->next
) {
991 (void) fwrite((void *)(ref
->referencee
), ref
->size
, 1, fp
);
995 (void) fseek(fp
, info_header
->range_tbl_sec
.place
.itm_ptr
, SEEK_SET
);
996 TRACE_MESSAGE('P', ("range_tbl_sec.place=%p:\n",
997 info_header
->range_tbl_sec
.place
.itm_ptr
));
998 for (ref
= ref_first
[ITMC_OBJ_RANGE
]; ref
; ref
= ref
->next
) {
999 (void) fwrite((void *)(ref
->referencee
), ref
->size
, 1, fp
);
1002 /* escape sequence */
1003 (void) fseek(fp
, info_header
->escapeseq_tbl_sec
.place
.itm_ptr
,
1005 TRACE_MESSAGE('P', ("escapeseq_tbl_sec.place=%p:\n",
1006 info_header
->escapeseq_tbl_sec
.place
.itm_ptr
));
1007 for (ref
= ref_first
[ITMC_OBJ_ESCAPESEQ
]; ref
; ref
= ref
->next
) {
1008 (void) fwrite((void *)(ref
->referencee
), ref
->size
, 1, fp
);
1013 (void) fseek(fp
, info_header
->data_sec
.place
.itm_ptr
, SEEK_SET
);
1014 TRACE_MESSAGE('P', ("data_sec.place=%p:\n",
1015 info_header
->data_sec
.place
.itm_ptr
));
1016 for (ref
= ref_first
[ITMC_OBJ_DATA
]; ref
; ref
= ref
->next
) {
1017 (void) fwrite((void *)(ref
->referencee
), ref
->size
, 1, fp
);
1018 sec_size
+= ref
->size
;
1020 for (ref
= ref_first
[ITMC_OBJ_EXPR
]; ref
; ref
= ref
->next
) {
1021 (void) fwrite((void *)(ref
->referencee
), ref
->size
, 1, fp
);
1022 sec_size
+= ref
->size
;
1024 if (0 != cmd_opt
.strip
) {
1025 if (sec_size
< info_header
->data_sec
.size
) {
1026 (void) fwrite("\0\0\0\0", 1,
1027 info_header
->data_sec
.size
- sec_size
, fp
);
1031 /* ITM Info header */
1032 (void) fseek(fp
, itm_header
->info_hdr
.itm_ptr
, SEEK_SET
);
1033 TRACE_MESSAGE('P', ("info_hdr=%p:\n",
1034 itm_header
->info_hdr
.itm_ptr
));
1035 (void) fwrite(info_header
, sizeof (itm_info_hdr_t
), 1, fp
);
1037 (void) fseek(fp
, info_header
->direc_plc_tbl
.place
.itm_ptr
,
1039 TRACE_MESSAGE('P', ("direc_plc_tbl.place=%p:\n",
1040 info_header
->direc_plc_tbl
.place
.itm_ptr
));
1041 for (ref
= ref_first
[ITMC_OBJ_DIREC
]; ref
; ref
= ref
->next
) {
1042 (void) fwrite(&(ref
->reloc
),
1043 sizeof (itm_place_t
), 1, fp
);
1046 (void) fseek(fp
, info_header
->cond_plc_tbl
.place
.itm_ptr
,
1048 TRACE_MESSAGE('P', ("cond_plc_tbl.place=%p:\n",
1049 info_header
->cond_plc_tbl
.place
.itm_ptr
));
1051 for (ref
= ref_first
[ITMC_OBJ_COND
]; ref
; ref
= ref
->next
) {
1052 (void) fwrite(&(ref
->reloc
),
1053 sizeof (itm_place_t
), 1, fp
);
1056 (void) fseek(fp
, info_header
->map_plc_tbl
.place
.itm_ptr
,
1058 TRACE_MESSAGE('P', ("map_plc_tbl.place=%p:\n",
1059 info_header
->map_plc_tbl
.place
.itm_ptr
));
1061 for (ref
= ref_first
[ITMC_OBJ_MAP
]; ref
; ref
= ref
->next
) {
1062 (void) fwrite(&(ref
->reloc
),
1063 sizeof (itm_place_t
), 1, fp
);
1066 (void) fseek(fp
, info_header
->op_plc_tbl
.place
.itm_ptr
,
1068 TRACE_MESSAGE('P', ("op_plc_tbl.place=%p:\n",
1069 info_header
->op_plc_tbl
.place
.itm_ptr
));
1070 for (ref
= ref_first
[ITMC_OBJ_OP
]; ref
; ref
= ref
->next
) {
1071 (void) fwrite(&(ref
->reloc
),
1072 sizeof (itm_place_t
), 1, fp
);
1075 (void) fseek(fp
, info_header
->str_plc_tbl
.place
.itm_ptr
,
1077 TRACE_MESSAGE('P', ("str_plc_tbl.place=%p:\n",
1078 info_header
->str_plc_tbl
.place
.itm_ptr
));
1080 for (ref
= ref_first
[ITMC_OBJ_STRING
]; ref
; ref
= ref
->next
) {
1083 data
.place
.itm_pad
= 0;
1086 data
.place
= ref
->reloc
;
1087 data
.size
= ref
->size
;
1088 (void) fwrite(&data
, sizeof (itm_data_t
), 1, fp
);
1091 (void) fseek(fp
, info_header
->range_plc_tbl
.place
.itm_ptr
,
1093 TRACE_MESSAGE('P', ("range_plc_tbl.place=%p:\n",
1094 info_header
->range_plc_tbl
.place
.itm_ptr
));
1095 for (ref
= ref_first
[ITMC_OBJ_RANGE
]; ref
; ref
= ref
->next
) {
1096 (void) fwrite(&(ref
->reloc
),
1097 sizeof (itm_place_t
), 1, fp
);
1099 (void) fseek(fp
, info_header
->escapeseq_plc_tbl
.place
.itm_ptr
,
1101 TRACE_MESSAGE('P', ("escapeseq_plc_tbl.place=%p:\n",
1102 info_header
->escapeseq_plc_tbl
.place
.itm_ptr
));
1103 for (ref
= ref_first
[ITMC_OBJ_ESCAPESEQ
];
1104 ref
; ref
= ref
->next
) {
1105 (void) fwrite(&(ref
->reloc
),
1106 sizeof (itm_place_t
), 1, fp
);
1109 (void) fseek(fp
, info_header
->data_plc_tbl
.place
.itm_ptr
,
1111 TRACE_MESSAGE('P', ("data_plc_tbl.place=%p:\n",
1112 info_header
->data_plc_tbl
.place
.itm_ptr
));
1113 for (ref
= ref_first
[ITMC_OBJ_DATA
]; ref
; ref
= ref
->next
) {
1114 (void) fwrite(&(ref
->reloc
),
1115 sizeof (itm_place_t
), 1, fp
);
1117 for (ref
= ref_first
[ITMC_OBJ_EXPR
]; ref
; ref
= ref
->next
) {
1118 (void) fwrite(&(ref
->reloc
),
1119 sizeof (itm_place_t
), 1, fp
);
1122 (void) fseek(fp
, info_header
->name_plc_tbl
.place
.itm_ptr
,
1124 TRACE_MESSAGE('P', ("name_plc_tbl.place=%p:\n",
1125 info_header
->name_plc_tbl
.place
.itm_ptr
));
1126 for (name
= name_first
, sec_size
= 0;
1127 name
; name
= name
->next
) {
1129 if ((ITMC_OBJ_REGISTER
== name
->type
) ||
1130 (0 == name
->name
.size
)) {
1133 data
.size
= name
->name
.size
;
1137 if ((sizeof (itm_place_t
)) < data
.size
) {
1139 data
.place
.itm_pad
= 0;
1141 data
.place
.itm_ptr
= name
->reloc
.itm_ptr
;
1143 data
.place
= name
->name
.place
;
1145 (void) fwrite(&data
, sizeof (itm_data_t
), 1, fp
);
1148 (void) fseek(fp
, info_header
->reg_plc_tbl
.place
.itm_ptr
,
1150 TRACE_MESSAGE('P', ("reg_plc_tbl.place=%p:\n",
1151 info_header
->reg_plc_tbl
.place
.itm_ptr
));
1153 for (name
= name_first
;
1154 name
; name
= name
->next
) {
1156 if ((ITMC_OBJ_REGISTER
!= name
->type
) ||
1157 (0 == name
->name
.size
)) {
1163 data
.size
= name
->name
.size
;
1164 if ((sizeof (itm_place_t
)) < data
.size
) {
1166 data
.place
.itm_pad
= 0;
1168 data
.place
.itm_ptr
= name
->reloc
.itm_ptr
;
1170 data
.place
= name
->name
.place
;
1172 (void) fwrite(&data
, sizeof (itm_data_t
), 1, fp
);
1176 (void) fseek(fp
, info_header
->name_sec
.place
.itm_ptr
, SEEK_SET
);
1177 TRACE_MESSAGE('P', ("name_sec.place=%p:\n",
1178 info_header
->name_sec
.place
.itm_ptr
));
1179 for (name
= name_first
, sec_size
= 0;
1180 name
; name
= name
->next
) {
1181 if ((ITMC_OBJ_REGISTER
== name
->type
) ||
1182 (name
->name
.size
<= (sizeof (itm_place_t
)))) {
1185 (void) fwrite(NSPTR(&(name
->name
)), 1,
1186 name
->name
.size
, fp
);
1187 sec_size
+= name
->name
.size
;
1189 for (name
= name_first
; name
; name
= name
->next
) {
1190 if ((ITMC_OBJ_REGISTER
!= name
->type
) ||
1191 (name
->name
.size
<= (sizeof (itm_place_t
)))) {
1194 (void) fwrite(NSPTR(&(name
->name
)), 1,
1195 name
->name
.size
, fp
);
1196 sec_size
+= name
->name
.size
;
1198 if (sec_size
< info_header
->name_sec
.size
) {
1199 (void) fwrite("\0\0\0\0", 1,
1200 info_header
->name_sec
.size
- sec_size
, fp
);