* srconv.c (wr_hd): Space size within segment was being
[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 "bucomm.h"
29 #include "sysroff.h"
30 #include "coffgrok.h"
31 #include <libiberty.h>
32 #include <getopt.h>
33
34 #include "coff/internal.h"
35 #include "../bfd/libcoff.h"
36
37 #define PROGRAM_VERSION "1.5"
38 /*#define FOOP1 1 */
39
40 static int sh;
41 static int h8300;
42 static void wr_cs ();
43 static void walk_tree_scope ();
44 static void wr_globals ();
45 static int find_base ();
46
47 static FILE *file;
48 static bfd *abfd;
49 static int debug = 0;
50 static int quick = 0;
51 static int noprescan = 0;
52 static struct coff_ofile *tree;
53 /* Obsolete ??
54 static int absolute_p;
55 */
56
57 static int segmented_p;
58 static int code;
59
60 static int ids1[20000];
61 static int ids2[20000];
62
63 static int base1 = 0x18;
64 static int base2 = 0x2018;
65
66 char *
67 xcalloc (a, b)
68 int a;
69 int b;
70 {
71 char *r = xmalloc (a * b);
72 memset (r, 0, a * b);
73 return r;
74 }
75
76 static int
77 get_member_id (x)
78 int x;
79 {
80 if (ids2[x])
81 {
82 return ids2[x];
83 }
84 ids2[x] = base2++;
85 return ids2[x];
86 }
87
88 static int
89 get_ordinary_id (x)
90 int x;
91 {
92 if (ids1[x])
93 {
94 return ids1[x];
95 }
96 ids1[x] = base1++;
97 return ids1[x];
98 }
99 static char *
100 section_translate (n)
101 char *n;
102 {
103 if (strcmp (n, ".text") == 0)
104 return "P";
105 if (strcmp (n, ".data") == 0)
106 return "D";
107 if (strcmp (n, ".bss") == 0)
108 return "B";
109 return n;
110 }
111
112
113
114 #define DATE "940201073000"; /* Just a time on my birthday */
115
116
117 static
118 char *
119 strip_suffix (name)
120 char *name;
121 {
122 int i;
123 char *res;
124 for (i = 0; name[i] != 0 && name[i] != '.'; i++)
125 ;
126 res = (char *) xmalloc (i + 1);
127 memcpy (res, name, i);
128 res[i] = 0;
129 return res;
130 }
131
132
133 /* IT LEN stuff CS */
134 static void
135 checksum (file, ptr, size, code)
136 FILE *file;
137 char *ptr;
138 int size;
139 int code;
140 {
141 int j;
142 int last;
143 int sum = 0;
144 int bytes = size / 8;
145 last = !(code & 0xff00);
146 if (size & 0x7)
147 abort ();
148 ptr[0] = code | (last ? 0x80 : 0);
149 ptr[1] = bytes + 1;
150
151 for (j = 0; j < bytes; j++)
152 {
153 sum += ptr[j];
154 }
155 /* Glue on a checksum too */
156 ptr[bytes] = ~sum;
157 fwrite (ptr, bytes + 1, 1, file);
158 }
159
160
161
162
163 static void
164 writeINT (n, ptr, idx, size, file)
165 int n;
166 char *ptr;
167 int *idx;
168 int size;
169 FILE *file;
170 {
171 int byte = *idx / 8;
172
173 if (size == -2)
174 {
175 if (sh)
176 size = 4;
177 else if (h8300)
178 size = 2;
179 }
180 else if (size == -1)
181 size = 0;
182
183 if (byte > 240)
184 {
185 /* Lets write out that record and do another one */
186 checksum (file, ptr, *idx, code | 0x1000);
187 *idx = 16;
188 byte = *idx / 8;
189 }
190 switch (size)
191 {
192 case 0:
193 break;
194 case 1:
195 ptr[byte] = n;
196 break;
197 case 2:
198 ptr[byte + 0] = n >> 8;
199 ptr[byte + 1] = n;
200 break;
201 case 4:
202 ptr[byte + 0] = n >> 24;
203 ptr[byte + 1] = n >> 16;
204 ptr[byte + 2] = n >> 8;
205 ptr[byte + 3] = n >> 0;
206 break;
207 default:
208 abort ();
209 }
210 *idx += size * 8;
211 }
212
213
214 static void
215 writeBITS (val, ptr, idx, size)
216 int val;
217 char *ptr;
218 int *idx;
219 int size;
220 {
221 int byte = *idx / 8;
222 int bit = *idx % 8;
223 int old;
224 *idx += size;
225
226 old = ptr[byte];
227 /* Turn off all about to change bits */
228 old &= ~((~0 >> (8 - bit - size)) & ((1 << size) - 1));
229 /* Turn on the bits we want */
230 old |= (val & ((1 << size) - 1)) << (8 - bit - size);
231 ptr[byte] = old;
232 }
233
234 static void
235 writeBARRAY (data, ptr, idx, size, file)
236 barray data;
237 char *ptr;
238 int *idx;
239 int size;
240 FILE *file;
241 {
242 int i;
243 writeINT (data.len, ptr, idx, 1, file);
244 for (i = 0; i < data.len; i++)
245 {
246 writeINT (data.data[i], ptr, idx, 1, file);
247 }
248 }
249
250
251 static void
252 writeCHARS (string, ptr, idx, size, file)
253 char *string;
254 char *ptr;
255 int *idx;
256 int size;
257 FILE *file;
258 {
259 int i = *idx / 8;
260
261 if (i > 240)
262 {
263 /* Lets write out that record and do another one */
264 checksum (file, ptr, *idx, code | 0x1000);
265 *idx = 16;
266 i = *idx / 8;
267 }
268
269 if (size == 0)
270 {
271 /* Variable length string */
272 size = strlen (string);
273 ptr[i++] = size;
274 }
275
276 /* BUG WAITING TO HAPPEN */
277 memcpy (ptr + i, string, size);
278 i += size;
279 *idx = i * 8;
280 }
281
282 #define SYSROFF_SWAP_OUT
283 #include "sysroff.c"
284
285
286 static char *rname_sh[] =
287 {
288 "R0", "R1", "R2", "R3", "R4", "R5", "R6", "R7", "R8", "R9", "R10", "R11", "R12", "R13", "R14", "R15"
289 };
290
291 static char *rname_h8300[] =
292 {
293 "ER0", "ER1", "ER2", "ER3", "ER4", "ER5", "ER6", "ER7", "PC", "CCR"
294 };
295
296 static void
297 wr_tr ()
298 {
299 /* The TR block is not normal - it doesn't have any contents. */
300
301 static char b[] = {
302 0xff, /* IT */
303 0x03, /* RL */
304 0xfd, /* CS */
305 };
306 fwrite (b, 1, sizeof (b), file);
307 }
308
309 static void
310 wr_un (ptr, sfile, first, nsecs)
311 struct coff_ofile *ptr;
312 struct coff_sfile *sfile;
313 int first;
314 int nsecs;
315 {
316 struct IT_un un;
317
318 struct coff_symbol *s;
319
320 un.spare1 = 0;
321
322 if (abfd->flags & EXEC_P)
323 un.format = FORMAT_LM;
324 else
325 un.format = FORMAT_OM;
326 un.spare1 = 0;
327
328
329 #if 0
330 un.nsections = ptr->nsections - 1; /* Don't count the abs section */
331 #else
332 /*NEW - only count sections with size */
333 un.nsections = nsecs;
334 #endif
335
336 un.nextdefs = 0;
337 un.nextrefs = 0;
338 /* Count all the undefined and defined variables with global scope */
339
340 if (first)
341 {
342 for (s = ptr->symbol_list_head; s; s = s->next_in_ofile_list)
343 {
344 if (s->visible->type == coff_vis_ext_def
345 || s->visible->type == coff_vis_common)
346 un.nextdefs++;
347
348 if (s->visible->type == coff_vis_ext_ref)
349 un.nextrefs++;
350 }
351 }
352 if (sh)
353 un.tool = "C_SH";
354 else if (h8300)
355 un.tool = "C_H8/300H";
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 = 0;
389 hd.afl = 2;
390 hd.spcsz = 32;
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 = 0;
399 hd.afl = 4;
400 hd.spcsz = 32;
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 else 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.075327 seconds and 5 git commands to generate.