cb62657e7ca82b365d2639bf0e77146575a04888
[deliverable/binutils-gdb.git] / binutils / srconv.c
1 /* srconv.c -- Sysroff conversion program
2 Copyright (C) 1994 Free Software Foundation, Inc.
3
4 This file is part of GNU Binutils.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20 /* Written by Steve Chamberlain (sac@cygnus.com)
21
22 This program can be used to convert a coff object file
23 into a Hitachi OM/LM (Sysroff) format.
24
25 All debugging information is preserved */
26
27 #include <bfd.h>
28 #include <getopt.h>
29 #include <stdio.h>
30 #include <time.h>
31 #include <libiberty.h>
32 #include "bucomm.h"
33 #include "sysroff.h"
34 #include "coffgrok.h"
35
36 #include "coff/internal.h"
37 #include "../bfd/libcoff.h"
38
39 #define PROGRAM_VERSION "1.5"
40 /*#define FOOP1 1*/
41
42 static int sh;
43 static int h8300;
44 static void wr_cs ();
45 static void walk_tree_scope ();
46 static void wr_globals ();
47 static int find_base ();
48
49 static FILE *file;
50 static bfd *abfd;
51 static int debug = 0;
52 static int quick = 0;
53
54 static struct coff_ofile *tree;
55
56 static int absolute_p;
57 static int segmented_p;
58 static int code;
59
60 static int ids1[20000];
61 static int ids2[20000];
62
63 static int base1 = 0x18;
64 static int base2 = 0x2018;
65
66 char *
67 xcalloc (a, b)
68 int a;
69 int b;
70 {
71 char *r = xmalloc (a * b);
72 memset (r, 0, a * b);
73 return r;
74 }
75
76 static int
77 get_member_id (x)
78 int x;
79 {
80 if (ids2[x])
81 {
82 return ids2[x];
83 }
84 ids2[x] = base2++;
85 return ids2[x];
86 }
87
88 static int
89 get_ordinary_id (x)
90 int x;
91 {
92 if (ids1[x])
93 {
94 return ids1[x];
95 }
96 ids1[x] = base1++;
97 return ids1[x];
98 }
99 static char *
100 section_translate (n)
101 char *n;
102 {
103 if (strcmp (n, ".text") == 0)
104 return "P";
105 if (strcmp (n, ".data") == 0)
106 return "D";
107 if (strcmp (n, ".bss") == 0)
108 return "B";
109 return n;
110 }
111
112
113
114 #define DATE "940201073000"; /* Just a time on my birthday */
115
116
117 static
118 char *
119 strip_suffix (name)
120 char *name;
121 {
122 int i;
123 char *res;
124 for (i = 0; name[i] != 0 && name[i] != '.'; i++)
125 ;
126 res = (char *) xmalloc (i + 1);
127 memcpy (res, name, i);
128 res[i] = 0;
129 return res;
130 }
131
132
133 /* IT LEN stuff CS */
134 static void
135 checksum (file, ptr, size, code)
136 FILE *file;
137 char *ptr;
138 int size;
139 int code;
140 {
141 int j;
142 int last;
143 int sum = 0;
144 int bytes = size / 8;
145 last = !(code & 0xff00);
146 if (size & 0x7)
147 abort ();
148 ptr[0] = code | (last ? 0x80 : 0);
149 ptr[1] = bytes + 1;
150
151 for (j = 0; j < bytes; j++)
152 {
153 sum += ptr[j];
154 }
155 /* Glue on a checksum too */
156 ptr[bytes] = ~sum;
157 fwrite (ptr, bytes + 1, 1, file);
158 }
159
160
161
162
163 static void
164 writeINT (n, ptr, idx, size, file)
165 int n;
166 char *ptr;
167 int *idx;
168 int size;
169 FILE *file;
170 {
171 int byte = *idx / 8;
172
173 if (size == -2)
174 size = 4;
175 if (size == -1)
176 size = 0;
177
178 if (byte > 240)
179 {
180 /* Lets write out that record and do another one */
181 checksum (file, ptr, *idx, code | 0x1000);
182 *idx = 16;
183 byte = *idx / 8;
184 }
185 switch (size)
186 {
187 case 0:
188 break;
189 case 1:
190 ptr[byte] = n;
191 break;
192 case 2:
193 ptr[byte + 0] = n >> 8;
194 ptr[byte + 1] = n;
195 break;
196 case 4:
197 ptr[byte + 0] = n >> 24;
198 ptr[byte + 1] = n >> 16;
199 ptr[byte + 2] = n >> 8;
200 ptr[byte + 3] = n >> 0;
201 break;
202 default:
203 abort ();
204 }
205 *idx += size * 8;
206 }
207
208
209 static void
210 writeBITS (val, ptr, idx, size)
211 int val;
212 char *ptr;
213 int *idx;
214 int size;
215 {
216 int byte = *idx / 8;
217 int bit = *idx % 8;
218 int old;
219 *idx += size;
220
221 old = ptr[byte];
222 /* Turn off all about to change bits */
223 old &= ~((~0 >> (8 - bit - size)) & ((1 << size) - 1));
224 /* Turn on the bits we want */
225 old |= (val & ((1 << size) - 1)) << (8 - bit - size);
226 ptr[byte] = old;
227 }
228
229 static void
230 writeBARRAY (data, ptr, idx, size, file)
231 barray data;
232 char *ptr;
233 int *idx;
234 int size;
235 FILE *file;
236 {
237 int i;
238 writeINT (data.len, ptr, idx, 1, file);
239 for (i = 0; i < data.len; i++)
240 {
241 writeINT (data.data[i], ptr, idx, 1, file);
242 }
243
244
245
246
247 }
248 static void
249 writeCHARS (string, ptr, idx, size, file)
250 char *string;
251 char *ptr;
252 int *idx;
253 int size;
254 FILE *file;
255 {
256 int i = *idx / 8;
257
258 if (i > 240)
259 {
260 /* Lets write out that record and do another one */
261 checksum (file, ptr, *idx, code | 0x1000);
262 *idx = 16;
263 i = *idx / 8;
264 }
265
266 if (size == 0)
267 {
268 /* Variable length string */
269 size = strlen (string);
270 ptr[i++] = size;
271 }
272
273
274 memcpy (ptr + i, string, size);
275 i += size;
276 *idx = i * 8;
277 }
278
279 #define SYSROFF_SWAP_OUT
280 #include "sysroff.c"
281
282
283 static char *rname_sh[] =
284 {
285 "R0", "R1", "R2", "R3", "R4", "R5", "R6", "R7", "R8", "R9", "R10", "R11", "R12", "R13", "R14", "R15"
286 };
287
288 static char *rname_h8300[] =
289 {
290 "ER0", "ER1", "ER2", "ER3", "ER4", "ER5", "ER6", "ER7", "PC", "CCR"
291 };
292
293 static void
294 wr_tr ()
295 {
296 struct IT_tr t;
297 sysroff_swap_tr_out (file, &t);
298 }
299
300 static void
301 wr_un (ptr, sfile, first)
302 struct coff_ofile *ptr;
303 struct coff_sfile *sfile;
304 int first;
305 {
306 struct IT_un un;
307
308 struct coff_symbol *s;
309
310 un.spare1 = 0;
311
312 if (abfd->flags & EXEC_P)
313 un.format = FORMAT_LM;
314 else
315 un.format = FORMAT_OM;
316 un.spare1 = 0;
317 un.nsections = ptr->nsections - 1; /* Don't count the abs section */
318 un.nextdefs = 0;
319 un.nextrefs = 0;
320 /* Count all the undefined and defined variables with global scope */
321
322 if (first)
323 {
324 for (s = ptr->symbol_list_head; s; s = s->next_in_ofile_list)
325 {
326 if (s->visible->type == coff_vis_ext_def
327 || s->visible->type == coff_vis_common)
328 un.nextdefs++;
329
330 if (s->visible->type == coff_vis_ext_ref)
331 un.nextrefs++;
332 }
333 }
334 if (sh)
335 {
336 un.tool = "C_SH";
337 }
338 if (h8300)
339 {
340 un.tool = "C_H8/300H";
341 }
342 un.tcd = DATE;
343 un.linker = "L_GX00";
344 un.lcd = DATE;
345 un.name = sfile->name;
346 sysroff_swap_un_out (file, &un);
347 }
348
349
350 static void
351 wr_hd (p)
352 struct coff_ofile *p;
353 {
354 struct IT_hd hd;
355
356 hd.spare1 = 0;
357 if (abfd->flags & EXEC_P)
358 {
359 hd.mt = MTYPE_ABS_LM;
360 }
361 else
362 {
363 hd.mt = MTYPE_OMS_OR_LMS;
364 }
365 hd.cd = DATE;
366
367 hd.nu = p->nsources; /* Always one unit */
368 hd.code = 0; /* Always ASCII */
369 hd.ver = "0200"; /* Version 2.00 */
370 switch (abfd->arch_info->arch)
371 {
372 case bfd_arch_h8300:
373 hd.au = 8;
374 hd.si = 32;
375 hd.afl = 2;
376 hd.spcsz = 0;
377 hd.segsz = 0;
378 hd.segsh = 0;
379 hd.cpu = "H8300H";
380 h8300 = 1;
381 break;
382 case bfd_arch_sh:
383 hd.au = 8;
384 hd.si = 32;
385 hd.afl = 2;
386 hd.spcsz = 0;
387 hd.segsz = 0;
388 hd.segsh = 0;
389 hd.cpu = "SH";
390 sh = 1;
391 break;
392 default:
393 abort ();
394 }
395
396 if (!abfd->flags & EXEC_P)
397 {
398 hd.ep = 0;
399 }
400 else
401 {
402 hd.ep = 1;
403 hd.uan = 0;
404 hd.sa = 0;
405 hd.sad = 0;
406 hd.address = bfd_get_start_address (abfd);
407 }
408
409 hd.os = "";
410 hd.sys = "";
411 hd.mn = strip_suffix (abfd->filename);
412
413
414 sysroff_swap_hd_out (file, &hd);
415 }
416
417
418 static void
419 wr_sh (p, sec)
420 struct coff_ofile *p;
421 struct coff_section *sec;
422 {
423 struct IT_sh sh;
424 sh.unit = 0;
425 sh.section = sec->number;
426 #ifdef FOOP1
427 sh.section = 0;
428 #endif
429 sysroff_swap_sh_out (file, &sh);
430 }
431
432
433 static void
434 wr_ob (p, section)
435 struct coff_ofile *p;
436 struct coff_section *section;
437 {
438 int i;
439 int first = 1;
440 unsigned char stuff[200];
441
442 i = 0;
443 while (i < section->size)
444 {
445 struct IT_ob ob;
446 int todo = 200; /* Copy in 200 byte lumps */
447 ob.spare = 0;
448 if (i + todo > section->size)
449 todo = section->size - i;
450
451 if (first)
452 {
453 ob.saf = 1;
454 if (abfd->flags & EXEC_P)
455 ob.address = section->address;
456 else
457 ob.address = 0;
458
459 first = 0;
460 }
461 else
462 {
463 ob.saf = 0;
464 }
465
466 ob.cpf = 0; /* Never compress */
467 ob.data.len = todo;
468 bfd_get_section_contents (abfd, section->bfd_section, stuff, i, todo);
469 ob.data.data = stuff;
470 sysroff_swap_ob_out (file, &ob /*, i + todo < section->size*/ );
471 i += todo;
472 }
473 }
474
475 static void
476 wr_rl (ptr, sec)
477 struct coff_ofile *ptr;
478 struct coff_section *sec;
479 {
480 int nr = sec->nrelocs;
481 int i;
482 for (i = 0; i < nr; i++)
483 {
484 struct coff_reloc *r = sec->relocs + i;
485 struct coff_symbol *ref;
486 struct IT_rl rl;
487 rl.apol = 0;
488 rl.boundary = 0;
489 rl.segment = 1;
490 rl.sign = 0;
491 rl.check = 0;
492 rl.addr = r->offset;
493 rl.bitloc = 0;
494 rl.flen = 32; /* SH Specific */
495 /* What sort of reloc ? Look in the section to find out */
496 ref = r->symbol;
497 if (ref->visible->type == coff_vis_ext_ref)
498 {
499 rl.bcount = 4; /* Always 4 for us */
500 rl.op = OP_EXT_REF;
501 rl.symn = ref->er_number;
502 }
503 else if (ref->visible->type == coff_vis_common)
504 {
505 rl.bcount = 11; /* Always 11 for us */
506 rl.op = OP_SEC_REF;
507 rl.secn = ref->where->section->number;
508 rl.copcode_is_3 = 3;
509 rl.alength_is_4 = 4;
510 rl.addend = ref->where->offset - ref->where->section->address;
511 rl.aopcode_is_0x20 = 0x20;
512 }
513
514 else
515 {
516 rl.bcount = 11; /* Always 11 for us */
517 rl.op = OP_SEC_REF;
518 rl.secn = ref->where->section->number;
519 rl.copcode_is_3 = 3;
520 rl.alength_is_4 = 4;
521 rl.addend = -ref->where->section->address;
522 rl.aopcode_is_0x20 = 0x20;
523 }
524 rl.end = 0xff;
525 if (rl.op == OP_SEC_REF
526 || rl.op == OP_EXT_REF)
527 {
528 sysroff_swap_rl_out (file, &rl);
529 }
530 }
531 }
532
533 static void
534 wr_object_body (p)
535 struct coff_ofile *p;
536 {
537 int i;
538 for (i = 1; i < p->nsections; i++)
539 {
540 wr_sh (p, p->sections + i);
541 wr_ob (p, p->sections + i);
542 wr_rl (p, p->sections + i);
543 }
544 }
545
546 static void
547 wr_dps_start (sfile, section, scope, type, nest)
548 struct coff_sfile *sfile;
549 struct coff_section *section;
550 struct coff_scope *scope;
551 int type;
552 int nest;
553 {
554 struct IT_dps dps;
555 dps.end = 0;
556 dps.opt = 0;
557 dps.type = type;
558 if (scope->sec)
559 {
560 dps.san = scope->sec->number;
561 dps.address = scope->offset - find_base (sfile, scope->sec);
562 dps.block_size = scope->size;
563 if (debug)
564 {
565 printf ("DPS %s %d %x\n",
566 sfile->name,
567 nest,
568 dps.address);
569
570 }
571 }
572 else
573 {
574 dps.san = 0;
575 dps.address = 0;
576 dps.block_size = 0;
577 }
578
579 dps.nesting = nest;
580 dps.neg = 0x1001;
581 sysroff_swap_dps_out (file, &dps);
582 }
583
584 static void
585 wr_dps_end (section, scope, type)
586 struct coff_section *section;
587 struct coff_scope *scope;
588 int type;
589 {
590 struct IT_dps dps;
591 dps.end = 1;
592 dps.type = type;
593 sysroff_swap_dps_out (file, &dps);
594 }
595
596 static int *
597 nints (x)
598 int x;
599 {
600 return (int *) (xcalloc (sizeof (int), x));
601 }
602
603 static void walk_tree_symbol ();
604 static void
605 walk_tree_type_1 (sfile, symbol, type, nest)
606 struct coff_sfile *sfile;
607 struct coff_symbol *symbol;
608 struct coff_type *type;
609 int nest;
610 {
611 switch (type->type)
612 {
613 case coff_secdef_type:
614 case coff_basic_type:
615 {
616 struct IT_dbt dbt;
617
618 switch (type->u.basic)
619 {
620 case T_NULL:
621 case T_VOID:
622 dbt.btype = BTYPE_VOID;
623 dbt.sign = BTYPE_UNSPEC;
624 dbt.fptype = FPTYPE_NOTSPEC;
625 break;
626 case T_CHAR:
627 dbt.btype = BTYPE_CHAR;
628 dbt.sign = BTYPE_UNSPEC;
629 dbt.fptype = FPTYPE_NOTSPEC;
630 break;
631 case T_SHORT:
632 case T_INT:
633 case T_LONG:
634 dbt.btype = BTYPE_INT;
635 dbt.sign = SIGN_SIGNED;
636 dbt.fptype = FPTYPE_NOTSPEC;
637 break;
638 case T_FLOAT:
639 dbt.btype = BTYPE_FLOAT;
640 dbt.fptype = FPTYPE_SINGLE;
641 break;
642 case T_DOUBLE:
643 dbt.btype = BTYPE_FLOAT;
644 dbt.fptype = FPTYPE_DOUBLE;
645 break;
646 case T_LNGDBL:
647 dbt.btype = BTYPE_FLOAT;
648 dbt.fptype = FPTYPE_EXTENDED;
649 break;
650 case T_UCHAR:
651 dbt.btype = BTYPE_CHAR;
652 dbt.sign = SIGN_UNSIGNED;
653 dbt.fptype = FPTYPE_NOTSPEC;
654 break;
655 case T_USHORT:
656 case T_UINT:
657 case T_ULONG:
658 dbt.btype = BTYPE_INT;
659 dbt.sign = SIGN_UNSIGNED;
660 dbt.fptype = FPTYPE_NOTSPEC;
661 break;
662 }
663 dbt.bitsize = type->size;
664 dbt.neg = 0x1001;
665 sysroff_swap_dbt_out (file, &dbt);
666 break;
667 }
668 case coff_pointer_type:
669 {
670 struct IT_dpt dpt;
671 walk_tree_type_1 (sfile, symbol, type->u.pointer.points_to, nest + 1);
672 dpt.neg = 0x1001;
673 sysroff_swap_dpt_out (file, &dpt);
674 break;
675 }
676
677 case coff_function_type:
678 {
679 struct IT_dfp dfp;
680 struct coff_symbol *param;
681 dfp.end = 0;
682 dfp.spare = 0;
683 dfp.nparams = type->u.function.parameters->nvars;
684 dfp.neg = 0x1001;
685
686 walk_tree_type_1 (sfile, symbol, type->u.function.function_returns, nest + 1);
687
688 sysroff_swap_dfp_out (file, &dfp);
689
690 for (param = type->u.function.parameters->vars_head;
691 param;
692 param = param->next)
693 {
694 walk_tree_symbol (sfile, 0, param, nest);
695 }
696 dfp.end = 1;
697 sysroff_swap_dfp_out (file, &dfp);
698 break;
699 }
700
701 case coff_structdef_type:
702 {
703 struct IT_dbt dbt;
704 struct IT_dds dds;
705 struct coff_symbol *member;
706 dds.spare = 0;
707 dbt.btype = BTYPE_STRUCT;
708 dbt.bitsize = type->size;
709 dbt.sign = SIGN_UNSPEC;
710 dbt.fptype = FPTYPE_NOTSPEC;
711 dbt.sid = get_member_id (type->u.astructdef.idx);
712 dbt.neg = 0x1001;
713 sysroff_swap_dbt_out (file, &dbt);
714 dds.end = 0;
715 dds.neg = 0x1001;
716 sysroff_swap_dds_out (file, &dds);
717 for (member = type->u.astructdef.elements->vars_head;
718 member;
719 member = member->next)
720 {
721 walk_tree_symbol (sfile, 0, member, nest + 1);
722 }
723
724 dds.end = 1;
725 sysroff_swap_dds_out (file, &dds);
726
727 }
728 break;
729 case coff_structref_type:
730 {
731 struct IT_dbt dbt;
732 dbt.btype = BTYPE_TAG;
733 dbt.bitsize = type->size;
734 dbt.sign = SIGN_UNSPEC;
735 dbt.fptype = FPTYPE_NOTSPEC;
736 if (type->u.astructref.ref)
737 {
738 dbt.sid = get_member_id (type->u.astructref.ref->number);
739 }
740 else
741 {
742 dbt.sid = 0;
743 }
744
745 dbt.neg = 0x1001;
746 sysroff_swap_dbt_out (file, &dbt);
747 }
748 break;
749 case coff_array_type:
750 {
751 struct IT_dar dar;
752 int j;
753 int dims = 1; /* Only output one dimension at a time */
754 dar.dims = dims;
755 dar.variable = nints (dims);
756 dar.subtype = nints (dims);
757 dar.spare = nints (dims);
758 dar.max_variable = nints (dims);
759 dar.maxspare = nints (dims);
760 dar.max = nints (dims);
761 dar.min_variable = nints (dims);
762 dar.min = nints (dims);
763 dar.minspare = nints (dims);
764 dar.neg = 0x1001;
765 dar.length = type->size / type->u.array.dim;
766 for (j = 0; j < dims; j++)
767 {
768 dar.variable[j] = VARIABLE_FIXED;
769 dar.subtype[j] = SUB_INTEGER;
770 dar.spare[j] = 0;
771 dar.max_variable[j] = 0;
772 dar.max[j] = type->u.array.dim;
773 dar.min_variable[j] = 0;
774 dar.min[j] = 1; /* Why isn't this 0 ? */
775 }
776 walk_tree_type_1 (sfile, symbol, type->u.array.array_of, nest + 1);
777 sysroff_swap_dar_out (file, &dar);
778 }
779 break;
780 case coff_enumdef_type:
781 {
782 struct IT_dbt dbt;
783 struct IT_den den;
784 struct coff_symbol *member;
785 dbt.btype = BTYPE_ENUM;
786 dbt.bitsize = type->size;
787 dbt.sign = SIGN_UNSPEC;
788 dbt.fptype = FPTYPE_NOTSPEC;
789 dbt.sid = get_member_id (type->u.aenumdef.idx);
790 dbt.neg = 0x1001;
791 sysroff_swap_dbt_out (file, &dbt);
792
793 den.end = 0;
794 den.neg = 0x1001;
795 den.spare = 0;
796 sysroff_swap_den_out (file, &den);
797 for (member = type->u.aenumdef.elements->vars_head;
798 member;
799 member = member->next)
800 {
801 walk_tree_symbol (sfile, 0, member, nest + 1);
802 }
803
804 den.end = 1;
805 sysroff_swap_den_out (file, &den);
806 }
807 break;
808
809 break;
810 case coff_enumref_type:
811 {
812 struct IT_dbt dbt;
813 dbt.btype = BTYPE_TAG;
814 dbt.bitsize = type->size;
815 dbt.sign = SIGN_UNSPEC;
816 dbt.fptype = FPTYPE_NOTSPEC;
817 dbt.sid = get_member_id (type->u.aenumref.ref->number);
818 dbt.neg = 0x1001;
819 sysroff_swap_dbt_out (file, &dbt);
820 }
821 break;
822 default:
823 abort ();
824 }
825 }
826
827 static void
828 dty_start ()
829 {
830 struct IT_dty dty;
831 dty.end = 0;
832 dty.neg = 0x1001;
833 dty.spare = 0;
834 sysroff_swap_dty_out (file, &dty);
835 }
836
837 static void
838 dty_stop ()
839 {
840 struct IT_dty dty;
841 dty.end = 0;
842 dty.neg = 0x1001;
843 dty.end = 1;
844 sysroff_swap_dty_out (file, &dty);
845 }
846
847
848 static void
849 dump_tree_structure (sfile, symbol, type, nest)
850 struct coff_sfile *sfile;
851 struct coff_symbol *symbol;
852 struct coff_type *type;
853 int nest;
854 {
855 if (symbol->type->type == coff_function_type)
856 {
857
858
859 }
860
861 }
862
863
864 static void
865 walk_tree_type (sfile, symbol, type, nest)
866
867 struct
868 coff_sfile *sfile;
869 struct coff_symbol *symbol;
870 struct coff_type *type;
871 int nest;
872 {
873 if (symbol->type->type == coff_function_type)
874 {
875
876 struct IT_dty dty;
877 dty.end = 0;
878 dty.neg = 0x1001;
879
880 sysroff_swap_dty_out (file, &dty);
881 walk_tree_type_1 (sfile, symbol, type, nest);
882 dty.end = 1;
883 sysroff_swap_dty_out (file, &dty);
884
885 wr_dps_start (sfile,
886 symbol->where->section,
887 symbol->type->u.function.code,
888 BLOCK_TYPE_FUNCTION, nest);
889 wr_dps_start (sfile, symbol->where->section,
890 symbol->type->u.function.code,
891 BLOCK_TYPE_BLOCK, nest);
892 walk_tree_scope (symbol->where->section,
893 sfile,
894 symbol->type->u.function.code,
895 nest + 1, BLOCK_TYPE_BLOCK);
896
897 wr_dps_end (symbol->where->section,
898 symbol->type->u.function.code,
899 BLOCK_TYPE_BLOCK);
900 wr_dps_end (symbol->where->section,
901 symbol->type->u.function.code, BLOCK_TYPE_FUNCTION);
902
903 }
904 else
905 {
906 struct IT_dty dty;
907 dty.end = 0;
908 dty.neg = 0x1001;
909 sysroff_swap_dty_out (file, &dty);
910 walk_tree_type_1 (sfile, symbol, type, nest);
911 dty.end = 1;
912 sysroff_swap_dty_out (file, &dty);
913 }
914
915 }
916
917
918
919 static void
920 walk_tree_symbol (sfile, section, symbol, nest)
921 struct coff_sfile *sfile;
922 struct coff_section *section;
923 struct coff_symbol *symbol;
924 int nest;
925 {
926 struct IT_dsy dsy;
927
928 dsy.spare2 = 0;
929 dsy.nesting = nest;
930
931 switch (symbol->type->type)
932 {
933 case coff_function_type:
934 dsy.type = STYPE_FUNC;
935 dsy.assign = 1;
936 break;
937 case coff_structref_type:
938 case coff_pointer_type:
939 case coff_array_type:
940 case coff_basic_type:
941 case coff_enumref_type:
942 dsy.type = STYPE_VAR;
943 dsy.assign = 1;
944 break;
945 case coff_enumdef_type:
946 dsy.type = STYPE_TAG;
947 dsy.assign = 0;
948 dsy.magic = 2;
949 break;
950 case coff_structdef_type:
951 dsy.type = STYPE_TAG;
952 dsy.assign = 0;
953 dsy.magic = symbol->type->u.astructdef.isstruct ? 0 : 1;
954 break;
955 case coff_secdef_type:
956 return;
957 default:
958 abort ();
959 }
960
961 if (symbol->where->where == coff_where_member_of_struct)
962 {
963 dsy.assign = 0;
964 dsy.type = STYPE_MEMBER;
965 }
966 if (symbol->where->where == coff_where_member_of_enum)
967 {
968 dsy.type = STYPE_ENUM;
969 dsy.assign = 0;
970 dsy.vallen = 4;
971 dsy.value = symbol->where->offset;
972 }
973
974 if (symbol->type->type == coff_structdef_type
975 || symbol->where->where == coff_where_entag
976 || symbol->where->where == coff_where_strtag)
977 {
978 dsy.snumber = get_member_id (symbol->number);
979 }
980 else
981 {
982 dsy.snumber = get_ordinary_id (symbol->number);
983 }
984
985
986 dsy.sname = symbol->name[0] == '_' ? symbol->name + 1 : symbol->name;
987
988 switch (symbol->visible->type)
989 {
990 case coff_vis_common:
991 case coff_vis_ext_def:
992 dsy.ainfo = AINFO_STATIC_EXT_DEF;
993 break;
994 case coff_vis_ext_ref:
995 dsy.ainfo = AINFO_STATIC_EXT_REF;
996 break;
997 case coff_vis_int_def:
998 dsy.ainfo = AINFO_STATIC_INT;
999 break;
1000 case coff_vis_auto:
1001 case coff_vis_autoparam:
1002 dsy.ainfo = AINFO_AUTO;
1003 break;
1004 case coff_vis_register:
1005 case coff_vis_regparam:
1006 dsy.ainfo = AINFO_REG;
1007 break;
1008 break;
1009 case coff_vis_tag:
1010 case coff_vis_member_of_struct:
1011 case coff_vis_member_of_enum:
1012 break;
1013 default:
1014 abort ();
1015 }
1016
1017 dsy.dlength = symbol->type->size;
1018 switch (symbol->where->where)
1019 {
1020 case coff_where_memory:
1021
1022 dsy.section = symbol->where->section->number;
1023 #ifdef FOOP
1024 dsy.section = 0;
1025 #endif
1026 break;
1027 case coff_where_member_of_struct:
1028 case coff_where_member_of_enum:
1029 case coff_where_stack:
1030 case coff_where_register:
1031 case coff_where_unknown:
1032 case coff_where_strtag:
1033
1034 case coff_where_entag:
1035 case coff_where_typedef:
1036 break;
1037 default:
1038 abort ();
1039 }
1040
1041 switch (symbol->where->where)
1042 {
1043 case coff_where_memory:
1044 dsy.address = symbol->where->offset - find_base (sfile, symbol->where->section);
1045 break;
1046 case coff_where_stack:
1047 dsy.address = symbol->where->offset;
1048 break;
1049 case coff_where_member_of_struct:
1050
1051
1052 if (symbol->where->bitsize)
1053 {
1054 int bits = (symbol->where->offset * 8 + symbol->where->bitoffset);
1055 dsy.bitunit = 1;
1056 dsy.field_len = symbol->where->bitsize;
1057 dsy.field_off = (bits / 32) * 4;
1058 dsy.field_bitoff = bits % 32;
1059 }
1060 else
1061 {
1062 dsy.bitunit = 0;
1063
1064 dsy.field_len = symbol->type->size;
1065 dsy.field_off = symbol->where->offset;
1066 }
1067 break;
1068 case coff_where_member_of_enum:
1069 /* dsy.bitunit = 0;
1070 dsy.field_len = symbol->type->size;
1071 dsy.field_off = symbol->where->offset;*/
1072 break;
1073 case coff_where_register:
1074 case coff_where_unknown:
1075 case coff_where_strtag:
1076
1077 case coff_where_entag:
1078 case coff_where_typedef:
1079 break;
1080 default:
1081 abort ();
1082 }
1083
1084 if (symbol->where->where == coff_where_register)
1085 {
1086 if (sh)
1087 dsy.reg = rname_sh[symbol->where->offset];
1088 if (h8300)
1089 dsy.reg = rname_h8300[symbol->where->offset];
1090 }
1091
1092 switch (symbol->visible->type)
1093 {
1094 case coff_vis_common:
1095 /* We do this 'cause common C symbols are treated as extdefs */
1096 case coff_vis_ext_def:
1097 case coff_vis_ext_ref:
1098
1099 dsy.ename = symbol->name;
1100 break;
1101
1102 case coff_vis_regparam:
1103 case coff_vis_autoparam:
1104 dsy.type = STYPE_PARAMETER;
1105 break;
1106
1107 case coff_vis_int_def:
1108
1109 case coff_vis_auto:
1110 case coff_vis_register:
1111 case coff_vis_tag:
1112 case coff_vis_member_of_struct:
1113 case coff_vis_member_of_enum:
1114 break;
1115 default:
1116 abort ();
1117 }
1118
1119 dsy.sfn = 0;
1120 dsy.sln = 2;
1121
1122 dsy.neg = 0x1001;
1123
1124
1125 sysroff_swap_dsy_out (file, &dsy);
1126
1127 walk_tree_type (sfile, symbol, symbol->type, nest);
1128 }
1129
1130
1131 static void
1132 walk_tree_scope (section, sfile, scope, nest, type)
1133 struct coff_section *section;
1134 struct coff_sfile *sfile;
1135 struct coff_scope *scope;
1136 int nest;
1137 int type;
1138 {
1139 struct coff_symbol *vars;
1140 struct coff_scope *child;
1141
1142 if (scope->vars_head
1143 || (scope->list_head && scope->list_head->vars_head))
1144 {
1145 wr_dps_start (sfile, section, scope, type, nest);
1146
1147 if (nest == 0)
1148 wr_globals (tree, sfile, nest + 1);
1149
1150 for (vars = scope->vars_head; vars; vars = vars->next)
1151 {
1152 walk_tree_symbol (sfile, section, vars, nest);
1153 }
1154
1155 for (child = scope->list_head; child; child = child->next)
1156 {
1157 walk_tree_scope (section, sfile, child, nest + 1, BLOCK_TYPE_BLOCK);
1158 }
1159
1160 wr_dps_end (section, scope, type);
1161 }
1162 }
1163 static void
1164 walk_tree_sfile (section, sfile)
1165 struct coff_section *section;
1166 struct coff_sfile *sfile;
1167 {
1168 walk_tree_scope (section, sfile, sfile->scope, 0, BLOCK_TYPE_COMPUNIT);
1169
1170 }
1171
1172 static void
1173 wr_program_structure (p, sfile)
1174 struct coff_ofile *p;
1175 struct coff_sfile *sfile;
1176 {
1177
1178 walk_tree_sfile (p->sections + 4, sfile);
1179
1180 }
1181
1182 static void
1183 wr_du (p, sfile, n)
1184 struct coff_ofile *p;
1185 struct coff_sfile *sfile;
1186 int n;
1187 {
1188 struct IT_du du;
1189 int lim;
1190 #if 0
1191 struct coff_symbol *symbol;
1192 static int incit = 0x500000;
1193 int used = 0;
1194 #endif
1195 int i;
1196 int j;
1197 unsigned int *lowest = (unsigned *) nints (p->nsections);
1198 unsigned int *highest = (unsigned *) nints (p->nsections);
1199 du.spare = 0;
1200 du.format = abfd->flags & EXEC_P ? 0 : 1;
1201 du.optimized = 0;
1202 du.unit = n;
1203 du.sections = p->nsections - 1;
1204 du.san = (int *) xcalloc (sizeof (int), du.sections);
1205 du.address = nints (du.sections);
1206 du.length = nints (du.sections);
1207
1208 for (i = 0; i < du.sections; i++)
1209 {
1210 lowest[i] = ~0;
1211 highest[i] = 0;
1212 }
1213
1214 /* Look through all the symbols and try and work out the extents in this
1215 source file */
1216 #if 0
1217 for (symbol = sfile->scope->vars_head;
1218 symbol;
1219 symbol = symbol->next)
1220 {
1221 if (symbol->type->type == coff_secdef_type)
1222 {
1223 unsigned int low = symbol->where->offset;
1224 unsigned int high = symbol->where->offset + symbol->type->size - 1;
1225 struct coff_section *section = symbol->where->section;
1226
1227 int sn = section->number;
1228 if (low < lowest[sn])
1229 lowest[sn] = low;
1230 if (high > highest[sn])
1231 highest[sn] = high;
1232 }
1233 }
1234
1235
1236 for (i = 0; i < du.sections; i++)
1237 {
1238 if (highest[i] == 0)
1239 {
1240 lowest[i] = highest[i] = incit;
1241 }
1242 du.san[used] = i;
1243 du.length[used] = highest[i] - lowest[i];
1244 du.address[used] = abfd->flags & EXEC_P ? lowest[i] : 0;
1245 if (debug)
1246 {
1247 printf (" section %6s 0x%08x..0x%08x\n",
1248 p->sections[i + 1].name,
1249 lowest[i],
1250 highest[i]);
1251 }
1252 used++;
1253 }
1254
1255 #endif
1256 lim = du.sections;
1257 for (j = 0; j < lim; j++)
1258 {
1259 int src = j;
1260 int dst = j;
1261 du.san[dst] = dst;
1262 if (sfile->section[src].init)
1263 {
1264 du.length[dst]
1265 = sfile->section[src].high - sfile->section[src].low + 1;
1266 du.address[dst]
1267 = sfile->section[src].low;
1268 }
1269 else
1270 {
1271 du.length[dst] = 0;
1272 du.address[dst] = 0;
1273 }
1274 if (debug)
1275 {
1276 if (sfile->section[src].parent)
1277 {
1278 printf (" section %6s 0x%08x..0x%08x\n",
1279 sfile->section[src].parent->name,
1280 du.address[dst],
1281 du.address[dst] + du.length[dst] - 1);
1282 }
1283 }
1284 du.sections = dst + 1;
1285 }
1286
1287 du.tool = "c_gcc";
1288 du.date = DATE;
1289
1290 sysroff_swap_du_out (file, &du);
1291 }
1292
1293 static void
1294 wr_dus (p, sfile)
1295 struct coff_ofile *p;
1296 struct coff_sfile *sfile;
1297 {
1298
1299 struct IT_dus dus;
1300
1301 dus.efn = 0x1001;
1302 dus.ns = 1; /* p->nsources; sac 14 jul 94 */
1303 dus.drb = nints (dus.ns);
1304 dus.fname = (char **) xcalloc (sizeof (char *), dus.ns);
1305 dus.spare = nints (dus.ns);
1306 dus.ndir = 0;
1307 /* Find the filenames */
1308 #if 0
1309 i = 0;
1310
1311 for (sfile = p->source_head;
1312 sfile;
1313 sfile = sfile->next)
1314 {
1315 dus.drb[i] = 0;
1316 dus.spare[i] = 0;
1317 dus.fname[i] = sfile->name;
1318 i++;
1319 }
1320 #else
1321 dus.drb[0] = 0;
1322 dus.fname[0] = sfile->name;
1323 #endif
1324
1325 sysroff_swap_dus_out (file, &dus);
1326
1327 }
1328
1329 /* Find the offset of the .text section for this sfile in the
1330 .text section for the output file */
1331
1332 static int
1333 find_base (sfile, section)
1334 struct coff_sfile *sfile;
1335 struct coff_section *section;
1336 {
1337 return sfile->section[section->number].low;
1338 }
1339 static void
1340 wr_dln (p, sfile, n)
1341 struct coff_ofile *p;
1342 struct coff_sfile *sfile;
1343 int n;
1344
1345 {
1346 #if 0
1347 if (n == 0)
1348 {
1349 /* Count up all the linenumbers */
1350 struct coff_symbol *sy;
1351 int lc = 0;
1352 struct IT_dln dln;
1353
1354 int idx;
1355
1356 for (sy = p->symbol_list_head;
1357 sy;
1358 sy = sy->next_in_ofile_list)
1359 {
1360 struct coff_type *t = sy->type;
1361 if (t->type == coff_function_type)
1362 {
1363 struct coff_line *l = t->u.function.lines;
1364 lc += l->nlines;
1365 }
1366 }
1367
1368 dln.sfn = nints (lc);
1369 dln.sln = nints (lc);
1370 dln.lln = nints (lc);
1371 dln.section = nints (lc);
1372
1373 dln.from_address = nints (lc);
1374 dln.to_address = nints (lc);
1375
1376
1377 dln.neg = 0x1001;
1378
1379 dln.nln = lc;
1380
1381 /* Run through once more and fill up the structure */
1382 idx = 0;
1383 for (sy = p->symbol_list_head;
1384 sy;
1385 sy = sy->next_in_ofile_list)
1386 {
1387 if (sy->type->type == coff_function_type)
1388 {
1389 int i;
1390 struct coff_line *l = sy->type->u.function.lines;
1391 for (i = 0; i < l->nlines; i++)
1392 {
1393 dln.section[idx] = sy->where->section->number;
1394 dln.sfn[idx] = n;
1395 dln.sln[idx] = l->lines[i];
1396 dln.from_address[idx] = l->addresses[i];
1397 if (idx)
1398 dln.to_address[idx - 1] = dln.from_address[idx];
1399 idx++;
1400 }
1401 }
1402 n++;
1403 }
1404 sysroff_swap_dln_out (file, &dln);
1405 }
1406
1407 #endif
1408 #if 1
1409 /* Count up all the linenumbers */
1410
1411 struct coff_symbol *sy;
1412 int lc = 0;
1413 struct IT_dln dln;
1414
1415 int idx;
1416
1417 for (sy = sfile->scope->vars_head;
1418 sy;
1419 sy = sy->next)
1420 {
1421 struct coff_type *t = sy->type;
1422 if (t->type == coff_function_type)
1423 {
1424 struct coff_line *l = t->u.function.lines;
1425 if (l)
1426 lc += l->nlines;
1427 }
1428 }
1429
1430 dln.sfn = nints (lc);
1431 dln.sln = nints (lc);
1432 dln.cc = nints (lc);
1433 dln.section = nints (lc);
1434
1435 dln.from_address = nints (lc);
1436 dln.to_address = nints (lc);
1437
1438
1439 dln.neg = 0x1001;
1440
1441 dln.nln = lc;
1442
1443 /* Run through once more and fill up the structure */
1444 idx = 0;
1445 for (sy = sfile->scope->vars_head;
1446 sy;
1447 sy = sy->next)
1448 {
1449 if (sy->type->type == coff_function_type)
1450 {
1451 int i;
1452 struct coff_line *l = sy->type->u.function.lines;
1453 if (l)
1454 {
1455 int base = find_base (sfile, sy->where->section);
1456 for (i = 0; i < l->nlines; i++)
1457 {
1458 dln.section[idx] = sy->where->section->number;
1459 dln.sfn[idx] = 0;
1460 dln.sln[idx] = l->lines[i];
1461 dln.from_address[idx] =
1462 l->addresses[i] + sy->where->section->address - base;
1463 dln.cc[idx] = 0;
1464 if (idx)
1465 dln.to_address[idx - 1] = dln.from_address[idx];
1466 idx++;
1467
1468 }
1469 dln.to_address[idx - 1] = dln.from_address[idx - 1] + 2;
1470 }
1471 }
1472 }
1473 if (lc)
1474 sysroff_swap_dln_out (file, &dln);
1475 #endif
1476 }
1477
1478 /* Write the global symbols out to the debug info */
1479 static void
1480 wr_globals (p, sfile, n)
1481 struct coff_ofile *p;
1482 struct coff_sfile *sfile;
1483 int n;
1484 {
1485 struct coff_symbol *sy;
1486 for (sy = p->symbol_list_head;
1487 sy;
1488 sy = sy->next_in_ofile_list)
1489 {
1490 if (sy->visible->type == coff_vis_ext_def
1491 || sy->visible->type == coff_vis_ext_ref)
1492 {
1493 /* Only write out symbols if they belong to
1494 the current source file */
1495 if (sy->sfile == sfile)
1496 walk_tree_symbol (sfile, 0, sy, 0);
1497
1498 }
1499 }
1500 }
1501
1502 static void
1503 wr_debug (p)
1504 struct coff_ofile *p;
1505 {
1506 struct coff_sfile *sfile;
1507 int n = 0;
1508 for (sfile = p->source_head;
1509 sfile;
1510 sfile = sfile->next)
1511
1512 {
1513 if (debug)
1514 {
1515 printf ("%s\n", sfile->name);
1516 }
1517 wr_du (p, sfile, n);
1518 wr_dus (p, sfile);
1519 wr_program_structure (p, sfile);
1520 wr_dln (p, sfile, n);
1521 n++;
1522 }
1523 }
1524 static void
1525 wr_cs ()
1526 {
1527 /* It seems that the CS struct is not normal - the size is wrong
1528 heres one I prepared earlier.. */
1529 static char b[] =
1530 {0x80, 0x21, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x80, 0x80,
1531 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x80, 0x00,
1532 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0xde};
1533 fwrite (b, 1, sizeof (b), file);
1534 }
1535
1536 /* Write out the SC records for a unit. Create an SC
1537 for all the sections which appear in the output file, even
1538 if there isn't an equivalent one on the input */
1539
1540 static void
1541 wr_sc (ptr, sfile)
1542 struct coff_ofile *ptr;
1543 struct coff_sfile *sfile;
1544 {
1545 int i;
1546 /* First work out the total number of sections */
1547
1548 int total_sec = ptr->nsections;
1549
1550 struct myinfo
1551 {
1552 struct coff_section *sec;
1553 struct coff_symbol *symbol;
1554 };
1555 struct coff_symbol *symbol;
1556
1557 struct myinfo *info
1558 = (struct myinfo *) calloc (total_sec, sizeof (struct myinfo));
1559
1560
1561
1562 for (i = 0; i < total_sec; i++)
1563 {
1564 info[i].sec = ptr->sections + i;
1565 info[i].symbol = 0;
1566 }
1567
1568 for (symbol = sfile->scope->vars_head;
1569 symbol;
1570 symbol = symbol->next)
1571 {
1572
1573 if (symbol->type->type == coff_secdef_type)
1574 {
1575 for (i = 0; i < total_sec; i++)
1576 {
1577 if (symbol->where->section == info[i].sec)
1578 {
1579 info[i].symbol = symbol;
1580 break;
1581 }
1582 }
1583 }
1584 }
1585
1586 /* Now output all the section info, and fake up some stuff for sections
1587 we don't have */
1588
1589 for (i = 1; i < total_sec; i++)
1590 {
1591 struct IT_sc sc;
1592 char *name;
1593 symbol = info[i].symbol;
1594 sc.spare = 0;
1595 sc.spare1 = 0;
1596 if (!symbol)
1597 {
1598 /* Don't have a symbol set aside for this section, which means that nothing
1599 in this file does anything for the section. */
1600 sc.format = !(abfd->flags & EXEC_P);
1601 sc.addr = 0;
1602 sc.length = 0;
1603 name = info[i].sec->name;
1604 }
1605 else
1606 {
1607 if (abfd->flags & EXEC_P)
1608 {
1609 sc.format = 0;
1610 sc.addr = symbol->where->offset;
1611 }
1612 else
1613 {
1614 sc.format = 1;
1615 sc.addr = 0;
1616 }
1617 sc.length = symbol->type->size;
1618 name = symbol->name;
1619 }
1620
1621 sc.align = 4;
1622
1623 sc.concat = CONCAT_SIMPLE;
1624 sc.read = 3;
1625 sc.write = 3;
1626 sc.exec = 3;
1627 sc.init = 3;
1628 sc.mode = 3;
1629 sc.spare = 0;
1630 sc.segadd = 0;
1631 sc.spare1 = 0; /* If not zero, then it doesn't work */
1632 sc.name = section_translate (name);
1633 if (strlen (sc.name) == 1)
1634 {
1635 switch (sc.name[0])
1636 {
1637 case 'D':
1638 case 'B':
1639 sc.contents = CONTENTS_DATA;
1640 break;
1641 default:
1642 sc.contents = CONTENTS_CODE;
1643 }
1644 }
1645 else
1646 {
1647 sc.contents = CONTENTS_CODE;
1648 }
1649
1650
1651 sysroff_swap_sc_out (file, &sc);
1652
1653
1654
1655 }
1656
1657 }
1658
1659 static void
1660 wr_er (ptr, sfile, first)
1661 struct coff_ofile *ptr;
1662 struct coff_sfile *sfile;
1663 int first;
1664 {
1665 int idx = 0;
1666 struct coff_symbol *sym;
1667 if (first)
1668 {
1669 for (sym = ptr->symbol_list_head; sym; sym = sym->next_in_ofile_list)
1670 {
1671 if (sym->visible->type == coff_vis_ext_ref)
1672 {
1673 struct IT_er er;
1674 er.spare = 0;
1675 er.type = ER_NOTSPEC;
1676 er.name = sym->name;
1677 sysroff_swap_er_out (file, &er);
1678 sym->er_number = idx++;
1679
1680 }
1681 }
1682 }
1683 }
1684
1685 static void
1686 wr_ed (ptr, sfile, first)
1687 struct coff_ofile *ptr;
1688 struct coff_sfile *sfile;
1689 int first;
1690 {
1691 struct coff_symbol *s;
1692 if (first)
1693 {
1694 for (s = ptr->symbol_list_head; s; s = s->next_in_ofile_list)
1695 {
1696 if (s->visible->type == coff_vis_ext_def
1697 || s->visible->type == coff_vis_common)
1698 {
1699 struct IT_ed ed;
1700
1701 ed.section = s->where->section->number;
1702 ed.spare = 0;
1703 if (s->where->section->data)
1704 {
1705 ed.type = ED_TYPE_DATA;
1706 }
1707 else if (s->where->section->code & SEC_CODE)
1708 {
1709 ed.type = ED_TYPE_ENTRY;
1710 }
1711 else
1712 {
1713 ed.type = ED_TYPE_NOTSPEC;
1714 ed.type = ED_TYPE_DATA;
1715 }
1716 ed.address = s->where->offset - s->where->section->address;
1717 ed.name = s->name;
1718 sysroff_swap_ed_out (file, &ed);
1719 }
1720 }
1721 }
1722 }
1723
1724 static void
1725 wr_unit_info (ptr)
1726 struct coff_ofile *ptr;
1727 {
1728 struct coff_sfile *sfile;
1729 int first = 1;
1730 for (sfile = ptr->source_head;
1731 sfile;
1732 sfile = sfile->next)
1733 {
1734 wr_un (ptr, sfile, first);
1735 wr_sc (ptr, sfile);
1736 wr_er (ptr, sfile, first);
1737 wr_ed (ptr, sfile, first);
1738 first = 0;
1739 }
1740 }
1741
1742 static void
1743 wr_module (p)
1744 struct coff_ofile *p;
1745 {
1746 wr_cs ();
1747 wr_hd (p);
1748 wr_unit_info (p);
1749 wr_object_body (p);
1750 wr_debug (p);
1751 wr_tr ();
1752 }
1753
1754 static int
1755 align (x)
1756 int x;
1757 {
1758 return (x + 3) & ~3;
1759 }
1760
1761 /* Find all the common variables and turn them into
1762 ordinary defs - dunno why, but thats what hitachi does with 'em */
1763
1764 static void
1765 prescan (tree)
1766 struct coff_ofile *tree;
1767 {
1768 struct coff_symbol *s;
1769 struct coff_section *common_section;
1770 /* Find the common section - always section 3 */
1771 common_section = tree->sections + 3;
1772 for (s = tree->symbol_list_head;
1773 s;
1774 s = s->next_in_ofile_list)
1775 {
1776 if (s->visible->type == coff_vis_common)
1777 {
1778 struct coff_where *w = s->where;
1779 /* s->visible->type = coff_vis_ext_def; leave it as common */
1780 common_section->size = align (common_section->size);
1781 w->offset = common_section->size + common_section->address;
1782 w->section = common_section;
1783 common_section->size += s->type->size;
1784 common_section->size = align (common_section->size);
1785 }
1786 }
1787 }
1788
1789 char *program_name;
1790
1791 static void
1792 show_usage (file, status)
1793 FILE *file;
1794 int status;
1795 {
1796 fprintf (file, "Usage: %s [-dhVq] in-file [out-file]\n", program_name);
1797 exit (status);
1798 }
1799
1800 static void
1801 show_help ()
1802 {
1803 printf ("%s: Convert a COFF object file into a SYSROFF object file\n",
1804 program_name);
1805 show_usage (stdout, 0);
1806 }
1807
1808
1809
1810 int
1811 main (ac, av)
1812 int ac;
1813 char *av[];
1814 {
1815 int opt;
1816 static struct option long_options[] =
1817 {
1818 {"debug", no_argument, 0, 'd'},
1819 {"quick", no_argument, 0, 'q'},
1820 {"help", no_argument, 0, 'h'},
1821 {"version", no_argument, 0, 'V'},
1822 {NULL, no_argument, 0, 0}
1823 };
1824 char **matching;
1825 char *input_file;
1826
1827 char *output_file;
1828 program_name = av[0];
1829 xmalloc_set_program_name (program_name);
1830
1831 while ((opt = getopt_long (ac, av, "dhVq", long_options,
1832 (int *) NULL))
1833 != EOF)
1834 {
1835 switch (opt)
1836 {
1837 case 'q':
1838 quick = 1;
1839 break;
1840 case 'd':
1841 debug = 1;
1842 break;
1843 case 'h':
1844 show_help ();
1845 /*NOTREACHED*/
1846 case 'V':
1847 printf ("GNU %s version %s\n", program_name, PROGRAM_VERSION);
1848 exit (0);
1849 /*NOTREACHED*/
1850 case 0:
1851 break;
1852 default:
1853 show_usage (stderr, 1);
1854 /*NOTREACHED*/
1855 }
1856 }
1857
1858 /* The input and output files may be named on the command line. */
1859 output_file = NULL;
1860 if (optind < ac)
1861 {
1862 input_file = av[optind];
1863 ++optind;
1864 if (optind < ac)
1865 {
1866 output_file = av[optind];
1867 ++optind;
1868 if (optind < ac)
1869 show_usage (stderr, 1);
1870 if (strcmp (input_file, output_file) == 0)
1871 {
1872 fprintf (stderr,
1873 "%s: input and output files must be different\n",
1874 program_name);
1875 exit (1);
1876 }
1877 }
1878 }
1879 else
1880 input_file = 0;
1881
1882 if (!input_file)
1883 {
1884 fprintf (stderr, "%s: no input file specified\n",
1885 program_name);
1886 exit (1);
1887 }
1888
1889 if (!output_file)
1890 {
1891 /* Take a .o off the input file and stick on a .obj. If
1892 it doesn't end in .o, then stick a .obj on anyway */
1893
1894 int len = strlen (input_file);
1895 output_file = xmalloc (len + 5);
1896 strcpy (output_file, input_file);
1897 if (len > 3
1898 && output_file[len - 2] == '.'
1899 && output_file[len - 1] == 'o')
1900 {
1901 output_file[len] = 'b';
1902 output_file[len + 1] = 'j';
1903 output_file[len + 2] = 0;
1904 }
1905 else
1906 {
1907 strcat (output_file, ".obj");
1908 }
1909 }
1910
1911 abfd = bfd_openr (input_file, 0);
1912
1913 if (!abfd)
1914 bfd_fatal (input_file);
1915
1916 if (!bfd_check_format_matches (abfd, bfd_object, &matching))
1917 {
1918 bfd_nonfatal (input_file);
1919 if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
1920 {
1921 list_matching_formats (matching);
1922 free (matching);
1923 }
1924 exit (1);
1925 }
1926
1927 file = fopen (output_file, "wb");
1928
1929 if (!file)
1930 {
1931 fprintf (stderr, "%s: unable to open output file %s\n",
1932 program_name, output_file);
1933 exit (1);
1934 }
1935
1936 if (debug)
1937 printf ("ids %d %d\n", base1, base2);
1938 tree = coff_grok (abfd);
1939 prescan (tree);
1940 wr_module (tree);
1941 return 0;
1942 }
This page took 0.077285 seconds and 4 git commands to generate.