1 /* bfd backend for oasys objects.
2 Copyright (C) 1990-1991 Free Software Foundation, Inc.
5 This file is part of BFD, the Binary File Descriptor library.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
23 #define UNDERSCORE_HACK 1
32 /* XXX - FIXME. offsetof belongs in the system-specific files in
34 /* Define offsetof for those systems which lack it */
37 #define offsetof(type, identifier) (size_t) &(((type *) 0)->identifier)
40 /* Read in all the section data and relocation stuff too */
41 PROTO(static boolean,oasys_slurp_section_data,(bfd *CONST abfd));
44 DEFUN(oasys_read_record,(abfd, record),
46 oasys_record_union_type *record)
49 bfd_read((PTR)record, 1, sizeof(record->header), abfd);
51 if ((size_t) record->header.length <= (size_t) sizeof (record->header))
53 bfd_read((PTR)(((char *)record )+ sizeof(record->header)),
54 1, record->header.length - sizeof(record->header),
58 DEFUN(oasys_string_length,(record),
59 oasys_record_union_type *record)
61 return record->header.length
62 - ((char *)record->symbol.name - (char *)record);
65 /*****************************************************************************/
69 Slurp the symbol table by reading in all the records at the start file
70 till we get to the first section record.
72 We'll sort the symbolss into two lists, defined and undefined. The
73 undefined symbols will be placed into the table according to their
76 We do this by placing all undefined symbols at the front of the table
77 moving in, and the defined symbols at the end of the table moving back.
82 DEFUN(oasys_slurp_symbol_table,(abfd),
85 oasys_record_union_type record;
86 oasys_data_type *data = oasys_data(abfd);
88 asymbol *dest_defined;
93 if (data->symbols != (asymbol *)NULL) {
96 /* Buy enough memory for all the symbols and all the names */
98 (asymbol *)bfd_alloc(abfd, sizeof(asymbol) * abfd->symcount);
99 #ifdef UNDERSCORE_HACK
100 /* buy 1 more char for each symbol to keep the underscore in*/
101 data->strings = bfd_alloc(abfd, data->symbol_string_length +
104 data->strings = bfd_alloc(abfd, data->symbol_string_length);
108 dest_defined = data->symbols + abfd->symcount -1;
110 string_ptr = data->strings;
111 bfd_seek(abfd, (file_ptr)0, SEEK_SET);
114 oasys_read_record(abfd, &record);
115 switch (record.header.type) {
116 case oasys_record_is_header_enum:
118 case oasys_record_is_local_enum:
119 case oasys_record_is_symbol_enum:
121 int flag = record.header.type == oasys_record_is_local_enum ?
122 (BSF_LOCAL) : (BSF_GLOBAL | BSF_EXPORT);
125 size_t length = oasys_string_length(&record);
126 switch (record.symbol.relb & RELOCATION_TYPE_BITS) {
127 case RELOCATION_TYPE_ABS:
128 dest = dest_defined--;
130 dest->flags = BSF_ABSOLUTE | flag;
132 case RELOCATION_TYPE_REL:
133 dest = dest_defined--;
135 oasys_data(abfd)->sections[record.symbol.relb &
136 RELOCATION_SECT_BITS];
137 if (record.header.type == oasys_record_is_local_enum)
139 dest->flags = BSF_LOCAL;
140 if (dest->section ==(asection *)(~0)) {
141 /* It seems that sometimes internal symbols are tied up, but
142 still get output, even though there is no
152 case RELOCATION_TYPE_UND:
153 dest = data->symbols + bfd_h_get_16(abfd, (bfd_byte *)&record.symbol.refno[0]);
154 dest->section = (asection *)NULL;
155 dest->flags = BSF_UNDEFINED;
157 case RELOCATION_TYPE_COM:
158 dest = dest_defined--;
159 dest->name = string_ptr;
160 dest->the_bfd = abfd;
162 dest->section = (asection *)NULL;
163 dest->flags = BSF_FORT_COMM;
166 dest = dest_defined--;
170 dest->name = string_ptr;
171 dest->the_bfd = abfd;
172 dest->udata = (PTR)NULL;
173 dest->value = bfd_h_get_32(abfd, (bfd_byte *)&record.symbol.value[0]);
175 #ifdef UNDERSCORE_HACK
176 if (record.symbol.name[0] != '_') {
181 memcpy(string_ptr, record.symbol.name, length);
184 string_ptr[length] =0;
185 string_ptr += length +1;
196 DEFUN(oasys_get_symtab_upper_bound,(abfd),
199 oasys_slurp_symbol_table (abfd);
201 return (abfd->symcount+1) * (sizeof (oasys_symbol_type *));
207 extern bfd_target oasys_vec;
210 DEFUN(oasys_get_symtab,(abfd, location),
215 unsigned int counter ;
216 if (oasys_slurp_symbol_table(abfd) == false) {
219 symbase = oasys_data(abfd)->symbols;
220 for (counter = 0; counter < abfd->symcount; counter++) {
221 *(location++) = symbase++;
224 return abfd->symcount;
227 /***********************************************************************
232 DEFUN(oasys_archive_p,(abfd),
235 oasys_archive_header_type header;
236 oasys_extarchive_header_type header_ext;
239 bfd_seek(abfd, (file_ptr) 0, false);
242 bfd_read((PTR)&header_ext, 1, sizeof(header_ext), abfd);
245 header.version = bfd_h_get_32(abfd, (bfd_byte *)header_ext.version);
246 header.mod_count = bfd_h_get_32(abfd, (bfd_byte *)header_ext.mod_count);
247 header.mod_tbl_offset = bfd_h_get_32(abfd, (bfd_byte *)header_ext.mod_tbl_offset);
248 header.sym_tbl_size = bfd_h_get_32(abfd, (bfd_byte *)header_ext.sym_tbl_size);
249 header.sym_count = bfd_h_get_32(abfd, (bfd_byte *)header_ext.sym_count);
250 header.sym_tbl_offset = bfd_h_get_32(abfd, (bfd_byte *)header_ext.sym_tbl_offset);
251 header.xref_count = bfd_h_get_32(abfd, (bfd_byte *)header_ext.xref_count);
252 header.xref_lst_offset = bfd_h_get_32(abfd, (bfd_byte *)header_ext.xref_lst_offset);
255 There isn't a magic number in an Oasys archive, so the best we
256 can do to verify reasnableness is to make sure that the values in
257 the header are too weird
260 if (header.version>10000 ||
261 header.mod_count>10000 ||
262 header.sym_count>100000 ||
263 header.xref_count > 100000) return (bfd_target *)NULL;
266 That all worked, lets buy the space for the header and read in
270 oasys_ar_data_type *ar =
271 (oasys_ar_data_type*) bfd_alloc(abfd, sizeof(oasys_ar_data_type));
274 oasys_module_info_type *module =
275 (oasys_module_info_type*)
276 bfd_alloc(abfd, sizeof(oasys_module_info_type) * header.mod_count);
279 oasys_module_table_type record;
284 ar->module_count = header.mod_count;
287 filepos = header.mod_tbl_offset;
288 for (i = 0; i < header.mod_count; i++) {
289 bfd_seek(abfd , filepos, SEEK_SET);
291 /* There are two ways of specifying the archive header */
294 oasys_extmodule_table_type_a_type record_ext;
295 bfd_read((PTR)&record_ext, 1, sizeof(record_ext), abfd);
297 record.mod_size = bfd_h_get_32(abfd, (bfd_byte *)record_ext.mod_size);
298 record.file_offset = bfd_h_get_32(abfd,
299 (bfd_byte *) record_ext.file_offset);
301 record.dep_count = bfd_h_get_32(abfd, (bfd_byte *)record_ext.dep_count);
302 record.depee_count = bfd_h_get_32(abfd,(bfd_byte *) record_ext.depee_count);
303 record.sect_count = bfd_h_get_32(abfd, (bfd_byte *) record_ext.sect_count);
306 module[i].name = bfd_alloc(abfd,33);
308 memcpy(module[i].name, record_ext.mod_name, 33);
311 record.dep_count * 4 +
312 record.depee_count * 4 +
313 record.sect_count * 8 + 187;
316 oasys_extmodule_table_type_b_type record_ext;
317 bfd_read((PTR)&record_ext, 1, sizeof(record_ext), abfd);
319 record.mod_size = bfd_h_get_32(abfd, (bfd_byte *) record_ext.mod_size);
320 record.file_offset = bfd_h_get_32(abfd,
321 (bfd_byte *)record_ext.file_offset);
323 record.dep_count = bfd_h_get_32(abfd, (bfd_byte *) record_ext.dep_count);
324 record.depee_count = bfd_h_get_32(abfd, (bfd_byte *) record_ext.depee_count);
325 record.sect_count = bfd_h_get_32(abfd, (bfd_byte *) record_ext.sect_count);
326 record.module_name_size = bfd_h_get_32(abfd, (bfd_byte *) record_ext.mod_name_length);
328 module[i].name = bfd_alloc(abfd,record.module_name_size + 1);
329 bfd_read((PTR)module[i].name, 1, record.module_name_size, abfd);
330 module[i].name[record.module_name_size] = 0;
333 record.dep_count * 4 +
334 record.module_name_size + 1;
339 module[i].size = record.mod_size;
340 module[i].pos = record.file_offset;
349 DEFUN(oasys_mkobject,(abfd),
354 (oasys_data_type*)bfd_alloc(abfd, sizeof(oasys_data_type)));
360 DEFUN(oasys_object_p,(abfd),
363 oasys_data_type *oasys;
364 oasys_data_type *save = oasys_data(abfd);
366 boolean had_usefull = false;
369 oasys_mkobject(abfd);
370 oasys = oasys_data(abfd);
371 memset((PTR)oasys->sections, 0xff, sizeof(oasys->sections));
373 /* Point to the start of the file */
374 bfd_seek(abfd, (file_ptr)0, SEEK_SET);
375 oasys->symbol_string_length = 0;
376 /* Inspect the records, but only keep the section info -
377 remember the size of the symbols
379 oasys->first_data_record = 0;
381 oasys_record_union_type record;
382 oasys_read_record(abfd, &record);
383 if ((size_t)record.header.length < (size_t)sizeof(record.header))
387 switch ((oasys_record_enum_type)(record.header.type)) {
388 case oasys_record_is_header_enum:
391 case oasys_record_is_symbol_enum:
392 case oasys_record_is_local_enum:
393 /* Count symbols and remember their size for a future malloc */
395 oasys->symbol_string_length += 1 + oasys_string_length(&record);
398 case oasys_record_is_section_enum:
402 unsigned int section_number;
403 if (record.section.header.length != sizeof(record.section))
407 buffer = bfd_alloc(abfd, 3);
408 section_number= record.section.relb & RELOCATION_SECT_BITS;
409 sprintf(buffer,"%u", section_number);
410 s = bfd_make_section(abfd,buffer);
411 oasys->sections[section_number] = s;
412 switch (record.section.relb & RELOCATION_TYPE_BITS) {
413 case RELOCATION_TYPE_ABS:
414 case RELOCATION_TYPE_REL:
416 case RELOCATION_TYPE_UND:
417 case RELOCATION_TYPE_COM:
421 s->size = bfd_h_get_32(abfd, (bfd_byte *) & record.section.value[0]) ;
422 s->vma = bfd_h_get_32(abfd, (bfd_byte *)&record.section.vma[0]);
427 case oasys_record_is_data_enum:
428 oasys->first_data_record = bfd_tell(abfd) - record.header.length;
429 case oasys_record_is_debug_enum:
430 case oasys_record_is_module_enum:
431 case oasys_record_is_named_section_enum:
432 case oasys_record_is_end_enum:
433 if (had_usefull == false) goto fail;
440 oasys->symbols = (asymbol *)NULL;
442 Oasys support several architectures, but I can't see a simple way
443 to discover which one is in a particular file - we'll guess
445 abfd->obj_arch = bfd_arch_m68k;
446 abfd->obj_machine =0;
447 if (abfd->symcount != 0) {
448 abfd->flags |= HAS_SYMS;
452 We don't know if a section has data until we've read it..
455 oasys_slurp_section_data(abfd);
461 (void) bfd_release(abfd, oasys);
462 set_tdata (abfd, save);
463 return (bfd_target *)NULL;
468 DEFUN(oasys_print_symbol,(ignore_abfd, afile, symbol, how),
472 bfd_print_symbol_enum_type how)
474 FILE *file = (FILE *)afile;
477 case bfd_print_symbol_name_enum:
478 case bfd_print_symbol_type_enum:
479 fprintf(file,"%s", symbol->name);
481 case bfd_print_symbol_all_enum:
483 CONST char *section_name = symbol->section == (asection *)NULL ?
484 "*abs" : symbol->section->name;
486 bfd_print_symbol_vandf((PTR)file,symbol);
488 fprintf(file," %-5s %s",
496 The howto table is build using the top two bits of a reloc byte to
497 index into it. The bits are PCREL,WORD/LONG
499 static reloc_howto_type howto_table[]=
502 HOWTO( 0, 0, 1, 16, false,0, true,true,0,"abs16",true,0x0000ffff, 0x0000ffff,false),
503 HOWTO( 0, 0, 2, 32, false,0, true,true,0,"abs32",true,0xffffffff, 0xffffffff,false),
504 HOWTO( 0, 0, 1, 16, true,0, true,true,0,"pcrel16",true,0x0000ffff, 0x0000ffff,false),
505 HOWTO( 0, 0, 2, 32, true,0, true,true,0,"pcrel32",true,0xffffffff, 0xffffffff,false)
508 /* Read in all the section data and relocation stuff too */
510 DEFUN(oasys_slurp_section_data,(abfd),
513 oasys_record_union_type record;
514 oasys_data_type *data = oasys_data(abfd);
517 oasys_per_section_type *per ;
521 /* See if the data has been slurped already .. */
522 for (s = abfd->sections; s != (asection *)NULL; s= s->next) {
523 per = oasys_per_section(s);
524 if (per->initialized == true)
528 if (data->first_data_record == 0) return true;
530 bfd_seek(abfd, data->first_data_record, SEEK_SET);
532 oasys_read_record(abfd, &record);
533 switch (record.header.type)
535 case oasys_record_is_header_enum:
537 case oasys_record_is_data_enum:
540 uint8e_type *src = record.data.data;
541 uint8e_type *end_src = ((uint8e_type *)&record) +
542 record.header.length;
545 bfd_byte *dst_base_ptr ;
548 data->sections[record.data.relb & RELOCATION_SECT_BITS];
550 per = oasys_per_section(section);
553 if (per->initialized == false)
555 per->data = (bfd_byte *) bfd_zalloc(abfd, section->size);
556 per->reloc_tail_ptr = (oasys_reloc_type **)&(section->relocation);
557 per->had_vma = false;
558 per->initialized = true;
559 section->reloc_count = 0;
560 section->flags = SEC_ALLOC;
563 dst_offset = bfd_h_get_32(abfd, record.data.addr) ;
564 if (per->had_vma == false) {
565 /* Take the first vma we see as the base */
567 section->vma = dst_offset;
572 dst_offset -= section->vma;
575 dst_base_ptr = oasys_per_section(section)->data;
576 dst_ptr = oasys_per_section(section)->data +
580 section->flags |= SEC_LOAD | SEC_HAS_CONTENTS;
582 while (src < end_src) {
583 uint8e_type mod_byte = *src++;
584 uint32_type gap = end_src - src;
587 if (mod_byte == 0 && gap >= 8) {
600 for (relbit = 1; count-- != 0 && src < end_src; relbit <<=1)
602 if (relbit & mod_byte)
604 uint8e_type reloc = *src;
605 /* This item needs to be relocated */
606 switch (reloc & RELOCATION_TYPE_BITS) {
607 case RELOCATION_TYPE_ABS:
611 case RELOCATION_TYPE_REL:
613 /* Relocate the item relative to the section */
614 oasys_reloc_type *r =
617 sizeof(oasys_reloc_type));
618 *(per->reloc_tail_ptr) = r;
619 per->reloc_tail_ptr = &r->next;
620 r->next= (oasys_reloc_type *)NULL;
621 /* Reference to undefined symbol */
623 /* There is no symbol */
625 /* Work out the howto */
627 data->sections[reloc & RELOCATION_SECT_BITS];
628 r->relent.addend = - r->relent.section->vma;
629 r->relent.address = dst_ptr - dst_base_ptr;
630 r->relent.howto = &howto_table[reloc>>6];
631 r->relent.sym_ptr_ptr = (asymbol **)NULL;
632 section->reloc_count++;
634 /* Fake up the data to look like it's got the -ve pc in it, this makes
635 it much easier to convert into other formats. This is done by
638 if (r->relent.howto->pc_relative == true) {
639 r->relent.addend -= dst_ptr - dst_base_ptr;
647 case RELOCATION_TYPE_UND:
649 oasys_reloc_type *r =
652 sizeof(oasys_reloc_type));
653 *(per->reloc_tail_ptr) = r;
654 per->reloc_tail_ptr = &r->next;
655 r->next= (oasys_reloc_type *)NULL;
656 /* Reference to undefined symbol */
658 /* Get symbol number */
659 r->symbol = (src[0]<<8) | src[1];
660 /* Work out the howto */
661 r->relent.section = (asection *)NULL;
662 r->relent.addend = 0;
663 r->relent.address = dst_ptr - dst_base_ptr;
664 r->relent.howto = &howto_table[reloc>>6];
665 r->relent.sym_ptr_ptr = (asymbol **)NULL;
666 section->reloc_count++;
669 /* Fake up the data to look like it's got the -ve pc in it, this makes
670 it much easier to convert into other formats. This is done by
673 if (r->relent.howto->pc_relative == true) {
674 r->relent.addend -= dst_ptr - dst_base_ptr;
681 case RELOCATION_TYPE_COM:
691 case oasys_record_is_local_enum:
692 case oasys_record_is_symbol_enum:
693 case oasys_record_is_section_enum:
706 bfd_error_vector_type bfd_error_vector;
709 DEFUN(oasys_new_section_hook,(abfd, newsect),
713 newsect->used_by_bfd = (PTR)
714 bfd_alloc(abfd, sizeof(oasys_per_section_type));
715 oasys_per_section( newsect)->data = (bfd_byte *)NULL;
716 oasys_per_section(newsect)->section = newsect;
717 oasys_per_section(newsect)->offset = 0;
718 oasys_per_section(newsect)->initialized = false;
719 newsect->alignment_power = 1;
720 /* Turn the section string into an index */
722 sscanf(newsect->name,"%u", &newsect->target_index);
729 DEFUN(oasys_get_reloc_upper_bound, (abfd, asect),
733 oasys_slurp_section_data(abfd);
734 return (asect->reloc_count+1) * sizeof(arelent *);
738 DEFUN(oasys_get_section_contents,(abfd, section, location, offset, count),
745 oasys_per_section_type *p = (oasys_per_section_type *) section->used_by_bfd;
746 oasys_slurp_section_data(abfd);
747 if (p->initialized == false)
749 (void) memset(location, 0, (int)count);
753 (void) memcpy(location,(PTR)( p->data + offset), (int)count);
760 DEFUN(oasys_canonicalize_reloc,(ignore_abfd, section, relptr, symbols),
766 unsigned int reloc_count = 0;
767 oasys_reloc_type *src = (oasys_reloc_type *)(section->relocation);
768 while (src != (oasys_reloc_type *)NULL) {
769 if (src->relent.section == (asection *)NULL)
771 src->relent.sym_ptr_ptr = symbols + src->symbol;
773 *relptr ++ = &src->relent;
777 *relptr = (arelent *)NULL;
778 return section->reloc_count = reloc_count;
783 DEFUN(oasys_set_arch_mach, (abfd, arch, machine),
785 enum bfd_architecture arch AND
786 unsigned long machine)
788 abfd->obj_arch = arch;
789 abfd->obj_machine = machine;
798 /* Calculate the checksum and write one record */
800 DEFUN(oasys_write_record,(abfd, type, record, size),
802 CONST oasys_record_enum_type type AND
803 oasys_record_union_type *record AND
809 record->header.length = size;
810 record->header.type = type;
811 record->header.check_sum = 0;
812 record->header.fill = 0;
813 ptr = &record->pad[0];
815 for (i = 0; i < size; i++) {
818 record->header.check_sum = 0xff & (- checksum);
819 bfd_write((PTR)record, 1, size, abfd);
823 /* Write out all the symbols */
825 DEFUN(oasys_write_syms, (abfd),
829 asymbol **generic = bfd_get_outsymbols(abfd);
830 unsigned int index = 0;
831 for (count = 0; count < bfd_get_symcount(abfd); count++) {
833 oasys_symbol_record_type symbol;
834 asymbol * CONST g = generic[count];
836 CONST char *src = g->name;
837 char *dst = symbol.name;
840 if (g->flags & BSF_FORT_COMM) {
841 symbol.relb = RELOCATION_TYPE_COM;
842 bfd_h_put_16(abfd, index, (uint8e_type *)(&symbol.refno[0]));
845 else if (g->flags & BSF_ABSOLUTE) {
846 symbol.relb = RELOCATION_TYPE_ABS;
847 bfd_h_put_16(abfd, 0, (uint8e_type *)(&symbol.refno[0]));
850 else if (g->flags & BSF_UNDEFINED) {
851 symbol.relb = RELOCATION_TYPE_UND ;
852 bfd_h_put_16(abfd, index, (uint8e_type *)(&symbol.refno[0]));
853 /* Overload the value field with the output index number */
856 else if (g->flags & BSF_DEBUGGING) {
861 if (g->section == (asection *)NULL) {
862 /* Sometime, the oasys tools give out a symbol with illegal
863 bits in it, we'll output it in the same broken way */
865 symbol.relb = RELOCATION_TYPE_REL | 0;
868 symbol.relb = RELOCATION_TYPE_REL |g->section->output_section->target_index;
870 bfd_h_put_16(abfd, 0, (uint8e_type *)(&symbol.refno[0]));
877 bfd_h_put_32(abfd, g->value, (bfd_byte*) symbol.value);
880 if (g->flags & BSF_LOCAL) {
881 oasys_write_record(abfd,
882 oasys_record_is_local_enum,
883 (oasys_record_union_type *) &symbol,
884 offsetof(oasys_symbol_record_type, name[0]) + l);
887 oasys_write_record(abfd,
888 oasys_record_is_symbol_enum,
889 (oasys_record_union_type *) &symbol,
890 offsetof(oasys_symbol_record_type, name[0]) + l);
897 /* Write a section header for each section */
899 DEFUN(oasys_write_sections, (abfd),
903 static oasys_section_record_type out = {0};
905 for (s = abfd->sections; s != (asection *)NULL; s = s->next) {
906 if (!isdigit(s->name[0]))
908 bfd_error_vector.nonrepresentable_section(abfd,
911 out.relb = RELOCATION_TYPE_REL | s->target_index;
912 bfd_h_put_32(abfd, s->size, (bfd_byte *) out.value);
913 bfd_h_put_32(abfd, s->vma, (bfd_byte *) out.vma);
915 oasys_write_record(abfd,
916 oasys_record_is_section_enum,
917 (oasys_record_union_type *) &out,
923 DEFUN(oasys_write_header, (abfd),
926 /* Create and write the header */
927 oasys_header_record_type r;
928 size_t length = strlen(abfd->filename);
929 if (length > (size_t)sizeof(r.module_name)) {
930 length = sizeof(r.module_name);
933 (void)memcpy(r.module_name,
936 (void)memset(r.module_name + length,
938 sizeof(r.module_name) - length);
940 r.version_number = OASYS_VERSION_NUMBER;
941 r.rev_number = OASYS_REV_NUMBER;
942 oasys_write_record(abfd,
943 oasys_record_is_header_enum,
944 (oasys_record_union_type *)&r,
945 offsetof(oasys_header_record_type, description[0]));
952 DEFUN(oasys_write_end,(abfd),
955 oasys_end_record_type end;
956 uint8e_type null = 0;
957 end.relb = RELOCATION_TYPE_ABS;
958 bfd_h_put_32(abfd, abfd->start_address, (bfd_byte *)end.entry);
959 bfd_h_put_16(abfd, 0, (bfd_byte *)end.fill);
961 oasys_write_record(abfd,
962 oasys_record_is_end_enum,
963 (oasys_record_union_type *)&end,
965 bfd_write((PTR)&null, 1, 1, abfd);
973 arelent *a = *((arelent **)ap);
974 arelent *b = *((arelent **)bp);
975 return a->address - b->address;
983 DEFUN(oasys_write_data, (abfd),
987 for (s = abfd->sections; s != (asection *)NULL; s = s->next) {
988 if (s->flags & SEC_LOAD) {
989 uint8e_type *raw_data = oasys_per_section(s)->data;
990 oasys_data_record_type processed_data;
991 bfd_size_type current_byte_index = 0;
992 unsigned int relocs_to_go = s->reloc_count;
993 arelent **p = s->orelocation;
994 if (s->reloc_count != 0) {
995 /* Sort the reloc records so it's easy to insert the relocs into the
998 qsort(s->orelocation,
1003 current_byte_index = 0;
1004 processed_data.relb = s->target_index | RELOCATION_TYPE_REL;
1006 while (current_byte_index < s->size)
1008 /* Scan forwards by eight bytes or however much is left and see if
1009 there are any relocations going on */
1010 uint8e_type *mod = &processed_data.data[0];
1011 uint8e_type *dst = &processed_data.data[1];
1014 unsigned int long_length = 128;
1017 bfd_h_put_32(abfd, s->vma + current_byte_index, processed_data.addr);
1018 if ((size_t)(long_length + current_byte_index) > (size_t)(s->size)) {
1019 long_length = s->size - current_byte_index;
1021 while (long_length > 0 && (dst - (uint8e_type*)&processed_data < 128)) {
1023 unsigned int length = long_length;
1028 for (i = 0; i < length; i++) {
1029 if (relocs_to_go != 0) {
1031 reloc_howto_type *CONST how=r->howto;
1032 /* There is a relocation, is it for this byte ? */
1033 if (r->address == current_byte_index) {
1034 uint8e_type rel_byte;
1039 if(how->pc_relative) {
1042 /* Also patch the raw data so that it doesn't have
1043 the -ve stuff any more */
1044 if (how->size != 2) {
1046 bfd_get_16(abfd,raw_data) +
1047 current_byte_index, raw_data);
1052 bfd_get_32(abfd,raw_data) +
1053 current_byte_index, raw_data);
1059 if (how->size ==2) {
1063 /* Is this a section relative relocation, or a symbol
1064 relative relocation ? */
1065 if (r->section != (asection*)NULL)
1067 /* The relent has a section attached, so it must be section
1069 rel_byte |= RELOCATION_TYPE_REL;
1070 rel_byte |= r->section->output_section->target_index;
1075 asymbol *p = *(r->sym_ptr_ptr);
1077 /* If this symbol has a section attached, then it
1078 has already been resolved. Change from a symbol
1079 ref to a section ref */
1080 if(p->section != (asection *)NULL) {
1081 rel_byte |= RELOCATION_TYPE_REL;
1083 p->section->output_section->target_index;
1087 rel_byte |= RELOCATION_TYPE_UND;
1091 /* Next two bytes are a symbol index - we can get
1092 this from the symbol value which has been zapped
1093 into the symbol index in the table when the
1094 symbol table was written
1096 *dst++ = p->value >> 8;
1103 /* If this is coming from an unloadable section then copy
1105 if (raw_data == (uint8e_type *)NULL) {
1109 *dst++ = *raw_data++;
1111 current_byte_index++;
1114 long_length -= length;
1117 oasys_write_record(abfd,
1118 oasys_record_is_data_enum,
1119 (oasys_record_union_type *)&processed_data,
1120 dst - (uint8e_type*)&processed_data);
1127 DEFUN(oasys_write_object_contents, (abfd),
1130 oasys_write_header(abfd);
1131 oasys_write_syms(abfd);
1132 oasys_write_sections(abfd);
1133 oasys_write_data(abfd);
1134 oasys_write_end(abfd);
1141 /** exec and core file sections */
1143 /* set section contents is complicated with OASYS since the format is
1144 * not a byte image, but a record stream.
1147 DEFUN(oasys_set_section_contents,(abfd, section, location, offset, count),
1152 bfd_size_type count)
1155 if (oasys_per_section(section)->data == (bfd_byte *)NULL )
1157 oasys_per_section(section)->data =
1158 (bfd_byte *)(bfd_alloc(abfd,section->size));
1160 (void) memcpy((PTR)(oasys_per_section(section)->data + offset),
1169 /* Native-level interface to symbols. */
1171 /* We read the symbols into a buffer, which is discarded when this
1172 function exits. We read the strings into a buffer large enough to
1173 hold them all plus all the cached symbol entries. */
1176 DEFUN(oasys_make_empty_symbol,(abfd),
1180 oasys_symbol_type *new =
1181 (oasys_symbol_type *)bfd_zalloc (abfd, sizeof (oasys_symbol_type));
1182 new->symbol.the_bfd = abfd;
1183 return &new->symbol;
1190 /* User should have checked the file flags; perhaps we should return
1191 BFD_NO_MORE_SYMBOLS if there are none? */
1194 oasys_openr_next_archived_file(arch, prev)
1198 oasys_ar_data_type *ar = oasys_ar_data(arch);
1199 oasys_module_info_type *p;
1200 /* take the next one from the arch state, or reset */
1201 if (prev == (bfd *)NULL) {
1202 /* Reset the index - the first two entries are bogus*/
1203 ar->module_index = 0;
1206 p = ar->module + ar->module_index;
1209 if (ar->module_index <= ar->module_count) {
1210 if (p->abfd == (bfd *)NULL) {
1211 p->abfd = _bfd_create_empty_archive_element_shell(arch);
1212 p->abfd->origin = p->pos;
1213 p->abfd->filename = p->name;
1215 /* Fixup a pointer to this element for the member */
1216 p->abfd->arelt_data = (PTR)p;
1221 bfd_error = no_more_archived_files;
1227 oasys_find_nearest_line(abfd,
1238 char **filename_ptr;
1239 char **functionname_ptr;
1240 unsigned int *line_ptr;
1247 DEFUN(oasys_generic_stat_arch_elt,(abfd, buf),
1251 oasys_module_info_type *mod = (oasys_module_info_type *) abfd->arelt_data;
1252 if (mod == (oasys_module_info_type *)NULL) {
1253 bfd_error = invalid_operation;
1257 buf->st_size = mod->size;
1258 buf->st_mode = 0666;
1264 DEFUN(oasys_sizeof_headers,(abfd, exec),
1271 #define oasys_core_file_failing_command (char *(*)())(bfd_nullvoidptr)
1272 #define oasys_core_file_failing_signal (int (*)())bfd_0
1273 #define oasys_core_file_matches_executable_p 0
1274 #define oasys_slurp_armap bfd_true
1275 #define oasys_slurp_extended_name_table bfd_true
1276 #define oasys_truncate_arname (void (*)())bfd_nullvoidptr
1277 #define oasys_write_armap 0
1278 #define oasys_get_lineno (struct lineno_cache_entry *(*)())bfd_nullvoidptr
1279 #define oasys_close_and_cleanup bfd_generic_close_and_cleanup
1281 #define oasys_bfd_debug_info_start bfd_void
1282 #define oasys_bfd_debug_info_end bfd_void
1283 #define oasys_bfd_debug_info_accumulate (FOO(void, (*), (bfd *, asection *)))bfd_void
1287 bfd_target oasys_vec =
1290 bfd_target_oasys_flavour_enum,
1291 true, /* target byte order */
1292 true, /* target headers byte order */
1293 (HAS_RELOC | EXEC_P | /* object flags */
1294 HAS_LINENO | HAS_DEBUG |
1295 HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
1296 (SEC_CODE|SEC_DATA|SEC_ROM|SEC_HAS_CONTENTS
1297 |SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
1298 ' ', /* ar_pad_char */
1299 16, /* ar_max_namelen */
1300 1, /* minimum alignment */
1301 _do_getb64, _do_putb64, _do_getb32, _do_putb32, _do_getb16, _do_putb16, /* data */
1302 _do_getb64, _do_putb64, _do_getb32, _do_putb32, _do_getb16, _do_putb16, /* hdrs */
1305 oasys_object_p, /* bfd_check_format */
1309 { /* bfd_set_format */
1312 _bfd_generic_mkarchive,
1315 { /* bfd_write_contents */
1317 oasys_write_object_contents,
1318 _bfd_write_archive_contents,