srconv.c revision 60484
128019Sjoerg/* srconv.c -- Sysroff conversion program
228019Sjoerg   Copyright (C) 1994, 95, 96, 98, 99, 2000 Free Software Foundation, Inc.
328019Sjoerg
428019Sjoerg   This file is part of GNU Binutils.
528019Sjoerg
628019Sjoerg   This program is free software; you can redistribute it and/or modify
728019Sjoerg   it under the terms of the GNU General Public License as published by
828019Sjoerg   the Free Software Foundation; either version 2 of the License, or
928019Sjoerg   (at your option) any later version.
1028019Sjoerg
1128019Sjoerg   This program is distributed in the hope that it will be useful,
1228019Sjoerg   but WITHOUT ANY WARRANTY; without even the implied warranty of
1328019Sjoerg   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1428019Sjoerg   GNU General Public License for more details.
1528019Sjoerg
1628019Sjoerg   You should have received a copy of the GNU General Public License
1728019Sjoerg   along with this program; if not, write to the Free Software
1828019Sjoerg   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
1928019Sjoerg   02111-1307, USA.  */
2028019Sjoerg
2128019Sjoerg/* Written by Steve Chamberlain (sac@cygnus.com)
2228019Sjoerg
2328019Sjoerg   This program can be used to convert a coff object file
2428019Sjoerg   into a Hitachi OM/LM (Sysroff) format.
2528019Sjoerg
2628019Sjoerg   All debugging information is preserved */
2728019Sjoerg
2828019Sjoerg#include <bfd.h>
2928019Sjoerg#include "bucomm.h"
3028019Sjoerg#include "sysroff.h"
3128019Sjoerg#include "coffgrok.h"
3228019Sjoerg#include <libiberty.h>
3328019Sjoerg#include <getopt.h>
3428019Sjoerg
3528019Sjoerg#include "coff/internal.h"
3628019Sjoerg#include "../bfd/libcoff.h"
3728019Sjoerg
3828019Sjoerg#define PROGRAM_VERSION "1.5"
3928019Sjoerg/*#define FOOP1 1 */
4028019Sjoerg
4128019Sjoergstatic int addrsize;
4228019Sjoergstatic char *toolname;
4328019Sjoergstatic char **rnames;
4428019Sjoerg
4528019Sjoergstatic void wr_cs ();
4628019Sjoergstatic void walk_tree_scope ();
4728019Sjoergstatic void wr_globals ();
4828019Sjoergstatic int find_base ();
4928019Sjoerg
5028019Sjoergstatic FILE *file;
5128019Sjoergstatic bfd *abfd;
5228019Sjoergstatic int debug = 0;
5328019Sjoergstatic int quick = 0;
5428019Sjoergstatic int noprescan = 0;
5528019Sjoergstatic struct coff_ofile *tree;
5628019Sjoerg/* Obsolete ??
5728019Sjoerg   static int absolute_p;
5828019Sjoerg */
5928019Sjoerg
6028019Sjoergstatic int segmented_p;
6128019Sjoergstatic int code;
6228019Sjoerg
6328019Sjoergstatic int ids1[20000];
6428019Sjoergstatic int ids2[20000];
6528019Sjoerg
6628019Sjoergstatic int base1 = 0x18;
6728019Sjoergstatic int base2 = 0x2018;
6828019Sjoerg
6928019Sjoergstatic int
7028019Sjoergget_member_id (x)
7128019Sjoerg     int x;
7228019Sjoerg{
7328019Sjoerg  if (ids2[x])
7428019Sjoerg    {
7528019Sjoerg      return ids2[x];
7628019Sjoerg    }
7728019Sjoerg  ids2[x] = base2++;
7828019Sjoerg  return ids2[x];
7928019Sjoerg}
8028019Sjoerg
8128019Sjoergstatic int
8228019Sjoergget_ordinary_id (x)
8328019Sjoerg     int x;
8428019Sjoerg{
8528019Sjoerg  if (ids1[x])
8628019Sjoerg    {
8728019Sjoerg      return ids1[x];
8828019Sjoerg    }
8928019Sjoerg  ids1[x] = base1++;
9028019Sjoerg  return ids1[x];
9128019Sjoerg}
9228019Sjoergstatic char *
9328019Sjoergsection_translate (n)
9428019Sjoerg     char *n;
9528019Sjoerg{
9628019Sjoerg  if (strcmp (n, ".text") == 0)
9728019Sjoerg    return "P";
9828019Sjoerg  if (strcmp (n, ".data") == 0)
9928019Sjoerg    return "D";
10028019Sjoerg  if (strcmp (n, ".bss") == 0)
10128019Sjoerg    return "B";
10228019Sjoerg  return n;
10328019Sjoerg}
10428019Sjoerg
10528019Sjoerg
10628019Sjoerg
10728019Sjoerg#define DATE "940201073000";	/* Just a time on my birthday */
10828019Sjoerg
10928019Sjoerg
11028019Sjoergstatic
11128019Sjoergchar *
11228019Sjoergstrip_suffix (name)
11328019Sjoerg     char *name;
11428019Sjoerg{
11528019Sjoerg  int i;
11628019Sjoerg  char *res;
11728019Sjoerg  for (i = 0; name[i] != 0 && name[i] != '.'; i++)
11828019Sjoerg    ;
11928019Sjoerg  res = (char *) xmalloc (i + 1);
12028019Sjoerg  memcpy (res, name, i);
12128019Sjoerg  res[i] = 0;
12228019Sjoerg  return res;
12328019Sjoerg}
12428019Sjoerg
12528019Sjoerg
12628019Sjoerg/* IT LEN stuff CS */
12728019Sjoergstatic void
12828019Sjoergchecksum (file, ptr, size, code)
12928019Sjoerg     FILE *file;
13028019Sjoerg     char *ptr;
13128019Sjoerg     int size;
13228019Sjoerg     int code;
13328019Sjoerg{
13428019Sjoerg  int j;
13528019Sjoerg  int last;
13628019Sjoerg  int sum = 0;
13728019Sjoerg  int bytes = size / 8;
13828019Sjoerg  last = !(code & 0xff00);
13928019Sjoerg  if (size & 0x7)
14028019Sjoerg    abort ();
14128019Sjoerg  ptr[0] = code | (last ? 0x80 : 0);
14228019Sjoerg  ptr[1] = bytes + 1;
14328019Sjoerg
14428019Sjoerg  for (j = 0; j < bytes; j++)
14528019Sjoerg    {
14628019Sjoerg      sum += ptr[j];
14728019Sjoerg    }
14828019Sjoerg  /* Glue on a checksum too */
14928019Sjoerg  ptr[bytes] = ~sum;
15028019Sjoerg  fwrite (ptr, bytes + 1, 1, file);
15128019Sjoerg}
15228019Sjoerg
15328019Sjoerg
15428019Sjoerg
15528019Sjoerg
15628019Sjoergstatic void
15728019SjoergwriteINT (n, ptr, idx, size, file)
15828019Sjoerg     int n;
15928019Sjoerg     char *ptr;
16028019Sjoerg     int *idx;
16128019Sjoerg     int size;
16228019Sjoerg     FILE *file;
16328019Sjoerg{
16428019Sjoerg  int byte = *idx / 8;
16528019Sjoerg
16628019Sjoerg  if (size == -2)
16728019Sjoerg    size = addrsize;
16828019Sjoerg  else if (size == -1)
16928019Sjoerg    size = 0;
17028019Sjoerg
17128019Sjoerg  if (byte > 240)
17228019Sjoerg    {
17328019Sjoerg      /* Lets write out that record and do another one */
17428019Sjoerg      checksum (file, ptr, *idx, code | 0x1000);
17528019Sjoerg      *idx = 16;
17628019Sjoerg      byte = *idx / 8;
17728019Sjoerg    }
17828019Sjoerg  switch (size)
17928019Sjoerg    {
18028019Sjoerg    case 0:
18128019Sjoerg      break;
18228019Sjoerg    case 1:
18328019Sjoerg      ptr[byte] = n;
18428019Sjoerg      break;
18528019Sjoerg    case 2:
18628019Sjoerg      ptr[byte + 0] = n >> 8;
18728019Sjoerg      ptr[byte + 1] = n;
18828019Sjoerg      break;
18928019Sjoerg    case 4:
19028019Sjoerg      ptr[byte + 0] = n >> 24;
19128019Sjoerg      ptr[byte + 1] = n >> 16;
19228019Sjoerg      ptr[byte + 2] = n >> 8;
19328019Sjoerg      ptr[byte + 3] = n >> 0;
19428019Sjoerg      break;
19528019Sjoerg    default:
19628019Sjoerg      abort ();
19728019Sjoerg    }
19828019Sjoerg  *idx += size * 8;
19928019Sjoerg}
20028019Sjoerg
20128019Sjoerg
20228019Sjoergstatic void
20328019SjoergwriteBITS (val, ptr, idx, size)
20428019Sjoerg     int val;
20528019Sjoerg     char *ptr;
20628019Sjoerg     int *idx;
20728019Sjoerg     int size;
20828019Sjoerg{
20928019Sjoerg  int byte = *idx / 8;
21028019Sjoerg  int bit = *idx % 8;
21128019Sjoerg  int old;
21228019Sjoerg  *idx += size;
21328019Sjoerg
21428019Sjoerg  old = ptr[byte];
21528019Sjoerg  /* Turn off all about to change bits */
21628019Sjoerg  old &= ~((~0 >> (8 - bit - size)) & ((1 << size) - 1));
21728019Sjoerg  /* Turn on the bits we want */
21828019Sjoerg  old |= (val & ((1 << size) - 1)) << (8 - bit - size);
21928019Sjoerg  ptr[byte] = old;
22028019Sjoerg}
22128019Sjoerg
22228019Sjoergstatic void
22328019SjoergwriteBARRAY (data, ptr, idx, size, file)
22428019Sjoerg     barray data;
22528019Sjoerg     char *ptr;
22628019Sjoerg     int *idx;
22728019Sjoerg     int size;
22828019Sjoerg     FILE *file;
22928019Sjoerg{
23028019Sjoerg  int i;
23128019Sjoerg  writeINT (data.len, ptr, idx, 1, file);
23228019Sjoerg  for (i = 0; i < data.len; i++)
23328019Sjoerg    {
23428019Sjoerg      writeINT (data.data[i], ptr, idx, 1, file);
23528019Sjoerg    }
23628019Sjoerg}
23728019Sjoerg
23828019Sjoerg
23928019Sjoergstatic void
24028019SjoergwriteCHARS (string, ptr, idx, size, file)
24128019Sjoerg     char *string;
24228019Sjoerg     char *ptr;
24328019Sjoerg     int *idx;
24428019Sjoerg     int size;
24528019Sjoerg     FILE *file;
24628019Sjoerg{
24728019Sjoerg  int i = *idx / 8;
24828019Sjoerg
24928019Sjoerg  if (i > 240)
25028019Sjoerg    {
25128019Sjoerg      /* Lets write out that record and do another one */
25228019Sjoerg      checksum (file, ptr, *idx, code | 0x1000);
25328019Sjoerg      *idx = 16;
25428019Sjoerg      i = *idx / 8;
25528019Sjoerg    }
25628019Sjoerg
25728019Sjoerg  if (size == 0)
25828019Sjoerg    {
25928019Sjoerg      /* Variable length string */
26028019Sjoerg      size = strlen (string);
26128019Sjoerg      ptr[i++] = size;
26228019Sjoerg    }
26328019Sjoerg
26428019Sjoerg  /* BUG WAITING TO HAPPEN */
26528019Sjoerg  memcpy (ptr + i, string, size);
26628019Sjoerg  i += size;
26728019Sjoerg  *idx = i * 8;
26828019Sjoerg}
26928019Sjoerg
27028019Sjoerg#define SYSROFF_SWAP_OUT
27128019Sjoerg#include "sysroff.c"
27228019Sjoerg
27328019Sjoerg
27428019Sjoergstatic char *rname_sh[] =
27528019Sjoerg{
27628019Sjoerg  "R0", "R1", "R2", "R3", "R4", "R5", "R6", "R7", "R8", "R9", "R10", "R11", "R12", "R13", "R14", "R15"
27728019Sjoerg};
27828019Sjoerg
27928019Sjoergstatic char *rname_h8300[] =
28028019Sjoerg{
28128019Sjoerg  "ER0", "ER1", "ER2", "ER3", "ER4", "ER5", "ER6", "ER7", "PC", "CCR"
28228019Sjoerg};
28328019Sjoerg
28428019Sjoergstatic void
28528019Sjoergwr_tr ()
28628019Sjoerg{
28728019Sjoerg  /* The TR block is not normal - it doesn't have any contents. */
28828019Sjoerg
28928019Sjoerg  static char b[] = {
29028019Sjoerg    0xff,			/* IT */
29128019Sjoerg    0x03,			/* RL */
29228019Sjoerg    0xfd,			/* CS */
29328019Sjoerg  };
29428019Sjoerg  fwrite (b, 1, sizeof (b), file);
29528019Sjoerg}
29628019Sjoerg
29728019Sjoergstatic void
29828019Sjoergwr_un (ptr, sfile, first, nsecs)
29928019Sjoerg     struct coff_ofile *ptr;
30028019Sjoerg     struct coff_sfile *sfile;
30128019Sjoerg     int first;
30228019Sjoerg     int nsecs;
30328019Sjoerg{
30428019Sjoerg  struct IT_un un;
30528019Sjoerg
30628019Sjoerg  struct coff_symbol *s;
30728019Sjoerg
30828019Sjoerg  un.spare1 = 0;
30928019Sjoerg
31028019Sjoerg  if (bfd_get_file_flags (abfd) & EXEC_P)
31128019Sjoerg    un.format = FORMAT_LM;
31228019Sjoerg  else
31328019Sjoerg    un.format = FORMAT_OM;
31428019Sjoerg  un.spare1 = 0;
31528019Sjoerg
31628019Sjoerg
31728019Sjoerg#if 1
31828019Sjoerg  un.nsections = ptr->nsections - 1;	/*  Don't count the abs section */
31928019Sjoerg#else
32028019Sjoerg  /*NEW - only count sections with size */
32128019Sjoerg  un.nsections = nsecs;
32228019Sjoerg#endif
32328019Sjoerg
32428019Sjoerg  un.nextdefs = 0;
32528019Sjoerg  un.nextrefs = 0;
32628019Sjoerg  /* Count all the undefined and defined variables with global scope */
32728019Sjoerg
32828019Sjoerg  if (first)
32928019Sjoerg    {
33028019Sjoerg      for (s = ptr->symbol_list_head; s; s = s->next_in_ofile_list)
33128019Sjoerg	{
33228019Sjoerg	  if (s->visible->type == coff_vis_ext_def
33328019Sjoerg	      || s->visible->type == coff_vis_common)
33428019Sjoerg	    un.nextdefs++;
33528019Sjoerg
33628019Sjoerg	  if (s->visible->type == coff_vis_ext_ref)
33728019Sjoerg	    un.nextrefs++;
33828019Sjoerg	}
33928019Sjoerg    }
34028019Sjoerg  un.tool = toolname;
34128019Sjoerg  un.tcd = DATE;
34228019Sjoerg  un.linker = "L_GX00";
34328019Sjoerg  un.lcd = DATE;
34428019Sjoerg  un.name = sfile->name;
34528019Sjoerg  sysroff_swap_un_out (file, &un);
34628019Sjoerg}
34728019Sjoerg
34828019Sjoerg
34928019Sjoergstatic void
35028019Sjoergwr_hd (p)
35128019Sjoerg     struct coff_ofile *p;
35228019Sjoerg{
35328019Sjoerg  struct IT_hd hd;
35428019Sjoerg
35528019Sjoerg  hd.spare1 = 0;
35628019Sjoerg  if (bfd_get_file_flags (abfd) & EXEC_P)
35728019Sjoerg    {
35828019Sjoerg      hd.mt = MTYPE_ABS_LM;
359    }
360  else
361    {
362      hd.mt = MTYPE_OMS_OR_LMS;
363    }
364  hd.cd = DATE;
365
366  hd.nu = p->nsources;		/* Always one unit */
367  hd.code = 0;			/* Always ASCII */
368  hd.ver = "0200";		/* Version 2.00 */
369  switch (bfd_get_arch (abfd))
370    {
371    case bfd_arch_h8300:
372      hd.au = 8;
373      hd.si = 0;
374      hd.spcsz = 32;
375      hd.segsz = 0;
376      hd.segsh = 0;
377      switch (bfd_get_mach (abfd))
378	{
379	case bfd_mach_h8300:
380	  hd.cpu = "H8300";
381	  hd.afl = 2;
382	  addrsize = 2;
383	  toolname = "C_H8/300";
384	  break;
385	case bfd_mach_h8300h:
386	  hd.cpu = "H8300H";
387	  hd.afl = 4;
388	  addrsize = 4;
389	  toolname = "C_H8/300H";
390	  break;
391	case bfd_mach_h8300s:
392	  hd.cpu = "H8300S";
393	  hd.afl = 4;
394	  addrsize = 4;
395	  toolname = "C_H8/300S";
396	  break;
397	default:
398	  abort();
399	}
400      rnames = rname_h8300;
401      break;
402    case bfd_arch_sh:
403      hd.au = 8;
404      hd.si = 0;
405      hd.afl = 4;
406      hd.spcsz = 32;
407      hd.segsz = 0;
408      hd.segsh = 0;
409      hd.cpu = "SH";
410      addrsize = 4;
411      toolname = "C_SH";
412      rnames = rname_sh;
413      break;
414    default:
415      abort ();
416    }
417
418  if (! bfd_get_file_flags(abfd) & EXEC_P)
419    {
420      hd.ep = 0;
421    }
422  else
423    {
424      hd.ep = 1;
425      hd.uan = 0;
426      hd.sa = 0;
427      hd.sad = 0;
428      hd.address = bfd_get_start_address (abfd);
429    }
430
431  hd.os = "";
432  hd.sys = "";
433  hd.mn = strip_suffix (bfd_get_filename (abfd));
434
435  sysroff_swap_hd_out (file, &hd);
436}
437
438
439static void
440wr_sh (p, sec)
441     struct coff_ofile *p;
442     struct coff_section *sec;
443{
444  struct IT_sh sh;
445  sh.unit = 0;
446  sh.section = sec->number;
447#ifdef FOOP1
448  sh.section = 0;
449#endif
450  sysroff_swap_sh_out (file, &sh);
451}
452
453
454static void
455wr_ob (p, section)
456     struct coff_ofile *p;
457     struct coff_section *section;
458{
459  bfd_size_type i;
460  int first = 1;
461  unsigned char stuff[200];
462
463  i = 0;
464  while (i < section->bfd_section->_raw_size)
465    {
466      struct IT_ob ob;
467      int todo = 200;		/* Copy in 200 byte lumps */
468      ob.spare = 0;
469      if (i + todo > section->bfd_section->_raw_size)
470	todo = section->bfd_section->_raw_size - i;
471
472      if (first)
473	{
474	  ob.saf = 1;
475	  if (bfd_get_file_flags (abfd) & EXEC_P)
476	    ob.address = section->address;
477	  else
478	    ob.address = 0;
479
480	  first = 0;
481	}
482      else
483	{
484	  ob.saf = 0;
485	}
486
487      ob.cpf = 0;		/* Never compress */
488      ob.data.len = todo;
489      bfd_get_section_contents (abfd, section->bfd_section, stuff, i, todo);
490      ob.data.data = stuff;
491      sysroff_swap_ob_out (file, &ob /*, i + todo < section->size */ );
492      i += todo;
493    }
494  /* Now fill the rest with blanks */
495  while (i < (bfd_size_type) section->size)
496    {
497      struct IT_ob ob;
498      int todo = 200;		/* Copy in 200 byte lumps */
499      ob.spare = 0;
500      if (i + todo > (bfd_size_type) section->size)
501	todo = section->size - i;
502      ob.saf = 0;
503
504      ob.cpf = 0;		/* Never compress */
505      ob.data.len = todo;
506      memset (stuff, 0, todo);
507      ob.data.data = stuff;
508      sysroff_swap_ob_out (file, &ob);
509      i += todo;
510    }
511  /* Now fill the rest with blanks */
512
513}
514
515static void
516wr_rl (ptr, sec)
517     struct coff_ofile *ptr;
518     struct coff_section *sec;
519{
520  int nr = sec->nrelocs;
521  int i;
522  for (i = 0; i < nr; i++)
523    {
524      struct coff_reloc *r = sec->relocs + i;
525      struct coff_symbol *ref;
526      struct IT_rl rl;
527      rl.apol = 0;
528      rl.boundary = 0;
529      rl.segment = 1;
530      rl.sign = 0;
531      rl.check = 0;
532      rl.addr = r->offset;
533      rl.bitloc = 0;
534      rl.flen = 32;		/* SH Specific */
535      /* What sort of reloc ? Look in the section to find out */
536      ref = r->symbol;
537      if (ref->visible->type == coff_vis_ext_ref)
538	{
539	  rl.bcount = 4;	/* Always 4 for us */
540	  rl.op = OP_EXT_REF;
541	  rl.symn = ref->er_number;
542	}
543      else if (ref->visible->type == coff_vis_common)
544	{
545	  rl.bcount = 11;	/* Always 11 for us */
546	  rl.op = OP_SEC_REF;
547	  rl.secn = ref->where->section->number;
548	  rl.copcode_is_3 = 3;
549	  rl.alength_is_4 = 4;
550	  rl.addend = ref->where->offset - ref->where->section->address;
551	  rl.aopcode_is_0x20 = 0x20;
552	}
553
554      else
555	{
556	  rl.bcount = 11;	/* Always 11 for us */
557	  rl.op = OP_SEC_REF;
558	  rl.secn = ref->where->section->number;
559	  rl.copcode_is_3 = 3;
560	  rl.alength_is_4 = 4;
561	  rl.addend = -ref->where->section->address;
562	  rl.aopcode_is_0x20 = 0x20;
563	}
564      rl.end = 0xff;
565      if (rl.op == OP_SEC_REF
566	  || rl.op == OP_EXT_REF)
567	{
568	  sysroff_swap_rl_out (file, &rl);
569	}
570    }
571}
572
573static void
574wr_object_body (p)
575     struct coff_ofile *p;
576{
577  int i;
578  for (i = 1; i < p->nsections; i++)
579    {
580      wr_sh (p, p->sections + i);
581      wr_ob (p, p->sections + i);
582      wr_rl (p, p->sections + i);
583    }
584}
585
586static void
587wr_dps_start (sfile, section, scope, type, nest)
588     struct coff_sfile *sfile;
589     struct coff_section *section;
590     struct coff_scope *scope;
591     int type;
592     int nest;
593{
594  struct IT_dps dps;
595  dps.end = 0;
596  dps.opt = 0;
597  dps.type = type;
598  if (scope->sec)
599    {
600      dps.san = scope->sec->number;
601      dps.address = scope->offset - find_base (sfile, scope->sec);
602      dps.block_size = scope->size;
603      if (debug)
604	{
605	  printf ("DPS %s %d %x\n",
606		  sfile->name,
607		  nest,
608		  dps.address);
609
610	}
611    }
612  else
613    {
614      dps.san = 0;
615      dps.address = 0;
616      dps.block_size = 0;
617    }
618
619  dps.nesting = nest;
620  dps.neg = 0x1001;
621  sysroff_swap_dps_out (file, &dps);
622}
623
624static void
625wr_dps_end (section, scope, type)
626     struct coff_section *section;
627     struct coff_scope *scope;
628     int type;
629{
630  struct IT_dps dps;
631  dps.end = 1;
632  dps.type = type;
633  sysroff_swap_dps_out (file, &dps);
634}
635
636static int *
637nints (x)
638     int x;
639{
640  return (int *) (xcalloc (sizeof (int), x));
641}
642
643static void walk_tree_symbol ();
644static void
645walk_tree_type_1 (sfile, symbol, type, nest)
646     struct coff_sfile *sfile;
647     struct coff_symbol *symbol;
648     struct coff_type *type;
649     int nest;
650{
651  switch (type->type)
652    {
653    case coff_secdef_type:
654    case coff_basic_type:
655      {
656	struct IT_dbt dbt;
657
658	switch (type->u.basic)
659	  {
660	  case T_NULL:
661	  case T_VOID:
662	    dbt.btype = BTYPE_VOID;
663	    dbt.sign = BTYPE_UNSPEC;
664	    dbt.fptype = FPTYPE_NOTSPEC;
665	    break;
666	  case T_CHAR:
667	    dbt.btype = BTYPE_CHAR;
668	    dbt.sign = BTYPE_UNSPEC;
669	    dbt.fptype = FPTYPE_NOTSPEC;
670	    break;
671	  case T_SHORT:
672	  case T_INT:
673	  case T_LONG:
674	    dbt.btype = BTYPE_INT;
675	    dbt.sign = SIGN_SIGNED;
676	    dbt.fptype = FPTYPE_NOTSPEC;
677	    break;
678	  case T_FLOAT:
679	    dbt.btype = BTYPE_FLOAT;
680	    dbt.fptype = FPTYPE_SINGLE;
681	    break;
682	  case T_DOUBLE:
683	    dbt.btype = BTYPE_FLOAT;
684	    dbt.fptype = FPTYPE_DOUBLE;
685	    break;
686	  case T_LNGDBL:
687	    dbt.btype = BTYPE_FLOAT;
688	    dbt.fptype = FPTYPE_EXTENDED;
689	    break;
690	  case T_UCHAR:
691	    dbt.btype = BTYPE_CHAR;
692	    dbt.sign = SIGN_UNSIGNED;
693	    dbt.fptype = FPTYPE_NOTSPEC;
694	    break;
695	  case T_USHORT:
696	  case T_UINT:
697	  case T_ULONG:
698	    dbt.btype = BTYPE_INT;
699	    dbt.sign = SIGN_UNSIGNED;
700	    dbt.fptype = FPTYPE_NOTSPEC;
701	    break;
702	  }
703	dbt.bitsize = type->size;
704	dbt.neg = 0x1001;
705	sysroff_swap_dbt_out (file, &dbt);
706	break;
707      }
708    case coff_pointer_type:
709      {
710	struct IT_dpt dpt;
711	walk_tree_type_1 (sfile, symbol, type->u.pointer.points_to, nest + 1);
712	dpt.neg = 0x1001;
713	sysroff_swap_dpt_out (file, &dpt);
714	break;
715      }
716
717    case coff_function_type:
718      {
719	struct IT_dfp dfp;
720	struct coff_symbol *param;
721	dfp.end = 0;
722	dfp.spare = 0;
723	dfp.nparams = type->u.function.parameters->nvars;
724	dfp.neg = 0x1001;
725
726	walk_tree_type_1 (sfile, symbol, type->u.function.function_returns, nest + 1);
727
728	sysroff_swap_dfp_out (file, &dfp);
729
730	for (param = type->u.function.parameters->vars_head;
731	     param;
732	     param = param->next)
733	  {
734	    walk_tree_symbol (sfile, 0, param, nest);
735	  }
736	dfp.end = 1;
737	sysroff_swap_dfp_out (file, &dfp);
738	break;
739      }
740
741    case coff_structdef_type:
742      {
743	struct IT_dbt dbt;
744	struct IT_dds dds;
745	struct coff_symbol *member;
746	dds.spare = 0;
747	dbt.btype = BTYPE_STRUCT;
748	dbt.bitsize = type->size;
749	dbt.sign = SIGN_UNSPEC;
750	dbt.fptype = FPTYPE_NOTSPEC;
751	dbt.sid = get_member_id (type->u.astructdef.idx);
752	dbt.neg = 0x1001;
753	sysroff_swap_dbt_out (file, &dbt);
754	dds.end = 0;
755	dds.neg = 0x1001;
756	sysroff_swap_dds_out (file, &dds);
757	for (member = type->u.astructdef.elements->vars_head;
758	     member;
759	     member = member->next)
760	  {
761	    walk_tree_symbol (sfile, 0, member, nest + 1);
762	  }
763
764	dds.end = 1;
765	sysroff_swap_dds_out (file, &dds);
766
767      }
768      break;
769    case coff_structref_type:
770      {
771	struct IT_dbt dbt;
772	dbt.btype = BTYPE_TAG;
773	dbt.bitsize = type->size;
774	dbt.sign = SIGN_UNSPEC;
775	dbt.fptype = FPTYPE_NOTSPEC;
776	if (type->u.astructref.ref)
777	  {
778	    dbt.sid = get_member_id (type->u.astructref.ref->number);
779	  }
780	else
781	  {
782	    dbt.sid = 0;
783	  }
784
785	dbt.neg = 0x1001;
786	sysroff_swap_dbt_out (file, &dbt);
787      }
788      break;
789    case coff_array_type:
790      {
791	struct IT_dar dar;
792	int j;
793	int dims = 1;		/* Only output one dimension at a time */
794	dar.dims = dims;
795	dar.variable = nints (dims);
796	dar.subtype = nints (dims);
797	dar.spare = nints (dims);
798	dar.max_variable = nints (dims);
799	dar.maxspare = nints (dims);
800	dar.max = nints (dims);
801	dar.min_variable = nints (dims);
802	dar.min = nints (dims);
803	dar.minspare = nints (dims);
804	dar.neg = 0x1001;
805	dar.length = type->size / type->u.array.dim;
806	for (j = 0; j < dims; j++)
807	  {
808	    dar.variable[j] = VARIABLE_FIXED;
809	    dar.subtype[j] = SUB_INTEGER;
810	    dar.spare[j] = 0;
811	    dar.max_variable[j] = 0;
812	    dar.max[j] = type->u.array.dim;
813	    dar.min_variable[j] = 0;
814	    dar.min[j] = 1;	/* Why isn't this 0 ? */
815	  }
816	walk_tree_type_1 (sfile, symbol, type->u.array.array_of, nest + 1);
817	sysroff_swap_dar_out (file, &dar);
818      }
819      break;
820    case coff_enumdef_type:
821      {
822	struct IT_dbt dbt;
823	struct IT_den den;
824	struct coff_symbol *member;
825	dbt.btype = BTYPE_ENUM;
826	dbt.bitsize = type->size;
827	dbt.sign = SIGN_UNSPEC;
828	dbt.fptype = FPTYPE_NOTSPEC;
829	dbt.sid = get_member_id (type->u.aenumdef.idx);
830	dbt.neg = 0x1001;
831	sysroff_swap_dbt_out (file, &dbt);
832
833	den.end = 0;
834	den.neg = 0x1001;
835	den.spare = 0;
836	sysroff_swap_den_out (file, &den);
837	for (member = type->u.aenumdef.elements->vars_head;
838	     member;
839	     member = member->next)
840	  {
841	    walk_tree_symbol (sfile, 0, member, nest + 1);
842	  }
843
844	den.end = 1;
845	sysroff_swap_den_out (file, &den);
846      }
847      break;
848
849      break;
850    case coff_enumref_type:
851      {
852	struct IT_dbt dbt;
853	dbt.btype = BTYPE_TAG;
854	dbt.bitsize = type->size;
855	dbt.sign = SIGN_UNSPEC;
856	dbt.fptype = FPTYPE_NOTSPEC;
857	dbt.sid = get_member_id (type->u.aenumref.ref->number);
858	dbt.neg = 0x1001;
859	sysroff_swap_dbt_out (file, &dbt);
860      }
861      break;
862    default:
863      abort ();
864    }
865}
866
867/* Obsolete ?
868   static void
869   dty_start ()
870   {
871   struct IT_dty dty;
872   dty.end = 0;
873   dty.neg = 0x1001;
874   dty.spare = 0;
875   sysroff_swap_dty_out (file, &dty);
876   }
877
878   static void
879   dty_stop ()
880   {
881   struct IT_dty dty;
882   dty.end = 0;
883   dty.neg = 0x1001;
884   dty.end = 1;
885   sysroff_swap_dty_out (file, &dty);
886   }
887
888
889   static void
890   dump_tree_structure (sfile, symbol, type, nest)
891   struct coff_sfile *sfile;
892   struct coff_symbol *symbol;
893   struct coff_type *type;
894   int nest;
895   {
896   if (symbol->type->type == coff_function_type)
897   {
898
899
900   }
901
902   }
903 */
904
905static void
906walk_tree_type (sfile, symbol, type, nest)
907
908     struct
909     coff_sfile *sfile;
910     struct coff_symbol *symbol;
911     struct coff_type *type;
912     int nest;
913{
914  if (symbol->type->type == coff_function_type)
915    {
916
917      struct IT_dty dty;
918      dty.end = 0;
919      dty.neg = 0x1001;
920
921      sysroff_swap_dty_out (file, &dty);
922      walk_tree_type_1 (sfile, symbol, type, nest);
923      dty.end = 1;
924      sysroff_swap_dty_out (file, &dty);
925
926      wr_dps_start (sfile,
927		    symbol->where->section,
928		    symbol->type->u.function.code,
929		    BLOCK_TYPE_FUNCTION, nest);
930      wr_dps_start (sfile, symbol->where->section,
931		    symbol->type->u.function.code,
932		    BLOCK_TYPE_BLOCK, nest);
933      walk_tree_scope (symbol->where->section,
934		       sfile,
935		       symbol->type->u.function.code,
936		       nest + 1, BLOCK_TYPE_BLOCK);
937
938      wr_dps_end (symbol->where->section,
939		  symbol->type->u.function.code,
940		  BLOCK_TYPE_BLOCK);
941      wr_dps_end (symbol->where->section,
942		  symbol->type->u.function.code, BLOCK_TYPE_FUNCTION);
943
944    }
945  else
946    {
947      struct IT_dty dty;
948      dty.end = 0;
949      dty.neg = 0x1001;
950      sysroff_swap_dty_out (file, &dty);
951      walk_tree_type_1 (sfile, symbol, type, nest);
952      dty.end = 1;
953      sysroff_swap_dty_out (file, &dty);
954    }
955
956}
957
958
959
960static void
961walk_tree_symbol (sfile, section, symbol, nest)
962     struct coff_sfile *sfile;
963     struct coff_section *section;
964     struct coff_symbol *symbol;
965     int nest;
966{
967  struct IT_dsy dsy;
968
969  memset(&dsy, 0, sizeof(dsy));
970  dsy.nesting = nest;
971
972  switch (symbol->type->type)
973    {
974    case coff_function_type:
975      dsy.type = STYPE_FUNC;
976      dsy.assign = 1;
977      break;
978    case coff_structref_type:
979    case coff_pointer_type:
980    case coff_array_type:
981    case coff_basic_type:
982    case coff_enumref_type:
983      dsy.type = STYPE_VAR;
984      dsy.assign = 1;
985      break;
986    case coff_enumdef_type:
987      dsy.type = STYPE_TAG;
988      dsy.assign = 0;
989      dsy.magic = 2;
990      break;
991    case coff_structdef_type:
992      dsy.type = STYPE_TAG;
993      dsy.assign = 0;
994      dsy.magic = symbol->type->u.astructdef.isstruct ? 0 : 1;
995      break;
996    case coff_secdef_type:
997      return;
998    default:
999      abort ();
1000    }
1001
1002  if (symbol->where->where == coff_where_member_of_struct)
1003    {
1004      dsy.assign = 0;
1005      dsy.type = STYPE_MEMBER;
1006    }
1007  if (symbol->where->where == coff_where_member_of_enum)
1008    {
1009      dsy.type = STYPE_ENUM;
1010      dsy.assign = 0;
1011      dsy.evallen = 4;
1012      dsy.evalue = symbol->where->offset;
1013    }
1014
1015  if (symbol->type->type == coff_structdef_type
1016      || symbol->where->where == coff_where_entag
1017      || symbol->where->where == coff_where_strtag)
1018    {
1019      dsy.snumber = get_member_id (symbol->number);
1020    }
1021  else
1022    {
1023      dsy.snumber = get_ordinary_id (symbol->number);
1024    }
1025
1026
1027  dsy.sname = symbol->name[0] == '_' ? symbol->name + 1 : symbol->name;
1028
1029  switch (symbol->visible->type)
1030    {
1031    case coff_vis_common:
1032    case coff_vis_ext_def:
1033      dsy.ainfo = AINFO_STATIC_EXT_DEF;
1034      break;
1035    case coff_vis_ext_ref:
1036      dsy.ainfo = AINFO_STATIC_EXT_REF;
1037      break;
1038    case coff_vis_int_def:
1039      dsy.ainfo = AINFO_STATIC_INT;
1040      break;
1041    case coff_vis_auto:
1042    case coff_vis_autoparam:
1043      dsy.ainfo = AINFO_AUTO;
1044      break;
1045    case coff_vis_register:
1046    case coff_vis_regparam:
1047      dsy.ainfo = AINFO_REG;
1048      break;
1049      break;
1050    case coff_vis_tag:
1051    case coff_vis_member_of_struct:
1052    case coff_vis_member_of_enum:
1053      break;
1054    default:
1055      abort ();
1056    }
1057
1058  dsy.dlength = symbol->type->size;
1059  switch (symbol->where->where)
1060    {
1061    case coff_where_memory:
1062
1063      dsy.section = symbol->where->section->number;
1064#ifdef FOOP
1065      dsy.section = 0;
1066#endif
1067      break;
1068    case coff_where_member_of_struct:
1069    case coff_where_member_of_enum:
1070    case coff_where_stack:
1071    case coff_where_register:
1072    case coff_where_unknown:
1073    case coff_where_strtag:
1074
1075    case coff_where_entag:
1076    case coff_where_typedef:
1077      break;
1078    default:
1079      abort ();
1080    }
1081
1082  switch (symbol->where->where)
1083    {
1084    case coff_where_memory:
1085      dsy.address = symbol->where->offset - find_base (sfile, symbol->where->section);
1086      break;
1087    case coff_where_stack:
1088      dsy.address = symbol->where->offset;
1089      break;
1090    case coff_where_member_of_struct:
1091
1092
1093      if (symbol->where->bitsize)
1094	{
1095	  int bits = (symbol->where->offset * 8 + symbol->where->bitoffset);
1096	  dsy.bitunit = 1;
1097	  dsy.field_len = symbol->where->bitsize;
1098	  dsy.field_off = (bits / 32) * 4;
1099	  dsy.field_bitoff = bits % 32;
1100	}
1101      else
1102	{
1103	  dsy.bitunit = 0;
1104
1105	  dsy.field_len = symbol->type->size;
1106	  dsy.field_off = symbol->where->offset;
1107	}
1108      break;
1109    case coff_where_member_of_enum:
1110      /*      dsy.bitunit = 0;
1111         dsy.field_len  = symbol->type->size;
1112         dsy.field_off = symbol->where->offset; */
1113      break;
1114    case coff_where_register:
1115    case coff_where_unknown:
1116    case coff_where_strtag:
1117
1118    case coff_where_entag:
1119    case coff_where_typedef:
1120      break;
1121    default:
1122      abort ();
1123    }
1124
1125  if (symbol->where->where == coff_where_register)
1126    dsy.reg = rnames[symbol->where->offset];
1127
1128  switch (symbol->visible->type)
1129    {
1130    case coff_vis_common:
1131      /* We do this 'cause common C symbols are treated as extdefs */
1132    case coff_vis_ext_def:
1133    case coff_vis_ext_ref:
1134
1135      dsy.ename = symbol->name;
1136      break;
1137
1138    case coff_vis_regparam:
1139    case coff_vis_autoparam:
1140      dsy.type = STYPE_PARAMETER;
1141      break;
1142
1143    case coff_vis_int_def:
1144
1145    case coff_vis_auto:
1146    case coff_vis_register:
1147    case coff_vis_tag:
1148    case coff_vis_member_of_struct:
1149    case coff_vis_member_of_enum:
1150      break;
1151    default:
1152      abort ();
1153    }
1154
1155  dsy.sfn = 0;
1156  dsy.sln = 2;
1157
1158  dsy.neg = 0x1001;
1159
1160
1161  sysroff_swap_dsy_out (file, &dsy);
1162
1163  walk_tree_type (sfile, symbol, symbol->type, nest);
1164}
1165
1166
1167static void
1168walk_tree_scope (section, sfile, scope, nest, type)
1169     struct coff_section *section;
1170     struct coff_sfile *sfile;
1171     struct coff_scope *scope;
1172     int nest;
1173     int type;
1174{
1175  struct coff_symbol *vars;
1176  struct coff_scope *child;
1177
1178  if (scope->vars_head
1179      || (scope->list_head && scope->list_head->vars_head))
1180    {
1181      wr_dps_start (sfile, section, scope, type, nest);
1182
1183      if (nest == 0)
1184	wr_globals (tree, sfile, nest + 1);
1185
1186      for (vars = scope->vars_head; vars; vars = vars->next)
1187	{
1188	  walk_tree_symbol (sfile, section, vars, nest);
1189	}
1190
1191      for (child = scope->list_head; child; child = child->next)
1192	{
1193	  walk_tree_scope (section, sfile, child, nest + 1, BLOCK_TYPE_BLOCK);
1194	}
1195
1196      wr_dps_end (section, scope, type);
1197    }
1198}
1199static void
1200walk_tree_sfile (section, sfile)
1201     struct coff_section *section;
1202     struct coff_sfile *sfile;
1203{
1204  walk_tree_scope (section, sfile, sfile->scope, 0, BLOCK_TYPE_COMPUNIT);
1205
1206}
1207
1208static void
1209wr_program_structure (p, sfile)
1210     struct coff_ofile *p;
1211     struct coff_sfile *sfile;
1212{
1213
1214  walk_tree_sfile (p->sections + 4, sfile);
1215
1216}
1217
1218static void
1219wr_du (p, sfile, n)
1220     struct coff_ofile *p;
1221     struct coff_sfile *sfile;
1222     int n;
1223{
1224  struct IT_du du;
1225  int lim;
1226#if 0
1227  struct coff_symbol *symbol;
1228  static int incit = 0x500000;
1229  int used = 0;
1230#endif
1231  int i;
1232  int j;
1233  unsigned int *lowest = (unsigned *) nints (p->nsections);
1234  unsigned int *highest = (unsigned *) nints (p->nsections);
1235  du.format = bfd_get_file_flags (abfd) & EXEC_P ? 0 : 1;
1236  du.optimized = 0;
1237  du.stackfrmt = 0;
1238  du.spare = 0;
1239  du.unit = n;
1240  du.sections = p->nsections - 1;
1241  du.san = (int *) xcalloc (sizeof (int), du.sections);
1242  du.address = nints (du.sections);
1243  du.length = nints (du.sections);
1244
1245  for (i = 0; i < du.sections; i++)
1246    {
1247      lowest[i] = ~0;
1248      highest[i] = 0;
1249    }
1250
1251  /* Look through all the symbols and try and work out the extents in this
1252     source file */
1253#if 0
1254  for (symbol = sfile->scope->vars_head;
1255       symbol;
1256       symbol = symbol->next)
1257    {
1258      if (symbol->type->type == coff_secdef_type)
1259	{
1260	  unsigned int low = symbol->where->offset;
1261	  unsigned int high = symbol->where->offset + symbol->type->size - 1;
1262	  struct coff_section *section = symbol->where->section;
1263
1264	  int sn = section->number;
1265	  if (low < lowest[sn])
1266	    lowest[sn] = low;
1267	  if (high > highest[sn])
1268	    highest[sn] = high;
1269	}
1270    }
1271
1272
1273  for (i = 0; i < du.sections; i++)
1274    {
1275      if (highest[i] == 0)
1276	{
1277	  lowest[i] = highest[i] = incit;
1278	}
1279      du.san[used] = i;
1280      du.length[used] = highest[i] - lowest[i];
1281      du.address[used] = bfd_get_file_flags (abfd) & EXEC_P ? lowest[i] : 0;
1282      if (debug)
1283	{
1284	  printf (" section %6s 0x%08x..0x%08x\n",
1285		  p->sections[i + 1].name,
1286		  lowest[i],
1287		  highest[i]);
1288	}
1289      used++;
1290    }
1291
1292#endif
1293  lim = du.sections;
1294  for (j = 0; j < lim; j++)
1295    {
1296      int src = j;
1297      int dst = j;
1298      du.san[dst] = dst;
1299      if (sfile->section[src].init)
1300	{
1301	  du.length[dst]
1302	    = sfile->section[src].high - sfile->section[src].low + 1;
1303	  du.address[dst]
1304	    = sfile->section[src].low;
1305	}
1306      else
1307	{
1308	  du.length[dst] = 0;
1309	  du.address[dst] = 0;
1310	}
1311      if (debug)
1312	{
1313	  if (sfile->section[src].parent)
1314	    {
1315	      printf (" section %6s 0x%08x..0x%08x\n",
1316		      sfile->section[src].parent->name,
1317		      du.address[dst],
1318		      du.address[dst] + du.length[dst] - 1);
1319	    }
1320	}
1321      du.sections = dst + 1;
1322    }
1323
1324  du.tool = "c_gcc";
1325  du.date = DATE;
1326
1327  sysroff_swap_du_out (file, &du);
1328}
1329
1330static void
1331wr_dus (p, sfile)
1332     struct coff_ofile *p;
1333     struct coff_sfile *sfile;
1334{
1335
1336  struct IT_dus dus;
1337
1338  dus.efn = 0x1001;
1339  dus.ns = 1;			/* p->nsources; sac 14 jul 94 */
1340  dus.drb = nints (dus.ns);
1341  dus.fname = (char **) xcalloc (sizeof (char *), dus.ns);
1342  dus.spare = nints (dus.ns);
1343  dus.ndir = 0;
1344  /* Find the filenames */
1345#if 0
1346  i = 0;
1347
1348  for (sfile = p->source_head;
1349       sfile;
1350       sfile = sfile->next)
1351    {
1352      dus.drb[i] = 0;
1353      dus.spare[i] = 0;
1354      dus.fname[i] = sfile->name;
1355      i++;
1356    }
1357#else
1358  dus.drb[0] = 0;
1359  dus.fname[0] = sfile->name;
1360#endif
1361
1362  sysroff_swap_dus_out (file, &dus);
1363
1364}
1365
1366/* Find the offset of the .text section for this sfile in the
1367   .text section for the output file */
1368
1369static int
1370find_base (sfile, section)
1371     struct coff_sfile *sfile;
1372     struct coff_section *section;
1373{
1374  return sfile->section[section->number].low;
1375}
1376static void
1377wr_dln (p, sfile, n)
1378     struct coff_ofile *p;
1379     struct coff_sfile *sfile;
1380     int n;
1381
1382{
1383#if 0
1384  if (n == 0)
1385    {
1386      /* Count up all the linenumbers */
1387      struct coff_symbol *sy;
1388      int lc = 0;
1389      struct IT_dln dln;
1390
1391      int idx;
1392
1393      for (sy = p->symbol_list_head;
1394	   sy;
1395	   sy = sy->next_in_ofile_list)
1396	{
1397	  struct coff_type *t = sy->type;
1398	  if (t->type == coff_function_type)
1399	    {
1400	      struct coff_line *l = t->u.function.lines;
1401	      lc += l->nlines;
1402	    }
1403	}
1404
1405      dln.sfn = nints (lc);
1406      dln.sln = nints (lc);
1407      dln.lln = nints (lc);
1408      dln.section = nints (lc);
1409
1410      dln.from_address = nints (lc);
1411      dln.to_address = nints (lc);
1412
1413
1414      dln.neg = 0x1001;
1415
1416      dln.nln = lc;
1417
1418      /* Run through once more and fill up the structure */
1419      idx = 0;
1420      for (sy = p->symbol_list_head;
1421	   sy;
1422	   sy = sy->next_in_ofile_list)
1423	{
1424	  if (sy->type->type == coff_function_type)
1425	    {
1426	      int i;
1427	      struct coff_line *l = sy->type->u.function.lines;
1428	      for (i = 0; i < l->nlines; i++)
1429		{
1430		  dln.section[idx] = sy->where->section->number;
1431		  dln.sfn[idx] = n;
1432		  dln.sln[idx] = l->lines[i];
1433		  dln.from_address[idx] = l->addresses[i];
1434		  if (idx)
1435		    dln.to_address[idx - 1] = dln.from_address[idx];
1436		  idx++;
1437		}
1438	    }
1439	  n++;
1440	}
1441      sysroff_swap_dln_out (file, &dln);
1442    }
1443
1444#endif
1445#if 1
1446  /* Count up all the linenumbers */
1447
1448  struct coff_symbol *sy;
1449  int lc = 0;
1450  struct IT_dln dln;
1451
1452  int idx;
1453
1454  for (sy = sfile->scope->vars_head;
1455       sy;
1456       sy = sy->next)
1457    {
1458      struct coff_type *t = sy->type;
1459      if (t->type == coff_function_type)
1460	{
1461	  struct coff_line *l = t->u.function.lines;
1462	  if (l)
1463	    lc += l->nlines;
1464	}
1465    }
1466
1467  dln.sfn = nints (lc);
1468  dln.sln = nints (lc);
1469  dln.cc = nints (lc);
1470  dln.section = nints (lc);
1471
1472  dln.from_address = nints (lc);
1473  dln.to_address = nints (lc);
1474
1475
1476  dln.neg = 0x1001;
1477
1478  dln.nln = lc;
1479
1480  /* Run through once more and fill up the structure */
1481  idx = 0;
1482  for (sy = sfile->scope->vars_head;
1483       sy;
1484       sy = sy->next)
1485    {
1486      if (sy->type->type == coff_function_type)
1487	{
1488	  int i;
1489	  struct coff_line *l = sy->type->u.function.lines;
1490	  if (l)
1491	    {
1492	      int base = find_base (sfile, sy->where->section);
1493	      for (i = 0; i < l->nlines; i++)
1494		{
1495		  dln.section[idx] = sy->where->section->number;
1496		  dln.sfn[idx] = 0;
1497		  dln.sln[idx] = l->lines[i];
1498		  dln.from_address[idx] =
1499		    l->addresses[i] + sy->where->section->address - base;
1500		  dln.cc[idx] = 0;
1501		  if (idx)
1502		    dln.to_address[idx - 1] = dln.from_address[idx];
1503		  idx++;
1504
1505		}
1506	      dln.to_address[idx - 1] = dln.from_address[idx - 1] + 2;
1507	    }
1508	}
1509    }
1510  if (lc)
1511    sysroff_swap_dln_out (file, &dln);
1512#endif
1513}
1514
1515/* Write the global symbols out to the debug info */
1516static void
1517wr_globals (p, sfile, n)
1518     struct coff_ofile *p;
1519     struct coff_sfile *sfile;
1520     int n;
1521{
1522  struct coff_symbol *sy;
1523  for (sy = p->symbol_list_head;
1524       sy;
1525       sy = sy->next_in_ofile_list)
1526    {
1527      if (sy->visible->type == coff_vis_ext_def
1528	  || sy->visible->type == coff_vis_ext_ref)
1529	{
1530	  /* Only write out symbols if they belong to
1531	     the current source file */
1532	  if (sy->sfile == sfile)
1533	    walk_tree_symbol (sfile, 0, sy, 0);
1534
1535	}
1536    }
1537}
1538
1539static void
1540wr_debug (p)
1541     struct coff_ofile *p;
1542{
1543  struct coff_sfile *sfile;
1544  int n = 0;
1545  for (sfile = p->source_head;
1546       sfile;
1547       sfile = sfile->next)
1548
1549    {
1550      if (debug)
1551	{
1552	  printf ("%s\n", sfile->name);
1553	}
1554      wr_du (p, sfile, n);
1555      wr_dus (p, sfile);
1556      wr_program_structure (p, sfile);
1557      wr_dln (p, sfile, n);
1558      n++;
1559    }
1560}
1561
1562static void
1563wr_cs ()
1564{
1565  /* It seems that the CS struct is not normal - the size is wrong
1566     heres one I prepared earlier.. */
1567  static char b[] = {
1568    0x80,			/* IT */
1569    0x21,			/* RL */
1570    0x00,			/* number of chars in variable length part */
1571    0x80,			/* hd */
1572    0x00,			/* hs */
1573    0x80,			/* un */
1574    0x00,			/* us */
1575    0x80,			/* sc */
1576    0x00,			/* ss */
1577    0x80,			/* er */
1578    0x80,			/* ed */
1579    0x80,			/* sh */
1580    0x80,			/* ob */
1581    0x80,			/* rl */
1582    0x80,			/* du */
1583    0x80,			/* dps */
1584    0x80,			/* dsy */
1585    0x80,			/* dty */
1586    0x80,			/* dln */
1587    0x80,			/* dso */
1588    0x80,			/* dus */
1589    0x00,			/* dss */
1590    0x80,			/* dbt */
1591    0x00,			/* dpp */
1592    0x80,			/* dfp */
1593    0x80,			/* den */
1594    0x80,			/* dds */
1595    0x80,			/* dar */
1596    0x80,			/* dpt */
1597    0x00,			/* dul */
1598    0x00,			/* dse */
1599    0x00,			/* dot */
1600    0xDE			/* CS */
1601  };
1602  fwrite (b, 1, sizeof (b), file);
1603}
1604
1605/* Write out the SC records for a unit.  Create an SC
1606   for all the sections which appear in the output file, even
1607   if there isn't an equivalent one on the input */
1608
1609static int
1610wr_sc (ptr, sfile)
1611     struct coff_ofile *ptr;
1612     struct coff_sfile *sfile;
1613{
1614  int i;
1615int scount = 0;
1616  /* First work out the total number of sections */
1617
1618  int total_sec = ptr->nsections;
1619
1620  struct myinfo
1621    {
1622      struct coff_section *sec;
1623      struct coff_symbol *symbol;
1624    };
1625  struct coff_symbol *symbol;
1626
1627  struct myinfo *info
1628    = (struct myinfo *) calloc (total_sec, sizeof (struct myinfo));
1629
1630
1631
1632  for (i = 0; i < total_sec; i++)
1633    {
1634      info[i].sec = ptr->sections + i;
1635      info[i].symbol = 0;
1636    }
1637
1638  for (symbol = sfile->scope->vars_head;
1639       symbol;
1640       symbol = symbol->next)
1641    {
1642
1643      if (symbol->type->type == coff_secdef_type)
1644	{
1645	  for (i = 0; i < total_sec; i++)
1646	    {
1647	      if (symbol->where->section == info[i].sec)
1648		{
1649		  info[i].symbol = symbol;
1650		  break;
1651		}
1652	    }
1653	}
1654    }
1655
1656  /* Now output all the section info, and fake up some stuff for sections
1657     we don't have */
1658
1659  for (i = 1; i < total_sec; i++)
1660    {
1661      struct IT_sc sc;
1662      char *name;
1663      symbol = info[i].symbol;
1664      sc.spare = 0;
1665      sc.spare1 = 0;
1666      if (!symbol)
1667	{
1668	  /* Don't have a symbol set aside for this section, which means that nothing
1669	     in this file does anything for the section. */
1670	  sc.format = !(bfd_get_file_flags (abfd) & EXEC_P);
1671	  sc.addr = 0;
1672	  sc.length = 0;
1673	  name = info[i].sec->name;
1674	}
1675      else
1676	{
1677	  if (bfd_get_file_flags (abfd) & EXEC_P)
1678	    {
1679	      sc.format = 0;
1680	      sc.addr = symbol->where->offset;
1681	    }
1682	  else
1683	    {
1684	      sc.format = 1;
1685	      sc.addr = 0;
1686	    }
1687	  sc.length = symbol->type->size;
1688	  name = symbol->name;
1689	}
1690
1691      sc.align = 4;
1692
1693      sc.concat = CONCAT_SIMPLE;
1694      sc.read = 3;
1695      sc.write = 3;
1696      sc.exec = 3;
1697      sc.init = 3;
1698      sc.mode = 3;
1699      sc.spare = 0;
1700      sc.segadd = 0;
1701      sc.spare1 = 0;		/* If not zero, then it doesn't work */
1702      sc.name = section_translate (name);
1703      if (strlen (sc.name) == 1)
1704	{
1705	  switch (sc.name[0])
1706	    {
1707	    case 'D':
1708	    case 'B':
1709	      sc.contents = CONTENTS_DATA;
1710	      break;
1711	    default:
1712	      sc.contents = CONTENTS_CODE;
1713	    }
1714	}
1715      else
1716	{
1717	  sc.contents = CONTENTS_CODE;
1718	}
1719#if 0
1720      /* NEW */
1721      if (sc.length) {
1722#endif
1723	sysroff_swap_sc_out (file, &sc);
1724	scount++;
1725#if 0
1726      }
1727#endif
1728    }
1729return scount;
1730}
1731
1732
1733/* Write out the ER records for a unit. */
1734static void
1735wr_er (ptr, sfile, first)
1736     struct coff_ofile *ptr;
1737     struct coff_sfile *sfile;
1738     int first;
1739{
1740  int idx = 0;
1741  struct coff_symbol *sym;
1742  if (first)
1743    {
1744      for (sym = ptr->symbol_list_head; sym; sym = sym->next_in_ofile_list)
1745	{
1746	  if (sym->visible->type == coff_vis_ext_ref)
1747	    {
1748	      struct IT_er er;
1749	      er.spare = 0;
1750	      er.type = ER_NOTSPEC;
1751	      er.name = sym->name;
1752	      sysroff_swap_er_out (file, &er);
1753	      sym->er_number = idx++;
1754	    }
1755	}
1756    }
1757}
1758
1759/* Write out the ED records for a unit. */
1760static void
1761wr_ed (ptr, sfile, first)
1762     struct coff_ofile *ptr;
1763     struct coff_sfile *sfile;
1764     int first;
1765{
1766  struct coff_symbol *s;
1767  if (first)
1768    {
1769      for (s = ptr->symbol_list_head; s; s = s->next_in_ofile_list)
1770	{
1771	  if (s->visible->type == coff_vis_ext_def
1772	      || s->visible->type == coff_vis_common)
1773	    {
1774	      struct IT_ed ed;
1775
1776	      ed.section = s->where->section->number;
1777	      ed.spare = 0;
1778	      if (s->where->section->data)
1779		{
1780		  ed.type = ED_TYPE_DATA;
1781		}
1782	      else if (s->where->section->code & SEC_CODE)
1783		{
1784		  ed.type = ED_TYPE_ENTRY;
1785		}
1786	      else
1787		{
1788		  ed.type = ED_TYPE_NOTSPEC;
1789		  ed.type = ED_TYPE_DATA;
1790		}
1791	      ed.address = s->where->offset - s->where->section->address;
1792	      ed.name = s->name;
1793	      sysroff_swap_ed_out (file, &ed);
1794	    }
1795	}
1796    }
1797}
1798
1799static void
1800wr_unit_info (ptr)
1801     struct coff_ofile *ptr;
1802{
1803  struct coff_sfile *sfile;
1804  int first = 1;
1805  for (sfile = ptr->source_head;
1806       sfile;
1807       sfile = sfile->next)
1808    {
1809      long p1;
1810      long p2;
1811      int nsecs;
1812      p1 = ftell (file);
1813      wr_un (ptr, sfile, first, 0);
1814      nsecs = wr_sc (ptr, sfile);
1815      p2 = ftell (file);
1816      fseek (file, p1, SEEK_SET);
1817      wr_un (ptr, sfile, first, nsecs);
1818      fseek (file, p2, SEEK_SET);
1819      wr_er (ptr, sfile, first);
1820      wr_ed (ptr, sfile, first);
1821      first = 0;
1822    }
1823}
1824
1825static void
1826wr_module (p)
1827     struct coff_ofile *p;
1828{
1829  wr_cs ();
1830  wr_hd (p);
1831  wr_unit_info (p);
1832  wr_object_body (p);
1833  wr_debug (p);
1834  wr_tr ();
1835}
1836
1837static int
1838align (x)
1839     int x;
1840{
1841  return (x + 3) & ~3;
1842}
1843
1844/* Find all the common variables and turn them into
1845   ordinary defs - dunno why, but thats what hitachi does with 'em */
1846
1847static void
1848prescan (tree)
1849     struct coff_ofile *tree;
1850{
1851  struct coff_symbol *s;
1852  struct coff_section *common_section;
1853  /* Find the common section - always section 3 */
1854  common_section = tree->sections + 3;
1855  for (s = tree->symbol_list_head;
1856       s;
1857       s = s->next_in_ofile_list)
1858    {
1859      if (s->visible->type == coff_vis_common)
1860	{
1861	  struct coff_where *w = s->where;
1862	  /*      s->visible->type = coff_vis_ext_def; leave it as common */
1863	  common_section->size = align (common_section->size);
1864	  w->offset = common_section->size + common_section->address;
1865	  w->section = common_section;
1866	  common_section->size += s->type->size;
1867	  common_section->size = align (common_section->size);
1868	}
1869    }
1870}
1871
1872char *program_name;
1873
1874static void
1875show_usage (file, status)
1876     FILE *file;
1877     int status;
1878{
1879  fprintf (file, _("Usage: %s [-dhVq] in-file [out-file]\n"), program_name);
1880  exit (status);
1881}
1882
1883static void
1884show_help ()
1885{
1886  printf (_("%s: Convert a COFF object file into a SYSROFF object file\n"),
1887	  program_name);
1888  show_usage (stdout, 0);
1889}
1890
1891
1892
1893int
1894main (ac, av)
1895     int ac;
1896     char *av[];
1897{
1898  int opt;
1899  static struct option long_options[] =
1900  {
1901    {"debug", no_argument, 0, 'd'},
1902    {"quick", no_argument, 0, 'q'},
1903    {"noprescan", no_argument, 0, 'n'},
1904    {"help", no_argument, 0, 'h'},
1905    {"version", no_argument, 0, 'V'},
1906    {NULL, no_argument, 0, 0}
1907  };
1908  char **matching;
1909  char *input_file;
1910  char *output_file;
1911
1912#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
1913  setlocale (LC_MESSAGES, "");
1914#endif
1915  bindtextdomain (PACKAGE, LOCALEDIR);
1916  textdomain (PACKAGE);
1917
1918  program_name = av[0];
1919  xmalloc_set_program_name (program_name);
1920
1921  while ((opt = getopt_long (ac, av, "dhVqn", long_options,
1922			     (int *) NULL))
1923	 != EOF)
1924    {
1925      switch (opt)
1926	{
1927	case 'q':
1928	  quick = 1;
1929	  break;
1930	case 'n':
1931	  noprescan = 1;
1932	  break;
1933	case 'd':
1934	  debug = 1;
1935	  break;
1936	case 'h':
1937	  show_help ();
1938	  /*NOTREACHED */
1939	case 'V':
1940	  printf (_("GNU %s version %s\n"), program_name, PROGRAM_VERSION);
1941	  exit (0);
1942	  /*NOTREACHED */
1943	case 0:
1944	  break;
1945	default:
1946	  show_usage (stderr, 1);
1947	  /*NOTREACHED */
1948	}
1949    }
1950
1951  /* The input and output files may be named on the command line.  */
1952  output_file = NULL;
1953  if (optind < ac)
1954    {
1955      input_file = av[optind];
1956      ++optind;
1957      if (optind < ac)
1958	{
1959	  output_file = av[optind];
1960	  ++optind;
1961	  if (optind < ac)
1962	    show_usage (stderr, 1);
1963	  if (strcmp (input_file, output_file) == 0)
1964	    {
1965	      fatal (_("input and output files must be different"));
1966	    }
1967	}
1968    }
1969  else
1970    input_file = 0;
1971
1972  if (!input_file)
1973    {
1974      fatal (_("no input file specified"));
1975    }
1976
1977  if (!output_file)
1978    {
1979      /* Take a .o off the input file and stick on a .obj.  If
1980         it doesn't end in .o, then stick a .obj on anyway */
1981
1982      int len = strlen (input_file);
1983      output_file = xmalloc (len + 5);
1984      strcpy (output_file, input_file);
1985      if (len > 3
1986	  && output_file[len - 2] == '.'
1987	  && output_file[len - 1] == 'o')
1988	{
1989	  output_file[len] = 'b';
1990	  output_file[len + 1] = 'j';
1991	  output_file[len + 2] = 0;
1992	}
1993      else
1994	{
1995	  strcat (output_file, ".obj");
1996	}
1997    }
1998
1999  abfd = bfd_openr (input_file, 0);
2000
2001  if (!abfd)
2002    bfd_fatal (input_file);
2003
2004  if (!bfd_check_format_matches (abfd, bfd_object, &matching))
2005    {
2006      bfd_nonfatal (input_file);
2007      if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
2008	{
2009	  list_matching_formats (matching);
2010	  free (matching);
2011	}
2012      exit (1);
2013    }
2014
2015  file = fopen (output_file, FOPEN_WB);
2016
2017  if (!file)
2018    {
2019      fatal (_("unable to open output file %s"), output_file);
2020    }
2021
2022  if (debug)
2023    printf ("ids %d %d\n", base1, base2);
2024  tree = coff_grok (abfd);
2025  if (!noprescan)
2026    prescan (tree);
2027  wr_module (tree);
2028  return 0;
2029}
2030