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