1 /*#define UNDERSCORE_HACK 0*/
4 bfd backend for oasys objects.
7 Object files contain records in order:
18 Written by Steve Chamberlain
36 #define obstack_chunk_alloc malloc
37 #define obstack_chunk_free free
39 typedef void generic_symbol_type;
42 void DEFUN(oasys_read_record,(abfd, record),
44 oasys_record_union_type *record)
47 bfd_read(record, 1, sizeof(record->header), abfd);
49 bfd_read(((char *)record )+ sizeof(record->header),
50 1, record->header.length - sizeof(record->header),
54 oasys_string_length(record)
55 oasys_record_union_type *record;
57 return record->header.length
58 - ((char *)record->symbol.name - (char *)record);
61 /*****************************************************************************/
65 Slurp the symbol table by reading in all the records at the start file
66 till we get to the first section record.
68 We'll sort the symbols into two lists, defined and undefined. The
69 undefined symbols will also be sorted by refno. We do this by placing
70 all undefined symbols at the front of the table moving in, and the
71 defined symbols at the end of the table moving back.
76 oasys_slurp_symbol_table(abfd)
79 oasys_record_union_type record;
80 oasys_data_type *data = oasys_data(abfd);
82 asymbol *dest_undefined;
83 asymbol *dest_defined;
88 if (data->symbols != (asymbol *)NULL) {
91 /* Buy enough memory for all the symbols and all the names */
93 (asymbol *)malloc(sizeof(asymbol) * abfd->symcount);
94 #ifdef UNDERSCORE_HACK
95 /* buy 1 more char for each symbol to keep the underscore in*/
96 data->strings = malloc(data->symbol_string_length +
99 data->strings = malloc(data->symbol_string_length);
102 dest_undefined = data->symbols;
103 dest_defined = data->symbols + abfd->symcount -1;
105 string_ptr = data->strings;
106 bfd_seek(abfd, (file_ptr)0, SEEK_SET);
109 oasys_read_record(abfd, &record);
110 switch (record.header.type) {
111 case oasys_record_is_header_enum:
113 case oasys_record_is_local_enum:
114 case oasys_record_is_symbol_enum:
116 int flag = record.header.type == oasys_record_is_local_enum ?
117 (BSF_LOCAL) : (BSF_GLOBAL | BSF_EXPORT);
120 size_t length = oasys_string_length(&record);
121 switch (record.symbol.relb[0] & RELOCATION_TYPE_BITS) {
122 case RELOCATION_TYPE_ABS:
123 dest = dest_defined--;
125 dest->flags = BSF_ABSOLUTE | flag;
127 case RELOCATION_TYPE_REL:
128 dest = dest_defined--;
130 oasys_data(abfd)->sections[record.symbol.relb[0] &
131 RELOCATION_SECT_BITS];
132 if (record.header.type == oasys_record_is_local_enum)
134 dest->flags = BSF_LOCAL;
141 case RELOCATION_TYPE_UND:
142 dest = dest_undefined++;
143 dest->section = (asection *)NULL;
144 dest->flags = BSF_UNDEFINED;
146 case RELOCATION_TYPE_COM:
147 dest = dest_defined--;
148 dest->name = string_ptr;
149 dest->the_bfd = abfd;
151 dest->section = (asection *)NULL;
152 dest->flags = BSF_FORT_COMM;
155 dest->name = string_ptr;
156 dest->the_bfd = abfd;
157 dest->udata = (void *)NULL;
158 dest->value = bfd_h_getlong(abfd, &record.symbol.value);
163 memcpy(string_ptr, record.symbol.name, length);
166 string_ptr[length] =0;
167 string_ptr += length +1;
179 oasys_get_symtab_upper_bound (abfd)
182 oasys_slurp_symbol_table (abfd);
184 return (abfd->symcount+1) * (sizeof (oasys_symbol_type *));
190 extern bfd_target oasys_vec;
193 oasys_get_symtab (abfd, location)
198 unsigned int counter ;
199 if (oasys_slurp_symbol_table(abfd) == false) {
202 symbase = oasys_data(abfd)->symbols;
203 for (counter = 0; counter < abfd->symcount; counter++) {
204 *(location++) = symbase++;
207 return abfd->symcount;
210 /***********************************************************************
213 #define swap(x) x = bfd_h_get_x(abfd, &x);
215 oasys_archive_p(abfd)
218 oasys_archive_header_type header;
221 bfd_seek(abfd, (file_ptr) 0, false);
224 bfd_read(&header, 1, sizeof(header), abfd);
227 swap(header.version);
228 swap(header.mod_count);
229 swap(header.mod_tbl_offset);
230 swap(header.sym_tbl_size);
231 swap(header.sym_count);
232 swap(header.sym_tbl_offset);
233 swap(header.xref_count);
234 swap(header.xref_lst_offset);
237 There isn't a magic number in an Oasys archive, so the best we
238 can do to verify reasnableness is to make sure that the values in
239 the header are too weird
242 if (header.version>10000 ||
243 header.mod_count>10000 ||
244 header.sym_count>100000 ||
245 header.xref_count > 100000) return (bfd_target *)NULL;
248 That all worked, lets buy the space for the header and read in
252 oasys_ar_data_type *ar =
253 (oasys_ar_data_type*) malloc(sizeof(oasys_ar_data_type));
256 oasys_module_info_type *module =
257 (oasys_module_info_type*)
258 malloc(sizeof(oasys_module_info_type) * header.mod_count);
260 oasys_module_table_type record;
262 oasys_ar_data(abfd) =ar;
264 ar->module_count = header.mod_count;
266 bfd_seek(abfd , header.mod_tbl_offset, SEEK_SET);
267 for (i = 0; i < header.mod_count; i++) {
269 bfd_read(&record, 1, sizeof(record), abfd);
270 swap(record.mod_size);
271 swap(record.file_offset);
272 swap(record.mod_name_length);
273 module[i].name = malloc(record.mod_name_length+1);
275 bfd_read(module[i].name, 1, record.mod_name_length +1, abfd);
276 /* SKip some stuff */
277 bfd_seek(abfd, record.dep_count * sizeof(int32_type),
280 module[i].size = record.mod_size;
281 module[i].pos = record.file_offset;
290 oasys_object_p (abfd)
293 oasys_data_type *oasys;
294 oasys_data_type static_data;
299 boolean had_usefull = false;
301 memset((PTR)static_data.sections, 0xff, sizeof(static_data.sections));
303 /* Point to the start of the file */
304 bfd_seek(abfd, (file_ptr)0, SEEK_SET);
305 static_data.symbol_string_length = 0;
306 /* Inspect the records, but only keep the section info -
307 remember the size of the symbols
309 static_data.first_data_record = 0;
312 oasys_record_union_type record;
313 oasys_read_record(abfd, &record);
314 if (record.header.length < sizeof(record.header))
315 return (bfd_target *)NULL;
317 switch ((oasys_record_enum_type)(record.header.type)) {
318 case oasys_record_is_header_enum:
321 case oasys_record_is_symbol_enum:
322 case oasys_record_is_local_enum:
323 /* Count symbols and remember their size for a future malloc */
325 static_data.symbol_string_length += 1 + oasys_string_length(&record);
328 case oasys_record_is_section_enum:
332 unsigned int section_number;
333 if (record.section.header.length != sizeof(record.section))
335 return (bfd_target *)NULL;
338 section_number= record.section.relb & RELOCATION_SECT_BITS;
339 sprintf(buffer,"%u", section_number);
340 s = bfd_make_section(abfd,buffer);
341 static_data.sections[section_number] = s;
342 switch (record.section.relb & RELOCATION_TYPE_BITS) {
343 case RELOCATION_TYPE_ABS:
344 case RELOCATION_TYPE_REL:
346 case RELOCATION_TYPE_UND:
347 case RELOCATION_TYPE_COM:
352 s->size = bfd_h_getlong(abfd, & record.section.value) ;
353 s->vma = bfd_h_getlong(abfd, &record.section.vma);
354 s->flags |= SEC_LOAD | SEC_HAS_CONTENTS;
358 case oasys_record_is_data_enum:
359 static_data.first_data_record = bfd_tell(abfd) - record.header.length;
360 case oasys_record_is_debug_enum:
361 case oasys_record_is_module_enum:
362 case oasys_record_is_named_section_enum:
363 case oasys_record_is_end_enum:
364 if (had_usefull == false) return (bfd_target *)NULL;
368 return (bfd_target *)NULL;
371 oasys_data(abfd) = (oasys_data_type
372 *)malloc(sizeof(oasys_data_type));
373 oasys = oasys_data(abfd);
374 * oasys = static_data;
376 oasys->symbols = (asymbol *)NULL;
378 Oasys support several architectures, but I can't see a simple way
379 to discover which one is in a particular file - we'll guess
381 abfd->obj_arch = bfd_arch_m68k;
382 abfd->obj_machine =0;
383 if (abfd->symcount != 0) {
384 abfd->flags |= HAS_SYMS;
391 oasys_print_symbol(ignore_abfd, file, symbol, how)
395 bfd_print_symbol_enum_type how;
398 case bfd_print_symbol_name_enum:
399 case bfd_print_symbol_type_enum:
400 fprintf(file,"%s", symbol->name);
402 case bfd_print_symbol_all_enum:
404 char *section_name = symbol->section == (asection *)NULL ?
405 "*abs" : symbol->section->name;
407 bfd_print_symbol_vandf((void *)file,symbol);
409 fprintf(file," %-5s %s",
417 The howto table is build using the top two bits of a reloc byte to
418 index into it. The bits are PCREL,WORD/LONG
420 static reloc_howto_type howto_table[]=
422 /* T rs size bsz pcrel bitpos abs ovr sf name partial inplace mask */
424 { 0, 0, 1, 16, false,0, true,true,0,"abs16",true,0x0000ffff},
425 { 0, 0, 2, 32, false,0, true,true,0,"abs32",true,0xffffffff},
426 { 0, 0, 1, 16, true,0, true,true,0,"pcrel16",true,0x0000ffff},
427 { 0, 0, 2, 32, true,0, true,true,0,"pcrel32",true,0xffffffff}
430 /* Read in all the section data and relocation stuff too */
431 static boolean oasys_slurp_section_data(abfd)
434 oasys_record_union_type record;
435 oasys_data_type *data = oasys_data(abfd);
438 oasys_per_section_type *per ;
442 /* Buy enough memory for all the section data and relocations */
443 for (s = abfd->sections; s != (asection *)NULL; s= s->next) {
444 per = oasys_per_section(s);
445 if (per->data != (bfd_byte*)NULL) return true;
446 per->data = (bfd_byte *) malloc(s->size);
447 obstack_init(&per->reloc_obstack);
448 per->reloc_tail_ptr = (oasys_reloc_type **)&(s->relocation);
451 if (data->first_data_record == 0) return true;
452 bfd_seek(abfd, data->first_data_record, SEEK_SET);
454 oasys_read_record(abfd, &record);
455 switch (record.header.type) {
456 case oasys_record_is_header_enum:
458 case oasys_record_is_data_enum:
461 uint8e_type *src = record.data.data;
462 uint8e_type *end_src = ((uint8e_type *)&record) +
463 record.header.length;
466 bfd_byte *dst_base_ptr ;
470 bfd_vma dst_offset = bfd_h_getlong(abfd, record.data.addr);
471 section = data->sections[record.data.relb & RELOCATION_SECT_BITS];
472 per = oasys_per_section(section);
473 dst_base_ptr = oasys_per_section(section)->data;
474 dst_ptr = oasys_per_section(section)->data +
477 while (src < end_src) {
478 uint32_type gap = end_src - src -1;
479 uint8e_type mod_byte = *src++;
481 if (mod_byte == 0 && gap >= 8) {
494 for (relbit = 1; count-- != 0 && gap != 0; gap --, relbit <<=1)
496 if (relbit & mod_byte)
498 uint8e_type reloc = *src;
499 /* This item needs to be relocated */
500 switch (reloc & RELOCATION_TYPE_BITS) {
501 case RELOCATION_TYPE_ABS:
505 case RELOCATION_TYPE_REL:
507 /* Relocate the item relative to the section */
508 oasys_reloc_type *r =
510 obstack_alloc(&per->reloc_obstack,
511 sizeof(oasys_reloc_type));
512 *(per->reloc_tail_ptr) = r;
513 per->reloc_tail_ptr = &r->next;
514 r->next= (oasys_reloc_type *)NULL;
515 /* Reference to undefined symbol */
517 /* There is no symbol */
519 /* Work out the howto */
521 data->sections[reloc & RELOCATION_SECT_BITS];
522 r->relent.addend = 0;
523 r->relent.address = dst_ptr - dst_base_ptr;
524 r->relent.howto = &howto_table[reloc>>6];
525 r->relent.sym_ptr_ptr = (asymbol **)NULL;
526 section->reloc_count++;
532 case RELOCATION_TYPE_UND:
534 oasys_reloc_type *r =
536 obstack_alloc(&per->reloc_obstack,
537 sizeof(oasys_reloc_type));
538 *(per->reloc_tail_ptr) = r;
539 per->reloc_tail_ptr = &r->next;
540 r->next= (oasys_reloc_type *)NULL;
541 /* Reference to undefined symbol */
543 /* Get symbol number */
544 r->symbol = (src[0]<<8) | src[1];
545 /* Work out the howto */
546 r->relent.section = (asection *)NULL;
547 r->relent.addend = 0;
548 r->relent.address = dst_ptr - dst_base_ptr;
549 r->relent.howto = &howto_table[reloc>>6];
550 r->relent.sym_ptr_ptr = (asymbol **)NULL;
552 section->reloc_count++;
556 case RELOCATION_TYPE_COM:
566 case oasys_record_is_local_enum:
567 case oasys_record_is_symbol_enum:
568 case oasys_record_is_section_enum:
583 oasys_new_section_hook (abfd, newsect)
587 newsect->used_by_bfd = (oasys_per_section_type *)
588 malloc(sizeof(oasys_per_section_type));
589 oasys_per_section( newsect)->data = (bfd_byte *)NULL;
590 oasys_per_section(newsect)->section = newsect;
591 oasys_per_section(newsect)->offset = 0;
597 oasys_get_reloc_upper_bound (abfd, asect)
601 oasys_slurp_section_data(abfd);
602 return (asect->reloc_count+1) * sizeof(arelent *);
606 oasys_get_section_contents (abfd, section, location, offset, count)
613 oasys_per_section_type *p = section->used_by_bfd;
614 oasys_slurp_section_data(abfd);
615 (void) memcpy(location, p->data + offset, count);
621 oasys_canonicalize_reloc (abfd, section, relptr, symbols)
627 oasys_reloc_type *src = (oasys_reloc_type *)(section->relocation);
628 while (src != (oasys_reloc_type *)NULL) {
629 if (src->relent.section == (asection *)NULL) {
630 src->relent.sym_ptr_ptr = symbols + src->symbol;
632 *relptr ++ = &src->relent;
635 *relptr = (arelent *)NULL;
636 return section->reloc_count;
640 oasys_set_arch_mach (abfd, arch, machine)
642 enum bfd_architecture arch;
643 unsigned long machine;
645 abfd->obj_arch = arch;
646 abfd->obj_machine = machine;
654 oasys_data_type *oasys =
655 (oasys_data_type *) malloc(sizeof(oasys_data_type));
656 oasys_data(abfd) = oasys;
657 if (oasys == (oasys_data_type *)NULL) {
658 bfd_error = no_memory;
672 init_for_output(abfd)
676 for (s = abfd->sections; s != (asection *)NULL; s = s->next) {
678 oasys_per_section(s)->data = (bfd_byte *)(malloc(s->size));
683 /** exec and core file sections */
685 /* set section contents is complicated with OASYS since the format is
686 * not a byte image, but a record stream.
689 oasys_set_section_contents (abfd, section, location, offset, count)
692 unsigned char *location;
696 if (oasys_per_section(section)->data == (bfd_byte *)NULL) {
697 init_for_output(abfd);
699 (void) memcpy(oasys_per_section(section)->data + offset, location, count);
706 /* Native-level interface to symbols. */
708 /* We read the symbols into a buffer, which is discarded when this
709 function exits. We read the strings into a buffer large enough to
710 hold them all plus all the cached symbol entries. */
713 oasys_make_empty_symbol (abfd)
717 oasys_symbol_type *new =
718 (oasys_symbol_type *)zalloc (sizeof (oasys_symbol_type));
719 new->symbol.the_bfd = abfd;
725 oasys_reclaim_symbol_table (abfd)
731 if (!bfd_get_symcount (abfd)) return;
733 for (section = abfd->sections; section != NULL; section = section->next)
734 if (section->relocation) {
735 free ((void *)section->relocation);
736 section->relocation = NULL;
737 section->reloc_count = 0;
740 bfd_get_symcount (abfd) = 0;
741 free ((void *)obj_aout_symbols (abfd));
742 obj_aout_symbols (abfd) = (aout_symbol_type *)NULL;
749 /* Obsbolete procedural interface; better to look at the cache directly */
751 /* User should have checked the file flags; perhaps we should return
752 BFD_NO_MORE_SYMBOLS if there are none? */
755 oasys_get_symcount_upper_bound (abfd)
759 /* In case we're doing an output file or something...? */
760 if (bfd_get_symcount (abfd)) return bfd_get_symcount (abfd);
762 return (exec_hdr (abfd)->a_syms) / (sizeof (struct nlist));
767 oasys_get_first_symbol (ignore_abfd)
774 oasys_get_next_symbol (abfd, oidx)
779 if (oidx == BFD_NO_MORE_SYMBOLS) return BFD_NO_MORE_SYMBOLS;
780 return ++oidx >= bfd_get_symcount (abfd) ? BFD_NO_MORE_SYMBOLS :
786 oasys_symbol_name (abfd, idx)
791 return (obj_aout_symbols (abfd) + idx)->symbol.name;
796 oasys_symbol_value (abfd, idx)
801 return (obj_aout_symbols (abfd) + idx)->symbol.value;
806 oasys_classify_symbol (abfd, idx)
811 aout_symbol_type *sym = obj_aout_symbols (abfd) + idx;
813 if ((sym->symbol.flags & BSF_FORT_COMM) != 0) return bfd_symclass_fcommon;
814 if ((sym->symbol.flags & BSF_GLOBAL) != 0) return bfd_symclass_global;
815 if ((sym->symbol.flags & BSF_DEBUGGING) != 0) return bfd_symclass_debugger;
816 if ((sym->symbol.flags & BSF_UNDEFINED) != 0) return bfd_symclass_undefined;
818 return bfd_symclass_unknown;
822 oasys_symbol_hasclass (abfd, idx, class)
828 aout_symbol_type *sym = obj_aout_symbols (abfd) + idx;
830 case bfd_symclass_fcommon:
831 return (sym->symbol.flags & BSF_FORT_COMM) ? true :false;
832 case bfd_symclass_global:
833 return (sym->symbol.flags & BSF_GLOBAL) ? true:false;
834 case bfd_symclass_debugger:
835 return (sym->symbol.flags & BSF_DEBUGGING) ? true:false;;
836 case bfd_symclass_undefined:
837 return (sym->symbol.flags & BSF_UNDEFINED) ? true:false;;
838 default: return false;
845 oasys_reclaim_reloc (ignore_abfd, section)
850 if (section->relocation) {
851 free (section->relocation);
852 section->relocation = NULL;
853 section->reloc_count = 0;
859 oasys_close_and_cleanup (abfd)
862 if (bfd_read_p (abfd) == false)
863 switch (abfd->format) {
865 if (!_bfd_write_archive_contents (abfd)) {
870 /* if (!oasys_write_object_contents (abfd)) */{
875 bfd_error = invalid_operation;
880 if (oasys_data(abfd) != (oasys_data_type *)NULL) {
881 /* FIXME MORE LEAKS */
889 oasys_openr_next_archived_file(arch, prev)
893 oasys_ar_data_type *ar = oasys_ar_data(arch);
894 oasys_module_info_type *p;
895 /* take the next one from the arch state, or reset */
896 if (prev == (bfd *)NULL) {
897 /* Reset the index - the first two entries are bogus*/
898 ar->module_index = 0;
901 p = ar->module + ar->module_index;
904 if (ar->module_index <= ar->module_count) {
905 if (p->abfd == (bfd *)NULL) {
906 p->abfd = _bfd_create_empty_archive_element_shell(arch);
907 p->abfd->origin = p->pos;
908 p->abfd->filename = p->name;
910 /* Fixup a pointer to this element for the member */
911 p->abfd->arelt_data = (void *)p;
916 bfd_error = no_more_archived_files;
922 oasys_find_nearest_line(abfd,
934 char **functionname_ptr;
935 unsigned int *line_ptr;
942 oasys_stat_arch_elt(abfd, buf)
946 oasys_module_info_type *mod = abfd->arelt_data;
947 if (mod == (oasys_module_info_type *)NULL) {
948 bfd_error = invalid_operation;
952 buf->st_size = mod->size;
962 bfd_target oasys_vec =
965 bfd_target_oasys_flavour_enum,
966 true, /* target byte order */
967 true, /* target headers byte order */
968 (HAS_RELOC | EXEC_P | /* object flags */
969 HAS_LINENO | HAS_DEBUG |
970 HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
971 (SEC_CODE|SEC_DATA|SEC_ROM|SEC_HAS_CONTENTS
972 |SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
973 0, /* valid reloc types */
974 ' ', /* ar_pad_char */
975 16, /* ar_max_namelen */
976 oasys_close_and_cleanup, /* _close_and_cleanup */
977 oasys_set_section_contents, /* bfd_set_section_contents */
978 oasys_get_section_contents,
979 oasys_new_section_hook, /* new_section_hook */
980 0, /* _core_file_failing_command */
981 0, /* _core_file_failing_signal */
982 0, /* _core_file_matches_ex...p */
984 0, /* bfd_slurp_bsd_armap, bfd_slurp_armap */
985 bfd_true, /* bfd_slurp_extended_name_table */
986 bfd_bsd_truncate_arname, /* bfd_truncate_arname */
988 oasys_get_symtab_upper_bound, /* get_symtab_upper_bound */
989 oasys_get_symtab, /* canonicalize_symtab */
990 0, /* oasys_reclaim_symbol_table, bfd_reclaim_symbol_table */
991 oasys_get_reloc_upper_bound, /* get_reloc_upper_bound */
992 oasys_canonicalize_reloc, /* bfd_canonicalize_reloc */
993 0, /* oasys_reclaim_reloc, bfd_reclaim_reloc */
994 0, /* oasys_get_symcount_upper_bound, bfd_get_symcount_upper_bound */
995 0, /* oasys_get_first_symbol, bfd_get_first_symbol */
996 0, /* oasys_get_next_symbol, bfd_get_next_symbol */
997 0, /* oasys_classify_symbol, bfd_classify_symbol */
998 0, /* oasys_symbol_hasclass, bfd_symbol_hasclass */
999 0, /* oasys_symbol_name, bfd_symbol_name */
1000 0, /* oasys_symbol_value, bfd_symbol_value */
1002 _do_getblong, _do_putblong, _do_getbshort, _do_putbshort, /* data */
1003 _do_getblong, _do_putblong, _do_getbshort, _do_putbshort, /* hdrs */
1006 oasys_object_p, /* bfd_check_format */
1013 _bfd_generic_mkarchive,
1016 oasys_make_empty_symbol,
1018 bfd_false, /* oasys_get_lineno,*/
1019 oasys_set_arch_mach, /* bfd_set_arch_mach,*/
1021 oasys_openr_next_archived_file,
1022 oasys_find_nearest_line, /* bfd_find_nearest_line */
1023 oasys_stat_arch_elt, /* bfd_stat_arch_elt */