]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - bfd/oasys.c
Fixed bug where abs symbols wern't being placed into the right bit of
[thirdparty/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 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 };