*** empty log message ***
[platform/upstream/binutils.git] / bfd / oasys.c
1 /*#define UNDERSCORE_HACK 0*/
2 /*
3    
4  bfd backend for oasys objects.
5
6
7  Object files contain records in order:
8
9  optional header
10  symbol records
11  section records
12  data records
13  debugging records
14  end record
15
16
17
18    Written by Steve Chamberlain
19    steve@cygnus.com
20
21
22
23  */
24
25
26 #include <ansidecl.h>
27 #include "sysdep.h"
28 #include "bfd.h"
29 #include "libbfd.h"
30 #include "obstack.h"
31 #include "oasys.h"
32 #include "liboasys.h"
33
34
35
36 #define obstack_chunk_alloc malloc
37 #define obstack_chunk_free free
38
39 typedef void generic_symbol_type;
40
41
42 void DEFUN(oasys_read_record,(abfd, record),
43       bfd *abfd AND 
44       oasys_record_union_type *record)
45 {
46
47   bfd_read(record, 1, sizeof(record->header), abfd);
48
49   bfd_read(((char *)record )+ sizeof(record->header),
50            1, record->header.length - sizeof(record->header),
51            abfd);
52 }
53 static size_t
54 oasys_string_length(record)
55 oasys_record_union_type *record;
56 {
57 return  record->header.length
58         - ((char *)record->symbol.name - (char *)record);
59 }
60
61 /*****************************************************************************/
62
63 /*
64
65 Slurp the symbol table by reading in all the records at the start file
66 till we get to the first section record.
67
68 We'll sort the symbols into  two lists, defined and undefined. The
69 undefined symbols will also be sorted by refno. We do this by placing
70 all undefined symbols at the front of the table moving in, and the
71 defined symbols at the end of the table moving back.
72
73 */
74
75 static boolean
76 oasys_slurp_symbol_table(abfd)
77 bfd *abfd;
78 {
79   oasys_record_union_type record;
80   oasys_data_type *data = oasys_data(abfd);
81   boolean loop = true;
82   asymbol *dest_undefined;
83   asymbol *dest_defined;
84   asymbol *dest;
85   char *string_ptr;
86
87
88   if (data->symbols != (asymbol *)NULL) {
89     return true;
90   }
91   /* Buy enough memory for all the symbols and all the names */
92   data->symbols = 
93     (asymbol *)malloc(sizeof(asymbol) * abfd->symcount);
94 #ifdef UNDERSCORE_HACK
95   /* buy 1 more char for each symbol to keep the underscore in*/
96   data->strings = malloc(data->symbol_string_length +
97                          abfd->symcount);
98 #else
99   data->strings = malloc(data->symbol_string_length);
100 #endif
101
102   dest_undefined = data->symbols;
103   dest_defined = data->symbols + abfd->symcount -1;
104
105   string_ptr = data->strings;
106   bfd_seek(abfd, (file_ptr)0, SEEK_SET);
107   while (loop) {
108
109     oasys_read_record(abfd, &record);
110     switch (record.header.type) {
111     case oasys_record_is_header_enum:
112       break;
113     case oasys_record_is_local_enum:
114     case oasys_record_is_symbol_enum:
115         {
116 int       flag = record.header.type == oasys_record_is_local_enum ?
117             (BSF_LOCAL) : (BSF_GLOBAL | BSF_EXPORT);
118
119
120           size_t length = oasys_string_length(&record);
121           switch (record.symbol.relb[0] & RELOCATION_TYPE_BITS) {
122           case RELOCATION_TYPE_ABS:
123             dest = dest_defined--;
124             dest->section = 0;
125             dest->flags = BSF_ABSOLUTE | flag;
126             break;
127           case RELOCATION_TYPE_REL:
128             dest = dest_defined--;
129             dest->section =
130               oasys_data(abfd)->sections[record.symbol.relb[0] &
131                                          RELOCATION_SECT_BITS];
132             if (record.header.type == oasys_record_is_local_enum) 
133                 {
134                   dest->flags = BSF_LOCAL;
135                 }
136             else {
137
138               dest->flags = flag;
139             }
140             break;
141           case RELOCATION_TYPE_UND:
142             dest = dest_undefined++;
143             dest->section = (asection *)NULL;
144             dest->flags = BSF_UNDEFINED;
145             break;
146           case RELOCATION_TYPE_COM:
147             dest = dest_defined--;
148             dest->name = string_ptr;
149             dest->the_bfd = abfd;
150
151             dest->section = (asection *)NULL;
152             dest->flags = BSF_FORT_COMM;
153             break;
154           }
155           dest->name = string_ptr;
156           dest->the_bfd = abfd;
157           dest->udata = (void *)NULL;
158           dest->value = bfd_h_getlong(abfd, &record.symbol.value);
159 #if UNDERSCORE_HACK
160           string_ptr[0] = '_';
161           string_ptr++;
162 #endif
163           memcpy(string_ptr, record.symbol.name, length);
164
165
166           string_ptr[length] =0;
167           string_ptr += length +1;
168         }
169       break;
170     default:
171       loop = false;
172     }
173   }
174   return true;
175
176 }
177
178 size_t
179 oasys_get_symtab_upper_bound (abfd)
180 bfd *abfd;
181 {
182   oasys_slurp_symbol_table (abfd);
183
184   return    (abfd->symcount+1) * (sizeof (oasys_symbol_type *));
185 }
186
187 /* 
188 */
189
190 extern bfd_target oasys_vec;
191
192 unsigned int
193 oasys_get_symtab (abfd, location)
194 bfd *abfd;
195 asymbol **location;
196 {
197   asymbol *symbase ;
198   unsigned int counter ;
199   if (oasys_slurp_symbol_table(abfd) == false) {
200     return 0;
201   }
202   symbase = oasys_data(abfd)->symbols;
203   for (counter = 0; counter < abfd->symcount; counter++) {
204     *(location++) = symbase++;
205   }
206   *location = 0;
207   return abfd->symcount;
208 }
209
210 /***********************************************************************
211 *  archive stuff 
212 */
213 #define swap(x) x = bfd_h_get_x(abfd, &x);
214 bfd_target *
215 oasys_archive_p(abfd)
216 bfd *abfd;
217 {
218   oasys_archive_header_type header;
219   unsigned int i;
220   
221   bfd_seek(abfd, (file_ptr) 0, false);
222
223   
224   bfd_read(&header, 1, sizeof(header), abfd);
225
226   
227   swap(header.version);
228   swap(header.mod_count);
229   swap(header.mod_tbl_offset);
230   swap(header.sym_tbl_size);
231   swap(header.sym_count);
232   swap(header.sym_tbl_offset);
233   swap(header.xref_count);
234   swap(header.xref_lst_offset);
235
236   /*
237      There isn't a magic number in an Oasys archive, so the best we
238      can do to verify reasnableness is to make sure that the values in
239      the header are too weird
240      */
241
242   if (header.version>10000 ||
243       header.mod_count>10000 ||
244       header.sym_count>100000 ||
245       header.xref_count > 100000) return (bfd_target *)NULL;
246
247   /*
248      That all worked, lets buy the space for the header and read in
249      the headers.
250      */
251   {
252     oasys_ar_data_type *ar =
253       (oasys_ar_data_type*) malloc(sizeof(oasys_ar_data_type));
254
255
256     oasys_module_info_type *module = 
257       (oasys_module_info_type*)
258         malloc(sizeof(oasys_module_info_type) * header.mod_count);
259
260     oasys_module_table_type record;
261
262     oasys_ar_data(abfd) =ar;
263     ar->module = module;
264     ar->module_count = header.mod_count;
265
266     bfd_seek(abfd , header.mod_tbl_offset, SEEK_SET);
267     for (i = 0; i < header.mod_count; i++) {
268
269       bfd_read(&record, 1, sizeof(record), abfd);
270       swap(record.mod_size);
271       swap(record.file_offset);
272       swap(record.mod_name_length);
273       module[i].name = malloc(record.mod_name_length+1);
274
275       bfd_read(module[i].name, 1, record.mod_name_length +1, abfd);
276       /* SKip some stuff */
277       bfd_seek(abfd, record.dep_count * sizeof(int32_type),
278             SEEK_CUR);
279
280       module[i].size = record.mod_size;
281       module[i].pos = record.file_offset;
282     }
283       
284   }
285   return abfd->xvec;
286 }
287
288 #define MAX_SECS 16
289 bfd_target *
290 oasys_object_p (abfd)
291 bfd *abfd;
292 {
293   oasys_data_type *oasys;
294   oasys_data_type static_data;
295
296   boolean loop = true;
297
298
299   boolean had_usefull = false;
300
301   memset((PTR)static_data.sections, 0xff, sizeof(static_data.sections));
302     
303   /* Point to the start of the file */
304   bfd_seek(abfd, (file_ptr)0, SEEK_SET);
305   static_data.symbol_string_length = 0;
306   /* Inspect the records, but only keep the section info -
307      remember the size of the symbols
308      */
309   static_data.first_data_record = 0;
310   while (loop) {
311
312     oasys_record_union_type record;
313     oasys_read_record(abfd, &record);
314  if (record.header.length < sizeof(record.header))
315       return (bfd_target *)NULL;
316
317     switch ((oasys_record_enum_type)(record.header.type)) {
318     case oasys_record_is_header_enum:
319       had_usefull = true;
320       break;
321     case oasys_record_is_symbol_enum:
322     case oasys_record_is_local_enum:
323       /* Count symbols and remember their size for a future malloc   */
324       abfd->symcount++;
325       static_data.symbol_string_length += 1 + oasys_string_length(&record);
326       had_usefull = true;
327       break;
328     case oasys_record_is_section_enum:
329       {
330         asection *s;
331         char *buffer;
332         unsigned int section_number;
333         if (record.section.header.length != sizeof(record.section))
334           {
335             return (bfd_target *)NULL;
336           }
337         buffer = malloc(3);
338         section_number= record.section.relb & RELOCATION_SECT_BITS;
339         sprintf(buffer,"%u", section_number);
340         s = bfd_make_section(abfd,buffer);
341         static_data.sections[section_number] = s;
342         switch (record.section.relb & RELOCATION_TYPE_BITS) {
343         case RELOCATION_TYPE_ABS:
344         case RELOCATION_TYPE_REL:
345           break;
346         case RELOCATION_TYPE_UND:
347         case RELOCATION_TYPE_COM:
348           BFD_FAIL();
349         }
350
351
352         s->size  = bfd_h_getlong(abfd, & record.section.value) ;
353         s->vma = bfd_h_getlong(abfd, &record.section.vma);
354         s->flags |= SEC_LOAD | SEC_HAS_CONTENTS;
355         had_usefull = true;
356       }
357       break;
358     case oasys_record_is_data_enum:
359       static_data.first_data_record = bfd_tell(abfd) - record.header.length;
360     case oasys_record_is_debug_enum:
361     case oasys_record_is_module_enum:
362     case oasys_record_is_named_section_enum:
363     case oasys_record_is_end_enum:
364       if (had_usefull == false) return (bfd_target *)NULL;
365       loop = false;
366       break;
367     default:
368       return (bfd_target *)NULL;
369     }
370   }
371   oasys_data(abfd) = (oasys_data_type
372                       *)malloc(sizeof(oasys_data_type));
373   oasys = oasys_data(abfd);
374   * oasys = static_data;
375
376   oasys->symbols = (asymbol *)NULL;
377   /* 
378      Oasys support several architectures, but I can't see a simple way
379      to discover which one is in a particular file - we'll guess 
380      */
381   abfd->obj_arch = bfd_arch_m68k;
382   abfd->obj_machine =0;
383   if (abfd->symcount != 0) {
384     abfd->flags |= HAS_SYMS;
385   }
386   return abfd->xvec;
387 }
388
389
390 void 
391 oasys_print_symbol(ignore_abfd, file,  symbol, how)
392 bfd *ignore_abfd;
393 FILE *file;
394 asymbol *symbol;
395 bfd_print_symbol_enum_type how;
396 {
397   switch (how) {
398   case bfd_print_symbol_name_enum:
399   case bfd_print_symbol_type_enum:
400     fprintf(file,"%s", symbol->name);
401     break;
402   case bfd_print_symbol_all_enum:
403     {
404       char *section_name = symbol->section == (asection *)NULL ?
405         "*abs" : symbol->section->name;
406
407       bfd_print_symbol_vandf((void *)file,symbol);
408
409       fprintf(file," %-5s %s",
410               section_name,
411               symbol->name);
412     }
413     break;
414   }
415 }
416 /*
417  The howto table is build using the top two bits of a reloc byte to
418  index into it. The bits are PCREL,WORD/LONG
419 */
420 static reloc_howto_type howto_table[]= 
421 {
422 /* T rs size bsz pcrel bitpos abs ovr sf name partial inplace mask */
423
424 {  0, 0,  1,   16, false,0,   true,true,0,"abs16",true,0x0000ffff},
425 {  0, 0,  2,   32, false,0,   true,true,0,"abs32",true,0xffffffff},
426 {  0, 0,  1,   16, true,0,   true,true,0,"pcrel16",true,0x0000ffff},
427 {  0, 0,  2,   32, true,0,   true,true,0,"pcrel32",true,0xffffffff}
428 };
429
430 /* Read in all the section data and relocation stuff too */
431 static boolean oasys_slurp_section_data(abfd)
432 bfd *abfd;
433 {
434   oasys_record_union_type record;
435   oasys_data_type *data = oasys_data(abfd);
436   boolean loop = true;
437
438   oasys_per_section_type *per ;
439
440   asection *s;
441
442   /* Buy enough memory for all the section data and relocations */
443   for (s = abfd->sections; s != (asection *)NULL; s= s->next) {
444     per =  oasys_per_section(s);
445     if (per->data != (bfd_byte*)NULL) return true;
446     per->data = (bfd_byte *) malloc(s->size);
447     obstack_init(&per->reloc_obstack);
448     per->reloc_tail_ptr = (oasys_reloc_type **)&(s->relocation);
449   }
450
451   if (data->first_data_record == 0)  return true;
452   bfd_seek(abfd, data->first_data_record, SEEK_SET);
453   while (loop) {
454     oasys_read_record(abfd, &record);
455     switch (record.header.type) {
456     case oasys_record_is_header_enum:
457       break;
458     case oasys_record_is_data_enum:
459         {
460
461           uint8e_type *src = record.data.data;
462           uint8e_type *end_src = ((uint8e_type *)&record) +
463             record.header.length;
464           unsigned int relbit;
465           bfd_byte *dst_ptr ;
466           bfd_byte *dst_base_ptr ;
467           asection *section;
468           unsigned int count;
469
470           bfd_vma dst_offset = bfd_h_getlong(abfd, record.data.addr);
471           section = data->sections[record.data.relb & RELOCATION_SECT_BITS];
472           per =  oasys_per_section(section);
473           dst_base_ptr = oasys_per_section(section)->data;
474           dst_ptr = oasys_per_section(section)->data +
475             dst_offset;
476
477           while (src < end_src) {
478             uint32_type gap = end_src - src -1;
479             uint8e_type mod_byte = *src++;
480             count = 8;
481             if (mod_byte == 0 && gap >= 8) {
482               dst_ptr[0] = src[0];
483               dst_ptr[1] = src[1];
484               dst_ptr[2] = src[2];
485               dst_ptr[3] = src[3];
486               dst_ptr[4] = src[4];
487               dst_ptr[5] = src[5];
488               dst_ptr[6] = src[6];
489               dst_ptr[7] = src[7];
490               dst_ptr+= 8;
491               src += 8;
492             }
493             else {
494               for (relbit = 1; count-- != 0 && gap != 0; gap --, relbit <<=1) 
495                   {
496                     if (relbit & mod_byte) 
497                         {
498                           uint8e_type reloc = *src;
499                           /* This item needs to be relocated */
500                           switch (reloc & RELOCATION_TYPE_BITS) {
501                           case RELOCATION_TYPE_ABS:
502
503                             break;
504
505                           case RELOCATION_TYPE_REL: 
506                               {
507                                 /* Relocate the item relative to the section */
508                                 oasys_reloc_type *r =
509                                   (oasys_reloc_type *)
510                                     obstack_alloc(&per->reloc_obstack,
511                                                   sizeof(oasys_reloc_type));
512                                 *(per->reloc_tail_ptr) = r;
513                                 per->reloc_tail_ptr = &r->next;
514                                 r->next= (oasys_reloc_type *)NULL;
515                                 /* Reference to undefined symbol */
516                                 src++;
517                                 /* There is no symbol */
518                                 r->symbol = 0;
519                                 /* Work out the howto */
520                                 r->relent.section =
521                                   data->sections[reloc & RELOCATION_SECT_BITS];
522                                 r->relent.addend = 0;
523                                 r->relent.address = dst_ptr - dst_base_ptr;
524                                 r->relent.howto = &howto_table[reloc>>6];
525                                 r->relent.sym_ptr_ptr = (asymbol **)NULL;
526                                 section->reloc_count++;
527
528                               }
529                             break;
530
531
532                           case RELOCATION_TYPE_UND:
533                               { 
534                                 oasys_reloc_type *r =
535                                   (oasys_reloc_type *)
536                                     obstack_alloc(&per->reloc_obstack,
537                                                   sizeof(oasys_reloc_type));
538                                 *(per->reloc_tail_ptr) = r;
539                                 per->reloc_tail_ptr = &r->next;
540                                 r->next= (oasys_reloc_type *)NULL;
541                                 /* Reference to undefined symbol */
542                                 src++;
543                                 /* Get symbol number */
544                                 r->symbol = (src[0]<<8) | src[1];
545                                 /* Work out the howto */
546                                 r->relent.section = (asection *)NULL;
547                                 r->relent.addend = 0;
548                                 r->relent.address = dst_ptr - dst_base_ptr;
549                                 r->relent.howto = &howto_table[reloc>>6];
550                                 r->relent.sym_ptr_ptr = (asymbol **)NULL;
551
552                                 section->reloc_count++;
553                                 src+=2;
554                               }
555                             break;
556                           case RELOCATION_TYPE_COM:
557                             BFD_FAIL();
558                           }
559                         }
560                     *dst_ptr++ = *src++;
561                   }
562             }
563           }       
564         }
565       break;
566     case oasys_record_is_local_enum:
567     case oasys_record_is_symbol_enum:
568     case oasys_record_is_section_enum:
569       break;
570     default:
571       loop = false;
572     }
573   }
574   return true;
575
576 }
577
578
579
580
581
582 boolean
583 oasys_new_section_hook (abfd, newsect)
584 bfd *abfd;
585 asection *newsect;
586 {
587   newsect->used_by_bfd = (oasys_per_section_type *)
588     malloc(sizeof(oasys_per_section_type));
589   oasys_per_section( newsect)->data = (bfd_byte *)NULL;
590   oasys_per_section(newsect)->section = newsect;
591   oasys_per_section(newsect)->offset  = 0;
592   return true;
593 }
594
595
596 unsigned int
597 oasys_get_reloc_upper_bound (abfd, asect)
598 bfd *abfd;
599 sec_ptr asect;
600 {
601   oasys_slurp_section_data(abfd);
602   return (asect->reloc_count+1) * sizeof(arelent *);
603 }
604
605 static boolean
606 oasys_get_section_contents (abfd, section, location, offset, count)
607 bfd *abfd;
608 sec_ptr section;
609 void  *location;
610 file_ptr offset;
611 unsigned      int count;
612 {
613   oasys_per_section_type *p = section->used_by_bfd;
614   oasys_slurp_section_data(abfd);
615   (void)  memcpy(location, p->data + offset, count);
616   return true;
617 }
618
619
620 unsigned int
621 oasys_canonicalize_reloc (abfd, section, relptr, symbols)
622 bfd *abfd;
623 sec_ptr section;
624 arelent **relptr;
625 asymbol **symbols;
626 {
627   oasys_reloc_type *src = (oasys_reloc_type *)(section->relocation);
628   while (src != (oasys_reloc_type *)NULL) {
629     if (src->relent.section == (asection *)NULL) {
630     src->relent.sym_ptr_ptr = symbols + src->symbol;
631   }
632     *relptr ++ = &src->relent;
633     src = src->next;
634   }
635   *relptr = (arelent *)NULL;
636   return section->reloc_count;
637 }
638
639 boolean
640 oasys_set_arch_mach (abfd, arch, machine)
641 bfd *abfd;
642 enum bfd_architecture arch;
643 unsigned long machine;
644 {
645   abfd->obj_arch = arch;
646   abfd->obj_machine = machine;
647   return true;
648 }
649
650 boolean
651 oasys_mkobject(abfd)
652 bfd *abfd;
653 {
654   oasys_data_type *oasys =
655     (oasys_data_type *) malloc(sizeof(oasys_data_type));
656   oasys_data(abfd) = oasys;
657   if (oasys == (oasys_data_type *)NULL) {
658     bfd_error = no_memory;
659     return false;
660   }
661
662   return true;
663 }
664
665
666
667
668
669
670
671 static void
672 init_for_output(abfd)
673 bfd *abfd;
674 {
675   asection *s; 
676   for (s = abfd->sections; s != (asection *)NULL; s = s->next) {
677     if (s->size != 0) {
678       oasys_per_section(s)->data = (bfd_byte *)(malloc(s->size));
679     }
680   }
681 }
682
683 /** exec and core file sections */
684
685 /* set section contents is complicated with OASYS since the format is 
686 * not a byte image, but a record stream.
687 */
688 boolean
689 oasys_set_section_contents (abfd, section, location, offset, count)
690 bfd *abfd;
691 sec_ptr section;
692 unsigned char *location;
693 file_ptr offset;
694 int count;
695 {
696   if (oasys_per_section(section)->data == (bfd_byte *)NULL) {
697     init_for_output(abfd);
698   }
699   (void) memcpy(oasys_per_section(section)->data + offset, location, count);
700   return true;
701 }
702
703
704
705 \f
706 /* Native-level interface to symbols. */
707
708 /* We read the symbols into a buffer, which is discarded when this
709 function exits.  We read the strings into a buffer large enough to
710 hold them all plus all the cached symbol entries. */
711
712 asymbol *
713 oasys_make_empty_symbol (abfd)
714 bfd *abfd;
715 {
716
717   oasys_symbol_type  *new =
718     (oasys_symbol_type *)zalloc (sizeof (oasys_symbol_type));
719   new->symbol.the_bfd = abfd;
720   return &new->symbol;
721
722 }
723
724 void
725 oasys_reclaim_symbol_table (abfd)
726 bfd *abfd;
727 {
728 #if 0
729   asection *section;
730
731   if (!bfd_get_symcount (abfd)) return;
732
733   for (section = abfd->sections; section != NULL; section = section->next)
734     if (section->relocation) {
735       free ((void *)section->relocation);
736       section->relocation = NULL;
737       section->reloc_count = 0;
738     }
739
740   bfd_get_symcount (abfd) = 0;
741   free ((void *)obj_aout_symbols (abfd));
742   obj_aout_symbols (abfd) = (aout_symbol_type *)NULL;
743 #endif
744 }
745 \f
746
747
748 \f
749 /* Obsbolete procedural interface; better to look at the cache directly */
750
751 /* User should have checked the file flags; perhaps we should return
752 BFD_NO_MORE_SYMBOLS if there are none? */
753
754 int
755 oasys_get_symcount_upper_bound (abfd)
756 bfd *abfd;
757 {
758 #if 0
759   /* In case we're doing an output file or something...?  */
760   if (bfd_get_symcount (abfd)) return bfd_get_symcount (abfd);
761
762   return (exec_hdr (abfd)->a_syms) / (sizeof (struct nlist));
763 #endif
764 }
765
766 symindex
767 oasys_get_first_symbol (ignore_abfd)
768 bfd * ignore_abfd;
769 {
770   return 0;
771 }
772
773 symindex
774 oasys_get_next_symbol (abfd, oidx)
775 bfd *abfd;
776 symindex oidx;
777 {
778 #if 0
779   if (oidx == BFD_NO_MORE_SYMBOLS) return BFD_NO_MORE_SYMBOLS;
780   return ++oidx >= bfd_get_symcount (abfd) ? BFD_NO_MORE_SYMBOLS :
781   oidx;
782 #endif
783 }
784
785 char *
786 oasys_symbol_name (abfd, idx)
787 bfd *abfd;
788 symindex idx;
789 {
790 #if 0
791   return (obj_aout_symbols (abfd) + idx)->symbol.name;
792 #endif
793 }
794
795 long
796 oasys_symbol_value (abfd, idx)
797 bfd *abfd;
798 symindex idx;
799 {
800 #if 0
801   return (obj_aout_symbols (abfd) + idx)->symbol.value;
802 #endif
803 }
804
805 symclass
806 oasys_classify_symbol (abfd, idx)
807 bfd *abfd;
808 symindex idx;
809 {
810 #if 0
811   aout_symbol_type *sym = obj_aout_symbols (abfd) + idx;
812
813   if ((sym->symbol.flags & BSF_FORT_COMM) != 0)   return bfd_symclass_fcommon;
814   if ((sym->symbol.flags & BSF_GLOBAL) != 0)    return bfd_symclass_global;
815   if ((sym->symbol.flags & BSF_DEBUGGING) != 0)  return bfd_symclass_debugger;
816   if ((sym->symbol.flags & BSF_UNDEFINED) != 0) return bfd_symclass_undefined;
817 #endif
818   return bfd_symclass_unknown;
819 }
820
821 boolean
822 oasys_symbol_hasclass (abfd, idx, class)
823 bfd *abfd;
824 symindex idx;
825 symclass class;
826 {
827 #if 0
828   aout_symbol_type *sym = obj_aout_symbols (abfd) + idx;
829   switch (class) {
830   case bfd_symclass_fcommon:
831     return (sym->symbol.flags & BSF_FORT_COMM) ? true :false;
832   case bfd_symclass_global:
833     return (sym->symbol.flags & BSF_GLOBAL) ? true:false;
834   case bfd_symclass_debugger:
835     return (sym->symbol.flags & BSF_DEBUGGING) ? true:false;;
836   case bfd_symclass_undefined:
837     return (sym->symbol.flags & BSF_UNDEFINED) ? true:false;;
838   default: return false;
839   }
840 #endif
841 }
842
843
844 void
845 oasys_reclaim_reloc (ignore_abfd, section)
846 bfd *ignore_abfd;
847 sec_ptr section;
848 {
849 #if 0
850   if (section->relocation) {
851     free (section->relocation);
852     section->relocation = NULL;
853     section->reloc_count = 0;
854   }
855 #endif
856 }
857
858 boolean
859 oasys_close_and_cleanup (abfd)
860 bfd *abfd;
861 {
862   if (bfd_read_p (abfd) == false)
863     switch (abfd->format) {
864     case bfd_archive:
865       if (!_bfd_write_archive_contents (abfd)) {
866         return false;
867       }
868       break;
869     case bfd_object:
870 /*      if (!oasys_write_object_contents (abfd)) */{
871         return false;
872       }
873       break;
874     default:
875       bfd_error = invalid_operation;
876       return false;
877     }
878
879
880   if (oasys_data(abfd) != (oasys_data_type *)NULL) {
881     /* FIXME MORE LEAKS */
882
883   }
884
885   return true;
886 }
887
888 static bfd *
889 oasys_openr_next_archived_file(arch, prev)
890 bfd *arch;
891 bfd *prev;
892 {
893   oasys_ar_data_type *ar = oasys_ar_data(arch);
894   oasys_module_info_type *p;
895   /* take the next one from the arch state, or reset */
896   if (prev == (bfd *)NULL) {
897     /* Reset the index - the first two entries are bogus*/
898     ar->module_index = 0;
899   }
900
901   p = ar->module + ar->module_index;
902   ar->module_index++;
903
904   if (ar->module_index <= ar->module_count) {
905     if (p->abfd == (bfd *)NULL) {
906       p->abfd = _bfd_create_empty_archive_element_shell(arch);
907       p->abfd->origin = p->pos;
908       p->abfd->filename = p->name;
909
910       /* Fixup a pointer to this element for the member */
911       p->abfd->arelt_data = (void *)p;
912     }
913     return p->abfd;
914   }
915   else {
916     bfd_error = no_more_archived_files;
917     return (bfd *)NULL;
918   }
919 }
920
921 static boolean
922 oasys_find_nearest_line(abfd,
923                          section,
924                          symbols,
925                          offset,
926                          filename_ptr,
927                          functionname_ptr,
928                          line_ptr)
929 bfd *abfd;
930 asection *section;
931 asymbol **symbols;
932 bfd_vma offset;
933 char **filename_ptr;
934 char **functionname_ptr;
935 unsigned int *line_ptr;
936 {
937   return false;
938
939 }
940
941 static int
942 oasys_stat_arch_elt(abfd, buf)
943 bfd *abfd;
944 struct stat *buf;
945 {
946   oasys_module_info_type *mod = abfd->arelt_data;
947   if (mod == (oasys_module_info_type *)NULL) {
948     bfd_error = invalid_operation;
949     return -1;
950   }
951   else {
952     buf->st_size = mod->size;
953     buf->st_mode = 0666;
954   return 0;
955   }
956
957
958 }
959
960
961 /*SUPPRESS 460 */
962 bfd_target oasys_vec =
963 {
964   "oasys",                      /* name */
965   bfd_target_oasys_flavour_enum,
966   true,                         /* target byte order */
967   true,                         /* target headers byte order */
968   (HAS_RELOC | EXEC_P |         /* object flags */
969    HAS_LINENO | HAS_DEBUG |
970    HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
971   (SEC_CODE|SEC_DATA|SEC_ROM|SEC_HAS_CONTENTS
972    |SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
973   0,                            /* valid reloc types */
974   ' ',                          /* ar_pad_char */
975   16,                           /* ar_max_namelen */
976   oasys_close_and_cleanup,      /* _close_and_cleanup */
977   oasys_set_section_contents,   /* bfd_set_section_contents */
978   oasys_get_section_contents,
979   oasys_new_section_hook,       /*   new_section_hook */
980   0,                            /* _core_file_failing_command */
981   0,                            /* _core_file_failing_signal */
982   0,                            /* _core_file_matches_ex...p */
983
984   0,                            /* bfd_slurp_bsd_armap,               bfd_slurp_armap */
985   bfd_true,                     /* bfd_slurp_extended_name_table */
986   bfd_bsd_truncate_arname,      /* bfd_truncate_arname */
987
988   oasys_get_symtab_upper_bound, /* get_symtab_upper_bound */
989   oasys_get_symtab,             /* canonicalize_symtab */
990   0,                            /* oasys_reclaim_symbol_table,            bfd_reclaim_symbol_table */
991   oasys_get_reloc_upper_bound,  /* get_reloc_upper_bound */
992   oasys_canonicalize_reloc,     /* bfd_canonicalize_reloc */
993   0,                            /*  oasys_reclaim_reloc,                   bfd_reclaim_reloc */
994   0,                            /* oasys_get_symcount_upper_bound,        bfd_get_symcount_upper_bound */
995   0,                            /* oasys_get_first_symbol,                bfd_get_first_symbol */
996   0,                            /* oasys_get_next_symbol,                 bfd_get_next_symbol */
997   0,                            /* oasys_classify_symbol,                 bfd_classify_symbol */
998   0,                            /* oasys_symbol_hasclass,                 bfd_symbol_hasclass */
999   0,                            /* oasys_symbol_name,                     bfd_symbol_name */
1000   0,                            /* oasys_symbol_value,                    bfd_symbol_value */
1001
1002   _do_getblong, _do_putblong, _do_getbshort, _do_putbshort, /* data */
1003   _do_getblong, _do_putblong, _do_getbshort, _do_putbshort, /* hdrs */
1004
1005   {_bfd_dummy_target,
1006      oasys_object_p,            /* bfd_check_format */
1007      oasys_archive_p,
1008      bfd_false
1009      },
1010   {
1011     bfd_false,
1012     oasys_mkobject, 
1013     _bfd_generic_mkarchive,
1014     bfd_false
1015     },
1016   oasys_make_empty_symbol,
1017   oasys_print_symbol,
1018   bfd_false,                    /*      oasys_get_lineno,*/
1019   oasys_set_arch_mach,          /* bfd_set_arch_mach,*/
1020   bfd_false,
1021   oasys_openr_next_archived_file,
1022   oasys_find_nearest_line,      /* bfd_find_nearest_line */
1023   oasys_stat_arch_elt,          /* bfd_stat_arch_elt */
1024 };