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