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