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