OpenCores
URL https://opencores.org/ocsvn/open8_urisc/open8_urisc/trunk

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [binutils/] [srconv.c] - Blame information for rev 299

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.