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