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