3 bfd backend for oasys objects.
6 Object files contain records in order:
17 Written by Steve Chamberlain
35 #define obstack_chunk_alloc malloc
36 #define obstack_chunk_free free
38 typedef void generic_symbol_type;
41 void DEFUN(oasys_read_record,(abfd, record),
43 oasys_record_union_type *record)
46 bfd_read(record, 1, sizeof(record->header), abfd);
48 bfd_read(((char *)record )+ sizeof(record->header),
49 1, record->header.length - sizeof(record->header),
53 oasys_string_length(record)
54 oasys_record_union_type *record;
56 return record->header.length
57 - ((char *)record->symbol.name - (char *)record);
60 /*****************************************************************************/
64 Slurp the symbol table by reading in all the records at the start file
65 till we get to the first section record.
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.
75 oasys_slurp_symbol_table(abfd)
78 oasys_record_union_type record;
79 oasys_data_type *data = oasys_data(abfd);
81 asymbol *dest_undefined;
82 asymbol *dest_defined;
87 if (data->symbols != (asymbol *)NULL) {
90 /* Buy enough memory for all the symbols and all the names */
92 (asymbol *)malloc(sizeof(asymbol) * abfd->symcount);
93 data->strings = malloc(data->symbol_string_length);
95 dest_undefined = data->symbols;
96 dest_defined = data->symbols + abfd->symcount -1;
98 string_ptr = data->strings;
99 bfd_seek(abfd, (file_ptr)0, SEEK_SET);
101 oasys_read_record(abfd, &record);
102 switch (record.header.type) {
103 case oasys_record_is_header_enum:
105 case oasys_record_is_local_enum:
106 case oasys_record_is_symbol_enum:
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--;
113 dest->flags = BSF_ABSOLUTE | BSF_EXPORT | BSF_GLOBAL;
116 case RELOCATION_TYPE_REL:
117 dest = dest_defined--;
119 oasys_data(abfd)->sections[record.symbol.relb[0] &
120 RELOCATION_SECT_BITS];
121 if (record.header.type == oasys_record_is_local_enum)
123 dest->flags = BSF_LOCAL;
127 dest->flags = BSF_EXPORT | BSF_GLOBAL;
130 case RELOCATION_TYPE_UND:
131 dest = dest_undefined++;
132 dest->section = (asection *)NULL;
133 dest->flags = BSF_UNDEFINED;
135 case RELOCATION_TYPE_COM:
136 dest = dest_defined--;
137 dest->name = string_ptr;
138 dest->the_bfd = abfd;
140 dest->section = (asection *)NULL;
141 dest->flags = BSF_FORT_COMM;
144 dest->name = string_ptr;
145 dest->the_bfd = abfd;
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;
162 oasys_get_symtab_upper_bound (abfd)
165 oasys_slurp_symbol_table (abfd);
167 return (abfd->symcount != 0) ?
168 (abfd->symcount+1) * (sizeof (oasys_symbol_type *)) : 0;
174 extern bfd_target oasys_vec;
177 oasys_get_symtab (abfd, location)
182 unsigned int counter ;
183 if (oasys_slurp_symbol_table(abfd) == false) {
186 symbase = oasys_data(abfd)->symbols;
187 for (counter = 0; counter < abfd->symcount; counter++) {
188 *(location++) = symbase++;
191 return abfd->symcount;
194 /***********************************************************************
197 #define swap(x) x = bfd_h_get_x(abfd, &x);
199 oasys_archive_p(abfd)
202 oasys_archive_header_type header;
205 bfd_seek(abfd, (file_ptr) 0, false);
208 bfd_read(&header, 1, sizeof(header), abfd);
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);
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
226 if (header.version>10000 ||
227 header.mod_count>10000 ||
228 header.sym_count>100000 ||
229 header.xref_count > 100000) return (bfd_target *)NULL;
232 That all worked, lets buy the space for the header and read in
236 oasys_ar_data_type *ar =
237 (oasys_ar_data_type*) malloc(sizeof(oasys_ar_data_type));
240 oasys_module_info_type *module =
241 (oasys_module_info_type*)
242 malloc(sizeof(oasys_module_info_type) * header.mod_count);
244 oasys_module_table_type record;
246 oasys_ar_data(abfd) =ar;
248 ar->module_count = header.mod_count;
250 bfd_seek(abfd , header.mod_tbl_offset, SEEK_SET);
251 for (i = 0; i < header.mod_count; i++) {
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);
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),
264 module[i].size = record.mod_size;
265 module[i].pos = record.file_offset;
274 oasys_object_p (abfd)
277 oasys_data_type *oasys;
278 oasys_data_type static_data;
283 boolean had_usefull = false;
285 memset((PTR)static_data.sections, 0xff, sizeof(static_data.sections));
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
294 oasys_record_union_type record;
295 oasys_read_record(abfd, &record);
298 switch ((oasys_record_enum_type)(record.header.type)) {
299 case oasys_record_is_header_enum:
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 */
306 static_data.symbol_string_length += 1 + oasys_string_length(&record);
309 case oasys_record_is_section_enum:
313 unsigned int section_number;
314 if (record.section.header.length != sizeof(record.section))
316 return (bfd_target *)NULL;
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:
327 case RELOCATION_TYPE_UND:
328 case RELOCATION_TYPE_COM:
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;
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;
349 return (bfd_target *)NULL;
352 oasys_data(abfd) = (oasys_data_type
353 *)malloc(sizeof(oasys_data_type));
354 oasys = oasys_data(abfd);
355 * oasys = static_data;
357 oasys->symbols = (asymbol *)NULL;
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
362 abfd->obj_arch = bfd_arch_m68k;
363 abfd->obj_machine =0;
364 if (abfd->symcount != 0) {
365 abfd->flags |= HAS_SYMS;
372 oasys_print_symbol(ignore_abfd, file, symbol, how)
376 bfd_print_symbol_enum_type how;
379 case bfd_print_symbol_name_enum:
380 case bfd_print_symbol_type_enum:
381 fprintf(file,"%s", symbol->name);
383 case bfd_print_symbol_all_enum:
385 char *section_name = symbol->section == (asection *)NULL ?
386 "*abs" : symbol->section->name;
388 bfd_print_symbol_vandf((void *)file,symbol);
390 fprintf(file," %-5s %s",
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
401 static reloc_howto_type howto_table[]=
403 /* T rs size bsz pcrel bitpos abs ovr sf name partial inplace mask */
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}
411 /* Read in all the section data and relocation stuff too */
412 static boolean oasys_slurp_section_data(abfd)
415 oasys_record_union_type record;
416 oasys_data_type *data = oasys_data(abfd);
419 oasys_per_section_type *per ;
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);
432 bfd_seek(abfd, data->first_data_record, SEEK_SET);
434 oasys_read_record(abfd, &record);
435 switch (record.header.type) {
436 case oasys_record_is_header_enum:
438 case oasys_record_is_data_enum:
441 uint8e_type *src = record.data.data;
442 uint8e_type *end_src = ((uint8e_type *)&record) + record.header.length;
445 bfd_byte *dst_base_ptr ;
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;
454 while (src < end_src) {
455 uint8e_type mod_byte = *src++;
458 for (relbit = 1; count-- != 0; relbit <<=1)
460 if (relbit & mod_byte)
462 uint8e_type reloc = *src;
463 /* This item needs to be relocated */
464 switch (reloc & RELOCATION_TYPE_BITS) {
465 case RELOCATION_TYPE_ABS:
469 case RELOCATION_TYPE_REL:
471 /* Relocate the item relative to the section */
472 oasys_reloc_type *r =
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 */
481 /* There is no symbol */
483 /* Work out the howto */
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++;
495 case RELOCATION_TYPE_UND:
497 oasys_reloc_type *r =
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 */
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];
514 section->reloc_count++;
518 case RELOCATION_TYPE_COM:
527 case oasys_record_is_local_enum:
528 case oasys_record_is_symbol_enum:
529 case oasys_record_is_section_enum:
544 oasys_new_section_hook (abfd, newsect)
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;
558 oasys_get_reloc_upper_bound (abfd, asect)
562 oasys_slurp_section_data(abfd);
563 return (asect->reloc_count+1) * sizeof(arelent *);
567 oasys_get_section_contents (abfd, section, location, offset, count)
574 oasys_per_section_type *p = section->used_by_bfd;
575 oasys_slurp_section_data(abfd);
576 (void) memcpy(location, p->data + offset, count);
582 oasys_canonicalize_reloc (abfd, section, relptr, symbols)
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;
593 *relptr ++ = &src->relent;
596 *relptr = (arelent *)NULL;
597 return section->reloc_count;
601 oasys_set_arch_mach (abfd, arch, machine)
603 enum bfd_architecture arch;
604 unsigned long machine;
606 abfd->obj_arch = arch;
607 abfd->obj_machine = machine;
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;
633 init_for_output(abfd)
637 for (s = abfd->sections; s != (asection *)NULL; s = s->next) {
639 oasys_per_section(s)->data = (bfd_byte *)(malloc(s->size));
644 /** exec and core file sections */
646 /* set section contents is complicated with OASYS since the format is
647 * not a byte image, but a record stream.
650 oasys_set_section_contents (abfd, section, location, offset, count)
653 unsigned char *location;
657 if (oasys_per_section(section)->data == (bfd_byte *)NULL) {
658 init_for_output(abfd);
660 (void) memcpy(oasys_per_section(section)->data + offset, location, count);
667 /* Native-level interface to symbols. */
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. */
674 oasys_make_empty_symbol (abfd)
678 oasys_symbol_type *new =
679 (oasys_symbol_type *)zalloc (sizeof (oasys_symbol_type));
680 new->symbol.the_bfd = abfd;
686 oasys_reclaim_symbol_table (abfd)
692 if (!bfd_get_symcount (abfd)) return;
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;
701 bfd_get_symcount (abfd) = 0;
702 free ((void *)obj_aout_symbols (abfd));
703 obj_aout_symbols (abfd) = (aout_symbol_type *)NULL;
710 /* Obsbolete procedural interface; better to look at the cache directly */
712 /* User should have checked the file flags; perhaps we should return
713 BFD_NO_MORE_SYMBOLS if there are none? */
716 oasys_get_symcount_upper_bound (abfd)
720 /* In case we're doing an output file or something...? */
721 if (bfd_get_symcount (abfd)) return bfd_get_symcount (abfd);
723 return (exec_hdr (abfd)->a_syms) / (sizeof (struct nlist));
728 oasys_get_first_symbol (ignore_abfd)
735 oasys_get_next_symbol (abfd, oidx)
740 if (oidx == BFD_NO_MORE_SYMBOLS) return BFD_NO_MORE_SYMBOLS;
741 return ++oidx >= bfd_get_symcount (abfd) ? BFD_NO_MORE_SYMBOLS :
747 oasys_symbol_name (abfd, idx)
752 return (obj_aout_symbols (abfd) + idx)->symbol.name;
757 oasys_symbol_value (abfd, idx)
762 return (obj_aout_symbols (abfd) + idx)->symbol.value;
767 oasys_classify_symbol (abfd, idx)
772 aout_symbol_type *sym = obj_aout_symbols (abfd) + idx;
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;
779 return bfd_symclass_unknown;
783 oasys_symbol_hasclass (abfd, idx, class)
789 aout_symbol_type *sym = obj_aout_symbols (abfd) + idx;
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;
806 oasys_reclaim_reloc (ignore_abfd, section)
811 if (section->relocation) {
812 free (section->relocation);
813 section->relocation = NULL;
814 section->reloc_count = 0;
820 oasys_close_and_cleanup (abfd)
823 if (bfd_read_p (abfd) == false)
824 switch (abfd->format) {
826 if (!_bfd_write_archive_contents (abfd)) {
831 /* if (!oasys_write_object_contents (abfd)) */{
836 bfd_error = invalid_operation;
841 if (oasys_data(abfd) != (oasys_data_type *)NULL) {
842 /* FIXME MORE LEAKS */
850 oasys_openr_next_archived_file(arch, prev)
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;
862 p = ar->module + ar->module_index;
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;
871 /* Fixup a pointer to this element for the member */
872 p->abfd->arelt_data = (void *)p;
877 bfd_error = no_more_archived_files;
883 oasys_find_nearest_line(abfd,
895 char **functionname_ptr;
896 unsigned int *line_ptr;
903 oasys_stat_arch_elt(abfd, buf)
907 oasys_module_info_type *mod = abfd->arelt_data;
908 if (mod == (oasys_module_info_type *)NULL) {
909 bfd_error = invalid_operation;
913 buf->st_size = mod->size;
923 bfd_target oasys_vec =
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 */
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 */
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 */
963 _do_getblong, _do_putblong, _do_getbshort, _do_putbshort, /* data */
964 _do_getblong, _do_putblong, _do_getbshort, _do_putbshort, /* hdrs */
967 oasys_object_p, /* bfd_check_format */
974 _bfd_generic_mkarchive,
977 oasys_make_empty_symbol,
979 bfd_false, /* oasys_get_lineno,*/
980 oasys_set_arch_mach, /* bfd_set_arch_mach,*/
982 oasys_openr_next_archived_file,
983 oasys_find_nearest_line, /* bfd_find_nearest_line */
984 oasys_stat_arch_elt, /* bfd_stat_arch_elt */