* elfcomm.c (setup_archive): Extract index table and symbol table
[deliverable/binutils-gdb.git] / binutils / srconv.c
CommitLineData
252b5132 1/* srconv.c -- Sysroff conversion program
dc3c06c2 2 Copyright 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
91d6fa6a 3 2005, 2007, 2008, 2009 Free Software Foundation, Inc.
252b5132
RH
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
32866df7 9 the Free Software Foundation; either version 3 of the License, or
252b5132
RH
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
b43b5d5f
NC
19 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
20 02110-1301, USA. */
252b5132
RH
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
3db64b00 29#include "sysdep.h"
e9792343 30#include "bfd.h"
252b5132
RH
31#include "bucomm.h"
32#include "sysroff.h"
33#include "coffgrok.h"
e9792343 34#include "libiberty.h"
8b6efd89 35#include "filenames.h"
e9792343 36#include "getopt.h"
252b5132
RH
37
38#include "coff/internal.h"
39#include "../bfd/libcoff.h"
40
252b5132
RH
41/*#define FOOP1 1 */
42
43static int addrsize;
44static char *toolname;
45static char **rnames;
46
2da42df6
AJ
47static int get_member_id (int);
48static int get_ordinary_id (int);
49static char *section_translate (char *);
0e51e555 50static char *strip_suffix (const char *);
dc3c06c2
AM
51static void checksum (FILE *, unsigned char *, int, int);
52static void writeINT (int, unsigned char *, int *, int, FILE *);
53static void writeBITS (int, unsigned char *, int *, int);
54static void writeBARRAY (barray, unsigned char *, int *, int, FILE *);
55static void writeCHARS (char *, unsigned char *, int *, int, FILE *);
2da42df6
AJ
56static void wr_tr (void);
57static void wr_un (struct coff_ofile *, struct coff_sfile *, int, int);
58static void wr_hd (struct coff_ofile *);
59static void wr_sh (struct coff_ofile *, struct coff_section *);
60static void wr_ob (struct coff_ofile *, struct coff_section *);
61static void wr_rl (struct coff_ofile *, struct coff_section *);
62static void wr_object_body (struct coff_ofile *);
c32144ff 63static void wr_dps_start
2da42df6
AJ
64 (struct coff_sfile *, struct coff_section *, struct coff_scope *, int, int);
65static void wr_dps_end (struct coff_section *, struct coff_scope *, int);
66static int *nints (int);
c32144ff 67static void walk_tree_type_1
2da42df6 68 (struct coff_sfile *, struct coff_symbol *, struct coff_type *, int);
c32144ff 69static void walk_tree_type
2da42df6 70 (struct coff_sfile *, struct coff_symbol *, struct coff_type *, int);
c32144ff 71static void walk_tree_symbol
2da42df6 72 (struct coff_sfile *, struct coff_section *, struct coff_symbol *, int);
c32144ff 73static void walk_tree_scope
2da42df6
AJ
74 (struct coff_section *, struct coff_sfile *, struct coff_scope *, int, int);
75static void walk_tree_sfile (struct coff_section *, struct coff_sfile *);
76static void wr_program_structure (struct coff_ofile *, struct coff_sfile *);
77static void wr_du (struct coff_ofile *, struct coff_sfile *, int);
78static void wr_dus (struct coff_ofile *, struct coff_sfile *);
79static int find_base (struct coff_sfile *, struct coff_section *);
80static void wr_dln (struct coff_ofile *, struct coff_sfile *, int);
81static void wr_globals (struct coff_ofile *, struct coff_sfile *, int);
82static void wr_debug (struct coff_ofile *);
83static void wr_cs (void);
84static int wr_sc (struct coff_ofile *, struct coff_sfile *);
85static void wr_er (struct coff_ofile *, struct coff_sfile *, int);
86static void wr_ed (struct coff_ofile *, struct coff_sfile *, int);
87static void wr_unit_info (struct coff_ofile *);
88static void wr_module (struct coff_ofile *);
89static int align (int);
90static void prescan (struct coff_ofile *);
91static void show_usage (FILE *, int);
92extern int main (int, char **);
252b5132
RH
93
94static FILE *file;
95static bfd *abfd;
96static int debug = 0;
97static int quick = 0;
98static int noprescan = 0;
99static struct coff_ofile *tree;
9f66665a 100/* Obsolete ??
252b5132
RH
101 static int absolute_p;
102 */
103
104static int segmented_p;
105static int code;
106
107static int ids1[20000];
108static int ids2[20000];
109
110static int base1 = 0x18;
111static int base2 = 0x2018;
112
113static int
2da42df6 114get_member_id (int x)
252b5132
RH
115{
116 if (ids2[x])
8b53311e
NC
117 return ids2[x];
118
252b5132
RH
119 ids2[x] = base2++;
120 return ids2[x];
121}
122
123static int
2da42df6 124get_ordinary_id (int x)
252b5132
RH
125{
126 if (ids1[x])
8b53311e
NC
127 return ids1[x];
128
252b5132
RH
129 ids1[x] = base1++;
130 return ids1[x];
131}
132static char *
2da42df6 133section_translate (char *n)
252b5132
RH
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
252b5132
RH
144#define DATE "940201073000"; /* Just a time on my birthday */
145
0e51e555
NC
146static char *
147strip_suffix (const char *name)
252b5132
RH
148{
149 int i;
150 char *res;
8b53311e 151
252b5132
RH
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
252b5132
RH
160/* IT LEN stuff CS */
161static void
91d6fa6a 162checksum (FILE *ffile, unsigned char *ptr, int size, int ccode)
252b5132
RH
163{
164 int j;
165 int last;
166 int sum = 0;
167 int bytes = size / 8;
8b53311e 168
91d6fa6a 169 last = !(ccode & 0xff00);
252b5132
RH
170 if (size & 0x7)
171 abort ();
91d6fa6a 172 ptr[0] = ccode | (last ? 0x80 : 0);
252b5132
RH
173 ptr[1] = bytes + 1;
174
175 for (j = 0; j < bytes; j++)
8b53311e
NC
176 sum += ptr[j];
177
178 /* Glue on a checksum too. */
252b5132 179 ptr[bytes] = ~sum;
91d6fa6a 180 if (fwrite (ptr, bytes + 1, 1, ffile) != 1)
615f3149
AM
181 /* FIXME: Return error status. */
182 abort ();
252b5132
RH
183}
184
185
252b5132 186static void
91d6fa6a 187writeINT (int n, unsigned char *ptr, int *idx, int size, FILE *ffile)
252b5132
RH
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 {
8b53311e 198 /* Lets write out that record and do another one. */
91d6fa6a 199 checksum (ffile, ptr, *idx, code | 0x1000);
252b5132
RH
200 *idx = 16;
201 byte = *idx / 8;
202 }
8b53311e 203
252b5132
RH
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
252b5132 227static void
dc3c06c2 228writeBITS (int val, unsigned char *ptr, int *idx, int size)
252b5132
RH
229{
230 int byte = *idx / 8;
231 int bit = *idx % 8;
232 int old;
8b53311e 233
252b5132
RH
234 *idx += size;
235
236 old = ptr[byte];
8b53311e 237 /* Turn off all about to change bits. */
252b5132 238 old &= ~((~0 >> (8 - bit - size)) & ((1 << size) - 1));
8b53311e 239 /* Turn on the bits we want. */
252b5132
RH
240 old |= (val & ((1 << size) - 1)) << (8 - bit - size);
241 ptr[byte] = old;
242}
243
244static void
dc3c06c2 245writeBARRAY (barray data, unsigned char *ptr, int *idx,
91d6fa6a 246 int size ATTRIBUTE_UNUSED, FILE *ffile)
252b5132
RH
247{
248 int i;
8b53311e 249
91d6fa6a 250 writeINT (data.len, ptr, idx, 1, ffile);
252b5132 251 for (i = 0; i < data.len; i++)
91d6fa6a 252 writeINT (data.data[i], ptr, idx, 1, ffile);
252b5132
RH
253}
254
252b5132 255static void
91d6fa6a 256writeCHARS (char *string, unsigned char *ptr, int *idx, int size, FILE *ffile)
252b5132
RH
257{
258 int i = *idx / 8;
259
260 if (i > 240)
261 {
8b53311e 262 /* Lets write out that record and do another one. */
91d6fa6a 263 checksum (ffile, ptr, *idx, code | 0x1000);
252b5132
RH
264 *idx = 16;
265 i = *idx / 8;
266 }
267
268 if (size == 0)
269 {
8b53311e 270 /* Variable length string. */
252b5132
RH
271 size = strlen (string);
272 ptr[i++] = size;
273 }
274
8b53311e 275 /* BUG WAITING TO HAPPEN. */
252b5132
RH
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
252b5132
RH
284static char *rname_sh[] =
285{
286 "R0", "R1", "R2", "R3", "R4", "R5", "R6", "R7", "R8", "R9", "R10", "R11", "R12", "R13", "R14", "R15"
287};
288
289static char *rname_h8300[] =
290{
291 "ER0", "ER1", "ER2", "ER3", "ER4", "ER5", "ER6", "ER7", "PC", "CCR"
292};
293
294static void
2da42df6 295wr_tr (void)
252b5132 296{
8b53311e 297 /* The TR block is not normal - it doesn't have any contents. */
252b5132 298
8b53311e
NC
299 static char b[] =
300 {
301 0xff, /* IT */
302 0x03, /* RL */
303 0xfd, /* CS */
304 };
615f3149
AM
305
306 if (fwrite (b, sizeof (b), 1, file) != 1)
307 /* FIXME: Return error status. */
308 abort ();
252b5132
RH
309}
310
311static void
2da42df6
AJ
312wr_un (struct coff_ofile *ptr, struct coff_sfile *sfile, int first,
313 int nsecs ATTRIBUTE_UNUSED)
252b5132
RH
314{
315 struct IT_un un;
252b5132
RH
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
84e43642
BE
326 /* Don't count the abs section. */
327 un.nsections = ptr->nsections - 1;
252b5132
RH
328
329 un.nextdefs = 0;
330 un.nextrefs = 0;
8b53311e 331 /* Count all the undefined and defined variables with global scope. */
252b5132
RH
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
252b5132 353static void
2da42df6 354wr_hd (struct coff_ofile *p)
252b5132
RH
355{
356 struct IT_hd hd;
357
358 hd.spare1 = 0;
359 if (bfd_get_file_flags (abfd) & EXEC_P)
8b53311e 360 hd.mt = MTYPE_ABS_LM;
252b5132 361 else
8b53311e
NC
362 hd.mt = MTYPE_OMS_OR_LMS;
363
252b5132
RH
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 */
8b53311e 369
252b5132
RH
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
f904699a 419 if (! (bfd_get_file_flags(abfd) & EXEC_P))
252b5132
RH
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
440static void
2da42df6 441wr_sh (struct coff_ofile *p ATTRIBUTE_UNUSED, struct coff_section *sec)
252b5132
RH
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
453static void
2da42df6 454wr_ob (struct coff_ofile *p ATTRIBUTE_UNUSED, struct coff_section *section)
252b5132
RH
455{
456 bfd_size_type i;
457 int first = 1;
458 unsigned char stuff[200];
459
460 i = 0;
135dfb4a 461 while (i < bfd_get_section_size (section->bfd_section))
252b5132
RH
462 {
463 struct IT_ob ob;
8b53311e
NC
464 int todo = 200; /* Copy in 200 byte lumps. */
465
252b5132 466 ob.spare = 0;
135dfb4a
AM
467 if (i + todo > bfd_get_section_size (section->bfd_section))
468 todo = bfd_get_section_size (section->bfd_section) - i;
252b5132
RH
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
8b53311e 485 ob.cpf = 0; /* Never compress. */
252b5132
RH
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 }
8b53311e
NC
492
493 /* Now fill the rest with blanks. */
252b5132
RH
494 while (i < (bfd_size_type) section->size)
495 {
496 struct IT_ob ob;
8b53311e
NC
497 int todo = 200; /* Copy in 200 byte lumps. */
498
252b5132
RH
499 ob.spare = 0;
500 if (i + todo > (bfd_size_type) section->size)
501 todo = section->size - i;
502 ob.saf = 0;
503
8b53311e 504 ob.cpf = 0; /* Never compress. */
252b5132
RH
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 }
8b53311e 511 /* Now fill the rest with blanks. */
252b5132
RH
512}
513
514static void
2da42df6 515wr_rl (struct coff_ofile *ptr ATTRIBUTE_UNUSED, struct coff_section *sec)
252b5132
RH
516{
517 int nr = sec->nrelocs;
518 int i;
8b53311e 519
252b5132
RH
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;
8b53311e 525
252b5132
RH
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;
8b53311e
NC
533 rl.flen = 32; /* SH Specific. */
534
535 /* What sort of reloc ? Look in the section to find out. */
252b5132
RH
536 ref = r->symbol;
537 if (ref->visible->type == coff_vis_ext_ref)
538 {
8b53311e 539 rl.bcount = 4; /* Always 4 for us. */
252b5132
RH
540 rl.op = OP_EXT_REF;
541 rl.symn = ref->er_number;
542 }
543 else if (ref->visible->type == coff_vis_common)
544 {
8b53311e 545 rl.bcount = 11; /* Always 11 for us. */
252b5132
RH
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 }
252b5132
RH
553 else
554 {
8b53311e 555 rl.bcount = 11; /* Always 11 for us. */
252b5132
RH
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 }
8b53311e 563
252b5132 564 rl.end = 0xff;
8b53311e
NC
565
566 if ( rl.op == OP_SEC_REF
252b5132 567 || rl.op == OP_EXT_REF)
8b53311e 568 sysroff_swap_rl_out (file, &rl);
252b5132
RH
569 }
570}
571
572static void
2da42df6 573wr_object_body (struct coff_ofile *p)
252b5132
RH
574{
575 int i;
8b53311e 576
252b5132
RH
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
585static void
2da42df6
AJ
586wr_dps_start (struct coff_sfile *sfile,
587 struct coff_section *section ATTRIBUTE_UNUSED,
588 struct coff_scope *scope, int type, int nest)
252b5132
RH
589{
590 struct IT_dps dps;
8b53311e 591
252b5132
RH
592 dps.end = 0;
593 dps.opt = 0;
594 dps.type = type;
8b53311e 595
252b5132
RH
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;
8b53311e 601
252b5132
RH
602 if (debug)
603 {
604 printf ("DPS %s %d %x\n",
605 sfile->name,
606 nest,
607 dps.address);
252b5132
RH
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
622static void
2da42df6
AJ
623wr_dps_end (struct coff_section *section ATTRIBUTE_UNUSED,
624 struct coff_scope *scope ATTRIBUTE_UNUSED, int type)
252b5132
RH
625{
626 struct IT_dps dps;
8b53311e 627
252b5132
RH
628 dps.end = 1;
629 dps.type = type;
630 sysroff_swap_dps_out (file, &dps);
631}
632
633static int *
2da42df6 634nints (int x)
252b5132
RH
635{
636 return (int *) (xcalloc (sizeof (int), x));
637}
638
252b5132 639static void
2da42df6
AJ
640walk_tree_type_1 (struct coff_sfile *sfile, struct coff_symbol *symbol,
641 struct coff_type *type, int nest)
252b5132
RH
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;
8b53311e 658
252b5132
RH
659 case T_CHAR:
660 dbt.btype = BTYPE_CHAR;
661 dbt.sign = BTYPE_UNSPEC;
662 dbt.fptype = FPTYPE_NOTSPEC;
663 break;
8b53311e 664
252b5132
RH
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;
8b53311e 672
252b5132
RH
673 case T_FLOAT:
674 dbt.btype = BTYPE_FLOAT;
675 dbt.fptype = FPTYPE_SINGLE;
676 break;
8b53311e 677
252b5132
RH
678 case T_DOUBLE:
679 dbt.btype = BTYPE_FLOAT;
680 dbt.fptype = FPTYPE_DOUBLE;
681 break;
8b53311e 682
252b5132
RH
683 case T_LNGDBL:
684 dbt.btype = BTYPE_FLOAT;
685 dbt.fptype = FPTYPE_EXTENDED;
686 break;
8b53311e 687
252b5132
RH
688 case T_UCHAR:
689 dbt.btype = BTYPE_CHAR;
690 dbt.sign = SIGN_UNSIGNED;
691 dbt.fptype = FPTYPE_NOTSPEC;
692 break;
8b53311e 693
252b5132
RH
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 }
8b53311e 702
252b5132
RH
703 dbt.bitsize = type->size;
704 dbt.neg = 0x1001;
705 sysroff_swap_dbt_out (file, &dbt);
706 break;
707 }
8b53311e 708
252b5132
RH
709 case coff_pointer_type:
710 {
711 struct IT_dpt dpt;
8b53311e 712
1a0a850d 713 dpt.dunno = 0;
252b5132
RH
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;
8b53311e 724
252b5132
RH
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)
8b53311e
NC
737 walk_tree_symbol (sfile, 0, param, nest);
738
252b5132
RH
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;
8b53311e 749
252b5132
RH
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);
8b53311e 761
252b5132
RH
762 for (member = type->u.astructdef.elements->vars_head;
763 member;
764 member = member->next)
8b53311e 765 walk_tree_symbol (sfile, 0, member, nest + 1);
252b5132
RH
766
767 dds.end = 1;
768 sysroff_swap_dds_out (file, &dds);
769
770 }
771 break;
8b53311e 772
252b5132
RH
773 case coff_structref_type:
774 {
775 struct IT_dbt dbt;
8b53311e 776
252b5132
RH
777 dbt.btype = BTYPE_TAG;
778 dbt.bitsize = type->size;
779 dbt.sign = SIGN_UNSPEC;
780 dbt.fptype = FPTYPE_NOTSPEC;
8b53311e 781
252b5132 782 if (type->u.astructref.ref)
8b53311e 783 dbt.sid = get_member_id (type->u.astructref.ref->number);
252b5132 784 else
8b53311e 785 dbt.sid = 0;
252b5132
RH
786
787 dbt.neg = 0x1001;
788 sysroff_swap_dbt_out (file, &dbt);
789 }
790 break;
8b53311e 791
252b5132
RH
792 case coff_array_type:
793 {
794 struct IT_dar dar;
795 int j;
8b53311e
NC
796 int dims = 1; /* Only output one dimension at a time. */
797
252b5132
RH
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;
8b53311e 810
252b5132
RH
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;
8b53311e 825
252b5132
RH
826 case coff_enumdef_type:
827 {
828 struct IT_dbt dbt;
829 struct IT_den den;
830 struct coff_symbol *member;
8b53311e 831
252b5132
RH
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);
8b53311e 844
252b5132
RH
845 for (member = type->u.aenumdef.elements->vars_head;
846 member;
847 member = member->next)
8b53311e 848 walk_tree_symbol (sfile, 0, member, nest + 1);
252b5132
RH
849
850 den.end = 1;
851 sysroff_swap_den_out (file, &den);
852 }
853 break;
854
252b5132
RH
855 case coff_enumref_type:
856 {
857 struct IT_dbt dbt;
8b53311e 858
252b5132
RH
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;
8b53311e 868
252b5132
RH
869 default:
870 abort ();
871 }
872}
873
9f66665a 874/* Obsolete ?
252b5132
RH
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
912static void
2da42df6
AJ
913walk_tree_type (struct coff_sfile *sfile, struct coff_symbol *symbol,
914 struct coff_type *type, int nest)
252b5132
RH
915{
916 if (symbol->type->type == coff_function_type)
917 {
252b5132 918 struct IT_dty dty;
8b53311e 919
252b5132
RH
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);
252b5132
RH
945 }
946 else
947 {
948 struct IT_dty dty;
8b53311e 949
252b5132
RH
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 }
252b5132
RH
957}
958
252b5132 959static void
2da42df6 960walk_tree_symbol (struct coff_sfile *sfile, struct coff_section *section ATTRIBUTE_UNUSED, struct coff_symbol *symbol, int nest)
252b5132
RH
961{
962 struct IT_dsy dsy;
963
8b53311e 964 memset (&dsy, 0, sizeof(dsy));
252b5132
RH
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;
8b53311e 973
252b5132
RH
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;
8b53311e 982
252b5132
RH
983 case coff_enumdef_type:
984 dsy.type = STYPE_TAG;
985 dsy.assign = 0;
986 dsy.magic = 2;
987 break;
8b53311e 988
252b5132
RH
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;
8b53311e 994
252b5132
RH
995 case coff_secdef_type:
996 return;
8b53311e 997
252b5132
RH
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 }
8b53311e 1007
252b5132
RH
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
252b5132
RH
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;
8b53311e 1035
252b5132
RH
1036 case coff_vis_ext_ref:
1037 dsy.ainfo = AINFO_STATIC_EXT_REF;
1038 break;
8b53311e 1039
252b5132
RH
1040 case coff_vis_int_def:
1041 dsy.ainfo = AINFO_STATIC_INT;
1042 break;
8b53311e 1043
252b5132
RH
1044 case coff_vis_auto:
1045 case coff_vis_autoparam:
1046 dsy.ainfo = AINFO_AUTO;
1047 break;
8b53311e 1048
252b5132
RH
1049 case coff_vis_register:
1050 case coff_vis_regparam:
1051 dsy.ainfo = AINFO_REG;
1052 break;
1053 break;
8b53311e 1054
252b5132
RH
1055 case coff_vis_tag:
1056 case coff_vis_member_of_struct:
1057 case coff_vis_member_of_enum:
1058 break;
8b53311e 1059
252b5132
RH
1060 default:
1061 abort ();
1062 }
1063
1064 dsy.dlength = symbol->type->size;
8b53311e 1065
252b5132
RH
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;
8b53311e 1075
252b5132
RH
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:
252b5132
RH
1082 case coff_where_entag:
1083 case coff_where_typedef:
1084 break;
8b53311e 1085
252b5132
RH
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;
8b53311e 1095
252b5132
RH
1096 case coff_where_stack:
1097 dsy.address = symbol->where->offset;
1098 break;
252b5132 1099
8b53311e 1100 case coff_where_member_of_struct:
252b5132
RH
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;
8b53311e 1117
252b5132
RH
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;
8b53311e 1123
252b5132
RH
1124 case coff_where_register:
1125 case coff_where_unknown:
1126 case coff_where_strtag:
252b5132
RH
1127 case coff_where_entag:
1128 case coff_where_typedef:
1129 break;
8b53311e 1130
252b5132
RH
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:
8b53311e 1141 /* We do this 'cause common C symbols are treated as extdefs. */
252b5132
RH
1142 case coff_vis_ext_def:
1143 case coff_vis_ext_ref:
252b5132
RH
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:
252b5132
RH
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;
8b53311e 1159
252b5132
RH
1160 default:
1161 abort ();
1162 }
1163
1164 dsy.sfn = 0;
1165 dsy.sln = 2;
252b5132
RH
1166 dsy.neg = 0x1001;
1167
252b5132
RH
1168 sysroff_swap_dsy_out (file, &dsy);
1169
1170 walk_tree_type (sfile, symbol, symbol->type, nest);
1171}
1172
252b5132 1173static void
2da42df6 1174walk_tree_scope (struct coff_section *section, struct coff_sfile *sfile, struct coff_scope *scope, int nest, int type)
252b5132
RH
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)
8b53311e 1188 walk_tree_symbol (sfile, section, vars, nest);
252b5132
RH
1189
1190 for (child = scope->list_head; child; child = child->next)
8b53311e 1191 walk_tree_scope (section, sfile, child, nest + 1, BLOCK_TYPE_BLOCK);
252b5132
RH
1192
1193 wr_dps_end (section, scope, type);
1194 }
1195}
8b53311e 1196
252b5132 1197static void
2da42df6 1198walk_tree_sfile (struct coff_section *section, struct coff_sfile *sfile)
252b5132
RH
1199{
1200 walk_tree_scope (section, sfile, sfile->scope, 0, BLOCK_TYPE_COMPUNIT);
252b5132
RH
1201}
1202
1203static void
2da42df6 1204wr_program_structure (struct coff_ofile *p, struct coff_sfile *sfile)
252b5132 1205{
252b5132 1206 walk_tree_sfile (p->sections + 4, sfile);
252b5132
RH
1207}
1208
1209static void
2da42df6 1210wr_du (struct coff_ofile *p, struct coff_sfile *sfile, int n)
252b5132
RH
1211{
1212 struct IT_du du;
1213 int lim;
252b5132
RH
1214 int i;
1215 int j;
1216 unsigned int *lowest = (unsigned *) nints (p->nsections);
1217 unsigned int *highest = (unsigned *) nints (p->nsections);
8b53311e 1218
252b5132
RH
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
252b5132
RH
1235 lim = du.sections;
1236 for (j = 0; j < lim; j++)
1237 {
1238 int src = j;
1239 int dst = j;
8b53311e 1240
252b5132 1241 du.san[dst] = dst;
8b53311e 1242
252b5132
RH
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 }
8b53311e 1255
252b5132
RH
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 }
8b53311e 1266
252b5132
RH
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
1276static void
2da42df6 1277wr_dus (struct coff_ofile *p ATTRIBUTE_UNUSED, struct coff_sfile *sfile)
252b5132 1278{
252b5132
RH
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;
8b53311e 1287 /* Find the filenames. */
252b5132
RH
1288 dus.drb[0] = 0;
1289 dus.fname[0] = sfile->name;
252b5132
RH
1290
1291 sysroff_swap_dus_out (file, &dus);
1292
1293}
1294
1295/* Find the offset of the .text section for this sfile in the
8b53311e 1296 .text section for the output file. */
252b5132
RH
1297
1298static int
2da42df6 1299find_base (struct coff_sfile *sfile, struct coff_section *section)
252b5132
RH
1300{
1301 return sfile->section[section->number].low;
1302}
0f371bb4 1303
252b5132 1304static void
2da42df6
AJ
1305wr_dln (struct coff_ofile *p ATTRIBUTE_UNUSED, struct coff_sfile *sfile,
1306 int n ATTRIBUTE_UNUSED)
252b5132 1307{
252b5132
RH
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);
252b5132
RH
1374}
1375
8b53311e
NC
1376/* Write the global symbols out to the debug info. */
1377
252b5132 1378static void
2da42df6
AJ
1379wr_globals (struct coff_ofile *p, struct coff_sfile *sfile,
1380 int n ATTRIBUTE_UNUSED)
252b5132
RH
1381{
1382 struct coff_symbol *sy;
8b53311e 1383
252b5132
RH
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
8b53311e 1392 the current source file. */
252b5132
RH
1393 if (sy->sfile == sfile)
1394 walk_tree_symbol (sfile, 0, sy, 0);
252b5132
RH
1395 }
1396 }
1397}
1398
1399static void
2da42df6 1400wr_debug (struct coff_ofile *p)
252b5132
RH
1401{
1402 struct coff_sfile *sfile;
1403 int n = 0;
8b53311e 1404
252b5132
RH
1405 for (sfile = p->source_head;
1406 sfile;
1407 sfile = sfile->next)
252b5132
RH
1408 {
1409 if (debug)
8b53311e
NC
1410 printf ("%s\n", sfile->name);
1411
252b5132
RH
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
1420static void
2da42df6 1421wr_cs (void)
252b5132
RH
1422{
1423 /* It seems that the CS struct is not normal - the size is wrong
8b53311e
NC
1424 heres one I prepared earlier. */
1425 static char b[] =
1426 {
252b5132
RH
1427 0x80, /* IT */
1428 0x21, /* RL */
1429 0x00, /* number of chars in variable length part */
9f66665a
KH
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 */
252b5132
RH
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 };
615f3149
AM
1461
1462 if (fwrite (b, sizeof (b), 1, file) != 1)
1463 /* FIXME: Return error status. */
1464 abort ();
252b5132
RH
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
8b53311e 1469 if there isn't an equivalent one on the input. */
252b5132
RH
1470
1471static int
2da42df6 1472wr_sc (struct coff_ofile *ptr, struct coff_sfile *sfile)
252b5132
RH
1473{
1474 int i;
8b53311e
NC
1475 int scount = 0;
1476 /* First work out the total number of sections. */
252b5132 1477 int total_sec = ptr->nsections;
252b5132
RH
1478 struct myinfo
1479 {
1480 struct coff_section *sec;
1481 struct coff_symbol *symbol;
1482 };
1483 struct coff_symbol *symbol;
252b5132
RH
1484 struct myinfo *info
1485 = (struct myinfo *) calloc (total_sec, sizeof (struct myinfo));
1486
1487
252b5132
RH
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
8b53311e 1513 we don't have. */
252b5132
RH
1514 for (i = 1; i < total_sec; i++)
1515 {
1516 struct IT_sc sc;
1517 char *name;
8b53311e 1518
252b5132
RH
1519 symbol = info[i].symbol;
1520 sc.spare = 0;
1521 sc.spare1 = 0;
8b53311e 1522
252b5132
RH
1523 if (!symbol)
1524 {
8b53311e
NC
1525 /* Don't have a symbol set aside for this section, which means
1526 that nothing in this file does anything for the section. */
252b5132
RH
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;
252b5132
RH
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;
8b53311e 1557 sc.spare1 = 0; /* If not zero, then it doesn't work. */
252b5132 1558 sc.name = section_translate (name);
8b53311e 1559
252b5132
RH
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;
8b53311e 1568
252b5132
RH
1569 default:
1570 sc.contents = CONTENTS_CODE;
1571 }
1572 }
1573 else
1574 {
1575 sc.contents = CONTENTS_CODE;
1576 }
84e43642
BE
1577
1578 sysroff_swap_sc_out (file, &sc);
1579 scount++;
252b5132 1580 }
8b53311e 1581 return scount;
252b5132
RH
1582}
1583
8b53311e 1584/* Write out the ER records for a unit. */
252b5132 1585
252b5132 1586static void
2da42df6
AJ
1587wr_er (struct coff_ofile *ptr, struct coff_sfile *sfile ATTRIBUTE_UNUSED,
1588 int first)
252b5132
RH
1589{
1590 int idx = 0;
1591 struct coff_symbol *sym;
8b53311e 1592
252b5132
RH
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;
8b53311e 1600
252b5132
RH
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
8b53311e
NC
1611/* Write out the ED records for a unit. */
1612
252b5132 1613static void
2da42df6
AJ
1614wr_ed (struct coff_ofile *ptr, struct coff_sfile *sfile ATTRIBUTE_UNUSED,
1615 int first)
252b5132
RH
1616{
1617 struct coff_symbol *s;
8b53311e 1618
252b5132
RH
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;
8b53311e 1630
252b5132
RH
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 }
8b53311e 1644
252b5132
RH
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
1653static void
2da42df6 1654wr_unit_info (struct coff_ofile *ptr)
252b5132
RH
1655{
1656 struct coff_sfile *sfile;
1657 int first = 1;
8b53311e 1658
252b5132
RH
1659 for (sfile = ptr->source_head;
1660 sfile;
1661 sfile = sfile->next)
1662 {
1663 long p1;
1664 long p2;
1665 int nsecs;
8b53311e 1666
252b5132
RH
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);
9f66665a 1673 fseek (file, p2, SEEK_SET);
252b5132
RH
1674 wr_er (ptr, sfile, first);
1675 wr_ed (ptr, sfile, first);
1676 first = 0;
1677 }
1678}
1679
1680static void
2da42df6 1681wr_module (struct coff_ofile *p)
252b5132
RH
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
1691static int
2da42df6 1692align (int x)
252b5132
RH
1693{
1694 return (x + 3) & ~3;
1695}
1696
1697/* Find all the common variables and turn them into
8b53311e 1698 ordinary defs - dunno why, but thats what hitachi does with 'em. */
252b5132
RH
1699
1700static void
91d6fa6a 1701prescan (struct coff_ofile *otree)
252b5132
RH
1702{
1703 struct coff_symbol *s;
1704 struct coff_section *common_section;
8b53311e
NC
1705
1706 /* Find the common section - always section 3. */
91d6fa6a 1707 common_section = otree->sections + 3;
8b53311e 1708
91d6fa6a 1709 for (s = otree->symbol_list_head;
252b5132
RH
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;
91d6fa6a 1716
252b5132
RH
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
1727char *program_name;
1728
1729static void
91d6fa6a 1730show_usage (FILE *ffile, int status)
252b5132 1731{
91d6fa6a
NC
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\
d412a550 1735 -q --quick (Obsolete - ignored)\n\
8b53311e
NC
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\
07012eee 1738 @<file> Read options from <file>\n\
8b53311e
NC
1739 -h --help Display this information\n\
1740 -v --version Print the program's version number\n"));
1741
92f01d61 1742 if (REPORT_BUGS_TO[0] && status == 0)
91d6fa6a 1743 fprintf (ffile, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132
RH
1744 exit (status);
1745}
1746
252b5132 1747int
2da42df6 1748main (int ac, char **av)
252b5132
RH
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, "");
3882b010
L
1766#endif
1767#if defined (HAVE_SETLOCALE)
1768 setlocale (LC_CTYPE, "");
252b5132
RH
1769#endif
1770 bindtextdomain (PACKAGE, LOCALEDIR);
1771 textdomain (PACKAGE);
1772
1773 program_name = av[0];
1774 xmalloc_set_program_name (program_name);
1775
869b9d07
MM
1776 expandargv (&ac, &av);
1777
8b53311e 1778 while ((opt = getopt_long (ac, av, "dHhVvqn", long_options,
252b5132
RH
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;
8b53311e 1793 case 'H':
252b5132 1794 case 'h':
8b53311e 1795 show_usage (stdout, 0);
252b5132 1796 /*NOTREACHED */
8b53311e 1797 case 'v':
252b5132 1798 case 'V':
6a8c2b0d 1799 print_version ("srconv");
252b5132
RH
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);
8b6efd89 1822 if (filename_cmp (input_file, output_file) == 0)
252b5132 1823 {
37cc8ec1 1824 fatal (_("input and output files must be different"));
252b5132
RH
1825 }
1826 }
1827 }
1828 else
1829 input_file = 0;
1830
1831 if (!input_file)
1832 {
37cc8ec1 1833 fatal (_("no input file specified"));
252b5132
RH
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);
8b53311e 1842
252b5132
RH
1843 output_file = xmalloc (len + 5);
1844 strcpy (output_file, input_file);
8b53311e 1845
252b5132
RH
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);
8b53311e 1868
252b5132
RH
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)
8b53311e 1880 fatal (_("unable to open output file %s"), output_file);
252b5132
RH
1881
1882 if (debug)
1883 printf ("ids %d %d\n", base1, base2);
8b53311e 1884
252b5132 1885 tree = coff_grok (abfd);
8b53311e 1886
252b5132
RH
1887 if (!noprescan)
1888 prescan (tree);
8b53311e 1889
252b5132
RH
1890 wr_module (tree);
1891 return 0;
1892}
This page took 0.548085 seconds and 4 git commands to generate.