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