Initial revision
[platform/upstream/binutils.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_struct *section_from_bfd_index(abfd, index)
569 bfd *abfd;
570 int index;
571 {
572 if (index > 0) {
573   struct sec_struct *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 */