995d962aee1f6647809313f38278cbd8c96fc473
[binutils-gdb.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 };