81c2a534e98f4539de0d7c173d2fb93c7109dbb7
[binutils-gdb.git] / bfd / coff-mips.c
1 /* MIPS Extended-Coff handler for Binary File Diddling.
2 Written by Per Bothner.
3
4 FIXME, Needs Copyleft here. */
5
6 /* This does not compile on anything but a MIPS yet (and I haven't been
7 able to test it there either since the latest merge!). So it stays
8 out by default. */
9 #ifdef ECOFF_BFD
10
11 #define MIPS 1
12 #include "libbfd.h"
13 #include "sysdep.h"
14 #include "libcoff.h" /* to allow easier abstraction-breaking */
15
16 #include "intel-coff.h"
17
18
19
20
21 static reloc_howto_type howto_table[] =
22 {
23 {0},
24 {1},
25 {2},
26 {3},
27 {4},
28 {5},
29 {6},
30 {7},
31 {8},
32 {9},
33 {10},
34 {11},
35 {12},
36 {13},
37 {14},
38 {15},
39 {16},
40 { R_RELLONG, 0, 2, 32, 0, 0, true, true},
41 {18},
42 {19},
43 {20},
44 {21},
45 {22},
46 {23},
47 {24},
48 { R_IPRMED, 2, 2,22,1,0, true, true},
49 {26},
50 /* What do we do with this - ? */
51 #if 1
52 { R_OPTCALL, 0,2,32,0,0, true, true},
53 #else
54 { R_OPTCALL, 0,3,32,0,0, true, true},
55 #endif
56 };
57
58
59 #define ALIGN(this, boundary) \
60 ((( (this) + ((boundary) -1)) & (~((boundary)-1))))
61
62
63 /* Support for Motorola 88k bcs coff as well as Intel 960 coff */
64
65
66 #include <stdio.h>
67 #include <string.h>
68
69
70 /* Align an address by rounding it up to a power of two. It leaves the
71 address unchanged if align == 0 (2^0 = alignment of 1 byte) */
72 #define i960_align(addr, align) \
73 ( ((addr) + ((1<<(align))-1)) & (-1 << (align)))
74
75 #define TAG_SECTION_NAME ".tagbits"
76
77 /* Libraries shouldn't be doing this stuff anyway! */
78 void fatal();
79 /* void warning(); */
80 \f
81
82 /* initialize a section structure with information
83 * peculiar to this particular implementation of coff
84 */
85
86 static void
87 ecoff_new_section_hook(abfd, section)
88 bfd *abfd;
89 asection *section;
90 {
91
92 section->output_file_alignment = DEFAULT_SECTION_ALIGNMENT;
93 section->subsection_alignment = section->output_file_alignment;
94 if (abfd->flags & D_PAGED)
95 {
96 /**
97 If the output object file is demand paged then the
98 text section starts at the filehdr, with the first
99 usefull bit of data at the end of the filehdr+opthdr+
100 scnhdrs. Since we don't know how many sections will
101 be put into the output file, we have to recalculate
102 the section pads after each additional section has
103 been created
104 **/
105 asection *ptr = abfd->sections;
106 unsigned int padding = FILHSZ + AOUTSZ +SCNHSZ * abfd->section_count;
107
108 padding = ALIGN(padding, ptr->output_file_alignment);
109 while (ptr)
110 {
111 ptr->start_pad = padding;
112 /* Only the first section is padded */
113 padding = 0;
114 ptr = ptr->next;
115 }
116 }
117 else
118 {
119
120 /* If the object is not demand paged, then all the sections
121 have no padding
122 */
123 section->start_pad = 0;
124 }
125
126
127
128 }
129 /* actually it makes itself and its children from the file headers */
130 static boolean
131 make_a_section_from_file (abfd, hdr)
132 bfd *abfd;
133 struct scnhdr *hdr;
134
135 {
136 asection *return_section ;
137
138 { char *name = (char *)xmalloc(9);
139
140 strncpy(name, (char *)&hdr->s_name[0], 8);
141
142 return_section = bfd_make_section(abfd, name);
143 (return_section->name)[8] = 0;
144 }
145
146 /* s_paddr is presumed to be = to s_vaddr */
147 /* FIXME -- needs to call swapping routines */
148 #define assign(to, from) return_section->to = hdr->from
149 assign (vma, s_vaddr);
150 assign (original_vma, s_vaddr);
151 assign (size, s_size);
152 assign (filepos, s_scnptr);
153 assign (rel_filepos, s_relptr);
154 assign (reloc_count, s_nreloc);
155 #ifdef I960
156 assign (alignment, s_align);
157 #endif
158 assign (line_filepos, s_lnnoptr);
159 /* return_section->linesize = hdr->s_nlnno * sizeof (struct lineno);*/
160
161 #undef assign
162 return_section->lineno_count = hdr->s_nlnno;
163 return_section->userdata = (void *)NULL;
164 return_section->next = (asection *)NULL;
165 if ((hdr->s_flags & STYP_TEXT) || (hdr->s_flags & STYP_DATA))
166 return_section->flags = (SEC_LOAD | SEC_ALLOC);
167 else if (hdr->s_flags & STYP_BSS)
168 return_section->flags = SEC_ALLOC;
169
170 if (hdr->s_nreloc != 0) return_section->flags |= SEC_RELOC;
171
172 return true;
173 }
174
175 bfd_target *
176 ecoff_real_object_p (abfd, nscns, opthdr)
177 bfd *abfd;
178 unsigned short nscns, opthdr;
179 {
180 struct icofdata *tdata;
181 char *file_info; /* buffer for all the headers */
182 long readsize; /* length of file_info */
183 struct filehdr* filehdr; /* points into file_info */
184 struct scnhdr *sections; /* points into file_info */
185
186 /* OK, now we know the format, read in the filehdr, soi-disant
187 "optional header", and all the sections.*/
188 readsize = sizeof(struct filehdr) + opthdr + (nscns * sizeof (struct scnhdr));
189 file_info = xmalloc (readsize);
190 if (file_info == NULL) {
191 bfd_error = no_memory;
192 return 0;
193 }
194 if (bfd_seek (abfd, 0, false) < 0) return 0;
195 if (bfd_read (file_info, 1, readsize, abfd) != readsize) return 0;
196 filehdr = (struct filehdr *) file_info;
197 sections = (struct scnhdr *) (file_info + sizeof (struct filehdr) + opthdr);
198
199 /* Now copy data as required; construct all asections etc */
200 tdata = (struct icofdata *) xmalloc (sizeof (struct icofdata) +
201 sizeof (AOUTHDR));
202 if (tdata == NULL) {
203 bfd_error = no_memory;
204 return 0;
205 }
206
207 if (nscns != 0)
208 {
209 unsigned int i;
210 for (i = 0; i < nscns; i++)
211 {
212 make_a_section_from_file (abfd, sections + i);
213 }
214 }
215
216 #ifdef I960
217 /* OK, now make a section for the tagbits if there were any */
218 #if 0
219 {
220 AOUTHDR *aouthdr; /* points into tdata! */
221 aouthdr = (AOUTHDR *) (((char *) tdata) + sizeof (struct icofdata));
222 if (aouthdr->tagentries != 0) {
223 asection *tag_section = (asection *) xmalloc (sizeof (asection));
224 if (tag_section == NULL) {
225 free (tdata);
226 return 0;
227 }
228 tag_section->size = aouthdr->tagentries * sizeof (TAGBITS);
229 tag_section->name = TAG_SECTION_NAME;
230 tag_section->filepos = readsize; /* not surprisingly */
231 /* Put this one first */
232 tag_section->next = abfd->sections;
233 abfd->sections = tag_section;
234 }
235 }
236 #endif
237 #endif
238 abfd->flags |= HAS_RELOC | HAS_LINENO | HAS_LOCALS;
239
240
241 /* FIXME, the guess should be set by OR-ing info from the sections */
242 if ((filehdr->f_flags & F_RELFLG) != F_RELFLG) abfd->flags &= ~HAS_RELOC;
243 if ((filehdr->f_flags & F_EXEC) == F_EXEC) abfd->flags |= EXEC_P;
244 if ((filehdr->f_flags & F_LNNO) != F_LNNO) abfd->flags &= ~HAS_LINENO;
245 if ((filehdr->f_flags & F_LSYMS) != F_LSYMS) abfd->flags &= ~HAS_LOCALS;
246 abfd->tdata = tdata;
247 bfd_get_symcount (abfd) = filehdr->f_nsyms;
248 if (filehdr->f_nsyms) abfd->flags |= HAS_SYMS;
249
250 tdata->sym_filepos = filehdr->f_symptr;
251 tdata->hdr = (struct aouthdr *)(file_info + sizeof (struct filehdr));
252 tdata->symbols = (esymbol *)NULL;
253 bfd_get_start_address (abfd) = exec_hdr (abfd)->entry;
254 return abfd->xvec;
255 }
256
257 bfd_target *
258 ecoff_object_p (abfd)
259 bfd *abfd;
260 {
261 unsigned short magic, nscns, opthdr;
262
263 bfd_error = no_error;
264
265 /* figure out how much to read */
266 if (bfd_read (&magic, 1, sizeof (magic), abfd) != sizeof (magic))
267 return 0;
268
269 magic = bfd_h_getshort (abfd, (unsigned char *)&magic);
270 if (magic != (abfd->xvec->byteorder_big_p ? 0x160 : 0x162)) {
271 bfd_error = wrong_format;
272 return 0;
273 }
274 if (bfd_read (&nscns, 1, sizeof (nscns), abfd) != sizeof (nscns))
275 return 0;
276 nscns = bfd_h_getshort (abfd, (unsigned char *)&nscns);
277
278 if (bfd_seek (abfd, ((sizeof (long)) * 3), true) < 0) return false;
279 if (bfd_read (&opthdr, 1, sizeof (opthdr), abfd) != sizeof (opthdr))
280 return 0;
281 opthdr = bfd_h_getshort (abfd, (unsigned char *)&opthdr);
282
283 return ecoff_real_object_p (abfd, nscns, opthdr);
284 }
285
286 static boolean
287 ecoff_mkobject (abfd)
288 bfd *abfd;
289 {
290 char *rawptr;
291
292
293 bfd_error = no_error;
294
295 /* Use an intermediate variable for clarity */
296 rawptr = xmalloc (sizeof (struct icofdata) + sizeof (AOUTHDR));
297 if (rawptr == NULL) {
298 bfd_error = no_memory;
299 return false;
300 }
301
302 abfd->tdata = (struct icofdata *) rawptr;
303 exec_hdr (abfd) = (AOUTHDR *) (rawptr + sizeof (struct icofdata));
304
305 return true;
306 }
307 \f
308 static void
309 ecoff_count_linenumbers(abfd)
310 bfd *abfd;
311 {
312 unsigned int limit = bfd_get_symcount(abfd);
313 unsigned int i = 0;
314 esymbol **p = (esymbol **)(abfd->outsymbols);
315 {
316 asection *s = abfd->sections;
317 while (s) {
318 if (s->lineno_count != 0) {
319 fatal("Bad initial state");
320 }
321 s = s->next;
322 }
323 }
324
325 while (i < limit)
326 {
327 esymbol *q = *p;
328 if (q->c.lineno)
329 {
330 /* This symbol has a linenumber, increment the
331 * owning section's linenumber count */
332 alent *l = q->c.lineno;
333 q->c.section->lineno_count++;
334 l++;
335 while (l->line_number) {
336 q->c.section->lineno_count++;
337 l++;
338 }
339 }
340 p++;
341 i++;
342 }
343 }
344
345 /*
346 run through the internal symbol table and make all the
347 pointers and things within the table point to the right places
348 */
349
350 static void
351 ecoff_mangle_symbols(abfd)
352 bfd *abfd;
353 {
354 esymbol **p = (esymbol **)(abfd->outsymbols);
355 unsigned int native_index = 0;
356 unsigned int last_file_index = 0;
357 unsigned int limit = bfd_get_symcount(abfd);
358 struct syment *last_file_symbol = (struct syment *)NULL;
359 while (limit--) {
360 esymbol *q = *p;
361 struct syment *native = q->native;
362 if(native) {
363 /* Alter the native representation */
364
365 native->n_value = q->c.value;
366 if (q->c.flags & BSF_FORT_COMM) {
367 native->n_scnum = 0;
368 }
369 else if (q->c.flags & BSF_DEBUGGING) {
370 native->n_scnum = -2;
371 }
372 else if (q->c.flags & BSF_UNDEFINED) {
373 native->n_scnum = 0;
374 }
375 else if (q->c.flags & BSF_ABSOLUTE) {
376 native->n_scnum = -1;
377 }
378 else {
379 native->n_scnum = q->c.section->index + 1;
380 }
381 if (native->n_numaux)
382 {
383 union auxent *a = (union auxent *)(native+1);
384 /* Relocate symbol indexes */
385 if (ISFCN(native->n_type))
386 {
387 a->x_sym.x_fcnary.x_fcn.x_endndx += last_file_index;
388 }
389 else if(native->n_sclass == C_BLOCK && q->c.name[1] == 'b')
390 {
391 a->x_sym.x_fcnary.x_fcn.x_endndx += last_file_index;
392 }
393
394 else if (native->n_sclass == C_STRTAG)
395 {
396 a->x_sym.x_fcnary.x_fcn.x_endndx += last_file_index;
397 }
398 else if (native->n_sclass == C_MOS || native->n_sclass == C_EOS || native->n_sclass == C_MOE)
399 {
400 a->x_sym.x_tagndx += last_file_index;
401 }
402 }
403
404
405 switch (native->n_sclass) {
406 case C_MOS:
407 case C_EOS:
408 case C_REGPARM:
409 case C_REG:
410 case 19: /*C_REGARG:FIXME */
411 /* Fix so that they have an absolute section */
412 native->n_scnum= -1;
413 break;
414
415 case C_FILE:
416 /* Chain all the .file symbols together */
417 if(last_file_symbol) {
418 last_file_symbol->n_value = native_index;
419 }
420 last_file_symbol = native;
421 last_file_index = native_index;
422 break;
423 case C_NULL:
424 case C_AUTO:
425 case C_EXT:
426 case C_EXTDEF:
427 case C_LABEL:
428 case C_ULABEL:
429 case C_USTATIC:
430 case C_STRTAG:
431 case C_FCN:
432 case C_BLOCK:
433 case C_STAT:
434 case C_LEAFPROC:
435 break;
436 default:
437 /* Bogus: This should be returning an error code, not printing
438 something out! */
439 /* warning("Unrecognised sclass %d", native->n_sclass); */
440 break;
441 }
442 native_index += 1 + native->n_numaux;
443 }
444 else {
445 native_index++;
446 }
447 p++;
448 }
449 }
450 static void
451 ecoff_write_symbols(abfd)
452 bfd *abfd;
453 {
454 }
455
456
457 void
458 ecoff_write_linenumbers(abfd)
459 bfd *abfd;
460 {
461 }
462
463
464 asymbol *
465 ecoff_make_empty_symbol(abfd, n)
466 bfd *abfd;
467 unsigned int n;
468 {
469 unsigned int j;
470 esymbol *new = (esymbol *)xmalloc(sizeof(esymbol) * n);
471 for (j= 0; j < n; j++) {
472 new[j].native = 0;
473 new[j].c.lineno = (alent *)NULL;
474 }
475 return (asymbol *)new;
476 }
477
478 /*SUPPRESS 558*/
479 /*SUPPRESS 529*/
480 boolean
481 ecoff_write_object_contents (abfd)
482 bfd *abfd;
483 {
484 return false;
485 }
486 \f
487 /* Calculate the file position for each section. */
488
489 static void
490 ecoff_compute_section_file_positions (abfd)
491 bfd *abfd;
492 {
493 file_ptr sofar = sizeof (struct filehdr) + sizeof (AOUTHDR);
494 asection *current;
495
496 sofar += abfd->section_count * sizeof (struct scnhdr);
497 for (current = abfd->sections; current != NULL; current = current->next) {
498 sofar = ALIGN(sofar, current->output_file_alignment);
499 current->filepos = sofar;
500 /* Only add sections which are loadable */
501 if (current->flags & SEC_LOAD) sofar += current->size;
502 #if 0
503 if(current->filepos & (current->alignment-1)) {
504 sofar += current->alignment - (current->filepos &(current->alignment-1));
505 current->filepos = (current->filepos + current->alignment) & -current->alignment;
506 }
507 #endif
508 }
509 obj_relocbase (abfd) = sofar;
510 }
511
512 boolean
513 ecoff_set_section_contents (abfd, section, location, offset, count)
514 bfd *abfd;
515 sec_ptr section;
516 unsigned char *location;
517 file_ptr offset;
518 int count;
519 {
520 return false;
521 }
522
523 boolean
524 ecoff_set_section_linenos (abfd, section, location, offset, count)
525 bfd *abfd;
526 sec_ptr section;
527 unsigned char *location;
528 file_ptr offset;
529 int count;
530 {
531 return 0;
532 }
533 \f
534
535 boolean
536 ecoff_close_and_cleanup (abfd)
537 bfd *abfd;
538 {
539 return false;
540 }
541 \f
542
543
544
545
546 static void *
547 buy_and_read(abfd, where, relative, size)
548 bfd *abfd;
549 int where;
550 boolean relative;
551 unsigned int size;
552 {
553 void *area = (void *)xmalloc(size);
554 if (!area) {
555 bfd_error = no_memory;
556 return 0;
557 }
558 bfd_seek(abfd, where, relative);
559 if (bfd_read(area, 1, size, abfd) != size){
560 bfd_error = system_call_error;
561 free(area);
562 return 0;
563 }
564 return area;
565 }
566
567 static
568 struct sec *section_from_bfd_index(abfd, index)
569 bfd *abfd;
570 int index;
571 {
572 if (index > 0) {
573 struct sec *answer = abfd->sections;
574
575 while (--index) {
576 answer = answer->next;
577 }
578 return answer;
579 }
580 return 0;
581 }
582
583 static int
584 ecoff_get_symcount_upper_bound (abfd)
585 bfd *abfd;
586 {
587 fatal("call to ecoff_get_symcount_upper_bound");
588 return 0;
589 }
590
591 static symindex
592 ecoff_get_first_symbol (abfd)
593 bfd * abfd;
594 {
595 return 0;
596 }
597
598 static symindex
599 ecoff_get_next_symbol (abfd, oidx)
600 bfd *abfd;
601 symindex oidx;
602 {
603 if (oidx == BFD_NO_MORE_SYMBOLS) return BFD_NO_MORE_SYMBOLS;
604 return ++oidx >= bfd_get_symcount (abfd) ? BFD_NO_MORE_SYMBOLS : oidx;
605 }
606
607 static char *
608 ecoff_symbol_name (abfd, idx)
609 bfd *abfd;
610 symindex idx;
611 {
612 return (obj_symbols (abfd) + idx)->c.name;
613 }
614
615 static long
616 ecoff_symbol_value (abfd, idx)
617 bfd *abfd;
618 symindex idx;
619 {
620 return (obj_symbols (abfd) + idx)->c.value;
621 }
622
623 static symclass
624 ecoff_classify_symbol (abfd, idx)
625 bfd *abfd;
626 symindex idx;
627 {
628 esymbol *sym = obj_symbols (abfd) + idx;
629
630 if ((sym->c.flags & BSF_FORT_COMM) != 0) return bfd_symclass_fcommon;
631 if ((sym->c.flags & BSF_GLOBAL) != 0) return bfd_symclass_global;
632 if ((sym->c.flags & BSF_DEBUGGING) != 0) return bfd_symclass_debugger;
633 if ((sym->c.flags & BSF_UNDEFINED) != 0) return bfd_symclass_undefined;
634
635 return bfd_symclass_unknown;
636 }
637
638 static boolean
639 ecoff_symbol_hasclass (abfd, idx, class)
640 bfd *abfd;
641 symindex idx;
642 symclass class;
643 {
644
645 esymbol *sym = obj_symbols (abfd) + idx;
646
647 switch (class) {
648
649 case bfd_symclass_fcommon: return (sym->c.flags & BSF_FORT_COMM) != 0;
650 case bfd_symclass_global: return (sym->c.flags & BSF_GLOBAL) != 0;
651 case bfd_symclass_debugger: return (sym->c.flags & BSF_DEBUGGING) != 0;
652 case bfd_symclass_undefined: return (sym->c.flags & BSF_UNDEFINED) != 0;
653
654 default: return false;
655 }
656 }
657
658
659
660
661 static
662 boolean
663 ecoff_slurp_line_table (abfd, asect)
664 bfd *abfd;
665 asection *asect;
666 {
667 return true;
668 }
669
670 static boolean
671 ecoff_slurp_symbol_table(abfd)
672 bfd *abfd;
673 {
674 struct syment *native_symbols;
675 esymbol *cached_area;
676 char *string_table = (char *)NULL;
677 unsigned int string_table_size;
678 unsigned int number_of_symbols = 0;
679 if (obj_symbols (abfd)) return true;
680 bfd_seek(abfd, obj_sym_filepos(abfd), false);
681 /* Read in the symbol table */
682 native_symbols =
683 (struct syment *)buy_and_read(abfd,
684 obj_sym_filepos(abfd),
685 false,
686 bfd_get_symcount(abfd) * sizeof(struct syment));
687 if (!native_symbols) {
688 return false;
689 }
690
691
692 /* Allocate enough room for all the symbols in cached form */
693 cached_area = (esymbol *)xmalloc(bfd_get_symcount(abfd) * sizeof(esymbol));
694
695
696 {
697
698 esymbol *dst = cached_area;
699 unsigned int last_native_index = bfd_get_symcount(abfd);
700 unsigned int this_index = 0;
701 while (this_index < last_native_index)
702 {
703 struct syment *src = native_symbols + this_index;
704 if (src->n_zeroes == 0) {
705 /* This symbol has a name in the string table */
706 /* Which means that we'll have to read it in */
707
708 /* Fetch the size of the string table which is straight after the
709 * symbol table
710 */
711 if (string_table == (char *)NULL) {
712 if (bfd_read(&string_table_size, sizeof(string_table_size), 1, abfd) !=
713 sizeof(string_table_size)) {
714 fatal("Corrupt coff format");
715 }
716 else {
717 /* Read the string table */
718 string_table =
719 (char *)buy_and_read(abfd,0, true,
720 string_table_size - sizeof(string_table_size)) ;
721
722 }
723 }
724
725
726 dst->c.name = string_table + src->n_offset - 4;
727 }
728 else {
729 /* Otherwise we have to buy somewhere for this name */
730 dst->c.name = xmalloc (SYMNMLEN+1);
731 strncpy(dst->c.name, src->n_name, SYMNMLEN);
732 dst->c.name[SYMNMLEN+1] = '\0'; /* Be sure to terminate it */
733 }
734
735 /* We use the native name field to point to the cached field */
736 src->n_zeroes = (long)dst;
737 dst->c.section = section_from_bfd_index(abfd, src->n_scnum);
738 switch (src->n_sclass)
739 {
740 #ifdef I960
741 case C_LEAFPROC:
742 dst->c.value = src->n_value - dst->c.section->vma;
743 dst->c.flags = BSF_EXPORT | BSF_GLOBAL;
744 dst->c.flags |= BSF_NOT_AT_END;
745 break;
746
747 #endif
748
749 case C_EXT:
750 if (src->n_scnum == 0) {
751 if (src->n_value == 0)
752 {
753 dst->c.flags = BSF_UNDEFINED;
754 }
755 else {
756 dst->c.flags = BSF_FORT_COMM;
757 dst->c.value = src->n_value;
758 }
759 }
760 else {
761
762 /* Base the value as an index from the base of the section */
763 if (dst->c.section == (asection *)NULL)
764 {
765 dst->c.flags = BSF_EXPORT | BSF_GLOBAL | BSF_ABSOLUTE;
766 dst->c.value = src->n_value;
767 }
768 else
769 {
770 dst->c.flags = BSF_EXPORT | BSF_GLOBAL;
771 dst->c.value = src->n_value - dst->c.section->vma;
772 }
773 if (ISFCN(src->n_type)) {
774 /* A function ext does not go at the end of a file*/
775 dst->c.flags |= BSF_NOT_AT_END;
776 }
777
778 }
779
780 break;
781 case C_STAT : /* static */
782 case C_LABEL : /* label */
783 dst->c.flags = BSF_LOCAL;
784 /* Base the value as an index from the base of the section */
785 dst->c.value = src->n_value - dst->c.section->vma;
786 break;
787
788 case C_MOS : /* member of structure */
789 case C_EOS : /* end of structure */
790 case C_REGPARM : /* register parameter */
791 case C_REG : /* register variable */
792 case 19 : /* Intel specific REGARG FIXME */
793 case C_TPDEF : /* type definition */
794
795 case C_ARG:
796 case C_AUTO: /* automatic variable */
797 case C_FIELD: /* bit field */
798 case C_ENTAG : /* enumeration tag */
799 case C_MOE : /* member of enumeration */
800 case C_MOU : /* member of union */
801 case C_UNTAG : /* union tag */
802
803 dst->c.flags = BSF_DEBUGGING;
804 dst->c.value = src->n_value;
805 break;
806
807 case C_FILE : /* file name */
808 case C_STRTAG : /* structure tag */
809 dst->c.flags = BSF_DEBUGGING;
810 dst->c.value = src->n_value ;
811
812 break;
813 case C_BLOCK : /* ".bb" or ".eb" */
814 case C_FCN : /* ".bf" or ".ef" */
815 dst->c.flags = BSF_LOCAL;
816 /* Base the value as an index from the base of the section */
817 dst->c.value = src->n_value - dst->c.section->vma;
818
819 break;
820 case C_EFCN : /* physical end of function */
821 case C_NULL:
822 case C_EXTDEF : /* external definition */
823 case C_ULABEL : /* undefined label */
824 case C_USTATIC : /* undefined static */
825 case C_LINE : /* line # reformatted as symbol table entry */
826 case C_ALIAS : /* duplicate tag */
827 case C_HIDDEN : /* ext symbol in dmert public lib */
828
829 default:
830
831 printf("SICK%d\n",src->n_sclass);
832 dst->c.flags = BSF_DEBUGGING;
833 dst->c.value = src->n_value ;
834
835 break;
836 }
837
838
839
840
841 if (dst->c.flags == 0) fatal("OOOO dear");
842
843 dst->native = src;
844 dst->c.udata = 0;
845 dst->c.lineno = (alent *)NULL;
846 this_index += src->n_numaux + 1;
847 dst++;
848 number_of_symbols++;
849 }
850
851 }
852 obj_symbols(abfd) = cached_area;
853 obj_raw_syments(abfd) = native_symbols;
854 bfd_get_symcount(abfd) = number_of_symbols;
855
856 /* Slurp the line tables for each section too */
857 {
858 asection *p;
859 p = abfd->sections;
860 while (p) {
861 ecoff_slurp_line_table(abfd, p);
862 p =p->next;
863 }
864 }
865 return true;
866 }
867
868 unsigned int
869 ecoff_get_symtab_upper_bound (abfd)
870 bfd *abfd;
871 {
872 if (!ecoff_slurp_symbol_table (abfd)) return 0;
873
874 return (bfd_get_symcount (abfd)+1) * (sizeof (esymbol *));
875 }
876
877
878 unsigned int
879 ecoff_get_symtab(abfd, alocation)
880 bfd *abfd;
881 asymbol **alocation;
882 {
883 unsigned int counter = 0;
884 esymbol *symbase;
885 esymbol **location = (esymbol **)(alocation);
886
887 if (!ecoff_slurp_symbol_table (abfd)) return 0;
888
889 for (symbase = obj_symbols (abfd); counter++ < bfd_get_symcount (abfd);)
890 *(location++) = symbase++;
891 *location++ =0;
892 return counter;
893 }
894
895 unsigned int
896 ecoff_get_reloc_upper_bound (abfd, asect)
897 bfd *abfd;
898 sec_ptr asect;
899 {
900 if (bfd_get_format (abfd) != bfd_object) {
901 bfd_error = invalid_operation;
902 return 0;
903 }
904
905 return (asect->reloc_count + 1) * sizeof(arelent *);
906 }
907
908
909
910
911 boolean
912 ecoff_slurp_reloc_table (abfd, asect)
913 bfd *abfd;
914 sec_ptr asect;
915 {
916 struct reloc *native_relocs;
917 arelent *reloc_cache;
918
919 if (asect->relocation) return true;
920 if (asect->reloc_count ==0) return true;
921 if (!ecoff_slurp_symbol_table (abfd)) return false;
922
923 native_relocs = (struct reloc *)buy_and_read(abfd,
924 asect->rel_filepos,
925 false,
926 sizeof(struct reloc) * asect->reloc_count);
927 reloc_cache = (arelent *)xmalloc(asect->reloc_count * sizeof(arelent ));
928
929 {
930
931 unsigned int counter = 0;
932 arelent *cache_ptr = reloc_cache;
933 struct reloc *src = native_relocs;
934 while (counter < asect->reloc_count)
935 {
936 cache_ptr->address = src->r_vaddr - asect->original_vma;
937 cache_ptr->sym = (asymbol *)(src->r_symndx +
938 obj_raw_syments (abfd))->n_zeroes;
939 /* The symbols that we have read in have been relocated as if their
940 * sections started at 0. But the offsets refering to the symbols
941 * in the raw data have not been modified, so we have to have
942 * a negative addend to compensate
943 */
944 if (cache_ptr->sym->section) {
945 cache_ptr->addend = - cache_ptr->sym->section->original_vma;
946 }
947 else {
948 /* If the symbol doesn't have a section then it hasn't been relocated,
949 * so we don't have to fix it
950 */
951 cache_ptr->addend = 0;
952 }
953
954 cache_ptr->section = 0;
955 #if I960
956 cache_ptr->howto = howto_table + src->r_type;
957 #endif
958 #if M88
959 if (src->r_type >= R_PCR16L && src->r_type <= R_VRT32)
960 {
961 cache_ptr->howto = howto_table + src->r_type - R_PCR16L;
962 }
963 else
964 {
965 fatal("unrecognised reloc type %d\n", src->r_type);
966 }
967 #endif
968 cache_ptr++;
969 src++;
970 counter++;
971 }
972
973 }
974
975 free (native_relocs);
976 asect->relocation = reloc_cache;
977 return true;
978 }
979
980
981 /* This is stupid. This function should be a boolean predicate */
982 unsigned int
983 ecoff_canonicalize_reloc (abfd, section, relptr)
984 bfd *abfd;
985 sec_ptr section;
986 arelent **relptr;
987 {
988 return 0;
989 }
990
991 bfd_target ecoff_little_vec =
992 {"ecoff-littlemips", /* name */
993 false, /* data byte order is little */
994 false, /* header byte order is little */
995
996 (HAS_RELOC | EXEC_P | /* object flags */
997 HAS_LINENO | HAS_DEBUG |
998 HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT),
999
1000 (SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
1001 0, /* valid reloc types */
1002 '/', /* ar_pad_char */
1003 15, /* ar_max_namelen */
1004 ecoff_close_and_cleanup, /* _close_and_cleanup */
1005 ecoff_set_section_contents, /* bfd_set_section_contents */
1006 ecoff_new_section_hook, /* new_section_hook */
1007 _bfd_dummy_core_file_failing_command, /* _core_file_failing_command */
1008 _bfd_dummy_core_file_failing_signal, /* _core_file_failing_signal */
1009 _bfd_dummy_core_file_matches_executable_p, /* _core_file_matches_ex...p */
1010
1011 bfd_slurp_coff_armap, /* bfd_slurp_armap */
1012 _bfd_slurp_extended_name_table, /* bfd_slurp_extended_name_table*/
1013 bfd_dont_truncate_arname, /* bfd_truncate_arname */
1014
1015 ecoff_get_symtab_upper_bound, /* get_symtab_upper_bound */
1016 ecoff_get_symtab, /* canonicalize_symtab */
1017 (void (*)())bfd_false, /* bfd_reclaim_symbol_table */
1018 ecoff_get_reloc_upper_bound, /* get_reloc_upper_bound */
1019 ecoff_canonicalize_reloc, /* bfd_canonicalize_reloc */
1020 (void (*)())bfd_false, /* bfd_reclaim_reloc */
1021
1022 ecoff_get_symcount_upper_bound, /* bfd_get_symcount_upper_bound */
1023 ecoff_get_first_symbol, /* bfd_get_first_symbol */
1024 ecoff_get_next_symbol, /* bfd_get_next_symbol */
1025 ecoff_classify_symbol, /* bfd_classify_symbol */
1026 ecoff_symbol_hasclass, /* bfd_symbol_hasclass */
1027 ecoff_symbol_name, /* bfd_symbol_name */
1028 ecoff_symbol_value, /* bfd_symbol_value */
1029
1030 _do_getllong, _do_putllong, _do_getlshort, _do_putlshort, /* data */
1031 _do_getllong, _do_putllong, _do_getlshort, _do_putlshort, /* hdrs */
1032
1033 {_bfd_dummy_target, ecoff_object_p, /* bfd_check_format */
1034 bfd_generic_archive_p, _bfd_dummy_target},
1035 {bfd_false, ecoff_mkobject, bfd_false, /* bfd_set_format */
1036 bfd_false},
1037 ecoff_make_empty_symbol,
1038
1039
1040 };
1041
1042 bfd_target ecoff_big_vec =
1043 {"ecoff-bigmips", /* name */
1044 true, /* data byte order is big */
1045 true, /* header byte order is big */
1046
1047 (HAS_RELOC | EXEC_P | /* object flags */
1048 HAS_LINENO | HAS_DEBUG |
1049 HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT),
1050
1051 (SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
1052 0, /* valid reloc types */
1053 '/', /* ar_pad_char */
1054 15, /* ar_max_namelen */
1055 ecoff_close_and_cleanup, /* _close_and_cleanup */
1056 ecoff_set_section_contents, /* bfd_set_section_contents */
1057 ecoff_new_section_hook, /* new_section_hook */
1058 _bfd_dummy_core_file_failing_command, /* _core_file_failing_command */
1059 _bfd_dummy_core_file_failing_signal, /* _core_file_failing_signal */
1060 _bfd_dummy_core_file_matches_executable_p, /* _core_file_matches_ex...p */
1061
1062 bfd_slurp_coff_armap, /* bfd_slurp_armap */
1063 _bfd_slurp_extended_name_table, /* bfd_slurp_extended_name_table*/
1064 bfd_dont_truncate_arname, /* bfd_truncate_arname */
1065
1066 ecoff_get_symtab_upper_bound, /* get_symtab_upper_bound */
1067 ecoff_get_symtab, /* canonicalize_symtab */
1068 (void (*)())bfd_false, /* bfd_reclaim_symbol_table */
1069 ecoff_get_reloc_upper_bound, /* get_reloc_upper_bound */
1070 ecoff_canonicalize_reloc, /* bfd_canonicalize_reloc */
1071 (void (*)())bfd_false, /* bfd_reclaim_reloc */
1072
1073 ecoff_get_symcount_upper_bound, /* bfd_get_symcount_upper_bound */
1074 ecoff_get_first_symbol, /* bfd_get_first_symbol */
1075 ecoff_get_next_symbol, /* bfd_get_next_symbol */
1076 ecoff_classify_symbol, /* bfd_classify_symbol */
1077 ecoff_symbol_hasclass, /* bfd_symbol_hasclass */
1078 ecoff_symbol_name, /* bfd_symbol_name */
1079 ecoff_symbol_value, /* bfd_symbol_value */
1080
1081 _do_getblong, _do_putblong, _do_getbshort, _do_putbshort, /* data */
1082 _do_getblong, _do_putblong, _do_getbshort, _do_putbshort, /* hdrs */
1083
1084 {_bfd_dummy_target, ecoff_object_p, /* bfd_check_format */
1085 bfd_generic_archive_p, _bfd_dummy_target},
1086 {bfd_false, ecoff_mkobject, bfd_false, /* bfd_set_format */
1087 bfd_false},
1088 ecoff_make_empty_symbol,
1089
1090
1091 };
1092
1093 #endif /* ECOFF_BFD */