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