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