~ubuntu-branches/ubuntu/utopic/binutils-arm64-cross/utopic

« back to all changes in this revision

Viewing changes to binutils-2.23.52.20130611/binutils/srconv.c

  • Committer: Package Import Robot
  • Author(s): Matthias Klose
  • Date: 2013-06-20 17:38:09 UTC
  • Revision ID: package-import@ubuntu.com-20130620173809-app8lzgvymy5fg6c
Tags: 0.7
Build-depend on binutils-source (>= 2.23.52.20130620-1~).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* 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
}