gcc -Wall lint.
[external/binutils.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 }