1 /* bfd backend for oasys objects.
2 Copyright (C) 1990-1991 Free Software Foundation, Inc.
3 Written by Steve Chamberlain of Cygnus Support <steve@cygnus.com>.
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
33 /* Read in all the section data and relocation stuff too */
34 PROTO(static boolean,oasys_slurp_section_data,(bfd *CONST abfd));
37 DEFUN(oasys_read_record,(abfd, record),
39 oasys_record_union_type *record)
42 bfd_read((PTR)record, 1, sizeof(record->header), abfd);
44 if ((size_t) record->header.length <= (size_t) sizeof (record->header))
46 bfd_read((PTR)(((char *)record )+ sizeof(record->header)),
47 1, record->header.length - sizeof(record->header),
51 DEFUN(oasys_string_length,(record),
52 oasys_record_union_type *record)
54 return record->header.length
55 - ((char *)record->symbol.name - (char *)record);
58 /*****************************************************************************/
62 Slurp the symbol table by reading in all the records at the start file
63 till we get to the first section record.
65 We'll sort the symbolss into two lists, defined and undefined. The
66 undefined symbols will be placed into the table according to their
69 We do this by placing all undefined symbols at the front of the table
70 moving in, and the defined symbols at the end of the table moving back.
75 DEFUN(oasys_slurp_symbol_table,(abfd),
78 oasys_record_union_type record;
79 oasys_data_type *data = oasys_data(abfd);
81 asymbol *dest_defined;
86 if (data->symbols != (asymbol *)NULL) {
89 /* Buy enough memory for all the symbols and all the names */
91 (asymbol *)bfd_alloc(abfd, sizeof(asymbol) * abfd->symcount);
92 #ifdef UNDERSCORE_HACK
93 /* buy 1 more char for each symbol to keep the underscore in*/
94 data->strings = bfd_alloc(abfd, data->symbol_string_length +
97 data->strings = bfd_alloc(abfd, data->symbol_string_length);
101 dest_defined = data->symbols + abfd->symcount -1;
103 string_ptr = data->strings;
104 bfd_seek(abfd, (file_ptr)0, SEEK_SET);
107 oasys_read_record(abfd, &record);
108 switch (record.header.type) {
109 case oasys_record_is_header_enum:
111 case oasys_record_is_local_enum:
112 case oasys_record_is_symbol_enum:
114 int flag = record.header.type == oasys_record_is_local_enum ?
115 (BSF_LOCAL) : (BSF_GLOBAL | BSF_EXPORT);
118 size_t length = oasys_string_length(&record);
119 switch (record.symbol.relb & RELOCATION_TYPE_BITS) {
120 case RELOCATION_TYPE_ABS:
121 dest = dest_defined--;
123 dest->flags = BSF_ABSOLUTE | flag;
125 case RELOCATION_TYPE_REL:
126 dest = dest_defined--;
128 oasys_data(abfd)->sections[record.symbol.relb &
129 RELOCATION_SECT_BITS];
130 if (record.header.type == oasys_record_is_local_enum)
132 dest->flags = BSF_LOCAL;
133 if (dest->section ==(asection *)(~0)) {
134 /* It seems that sometimes internal symbols are tied up, but
135 still get output, even though there is no
145 case RELOCATION_TYPE_UND:
146 dest = data->symbols + bfd_h_get_16(abfd, (bfd_byte *)&record.symbol.refno[0]);
147 dest->section = (asection *)NULL;
148 dest->flags = BSF_UNDEFINED;
150 case RELOCATION_TYPE_COM:
151 dest = dest_defined--;
152 dest->name = string_ptr;
153 dest->the_bfd = abfd;
155 dest->section = (asection *)NULL;
156 dest->flags = BSF_FORT_COMM;
159 dest = dest_defined--;
163 dest->name = string_ptr;
164 dest->the_bfd = abfd;
165 dest->udata = (PTR)NULL;
166 dest->value = bfd_h_get_32(abfd, (bfd_byte *)&record.symbol.value[0]);
168 #ifdef UNDERSCORE_HACK
169 if (record.symbol.name[0] != '_') {
174 memcpy(string_ptr, record.symbol.name, length);
177 string_ptr[length] =0;
178 string_ptr += length +1;
189 DEFUN(oasys_get_symtab_upper_bound,(abfd),
192 oasys_slurp_symbol_table (abfd);
194 return (abfd->symcount+1) * (sizeof (oasys_symbol_type *));
200 extern bfd_target oasys_vec;
203 DEFUN(oasys_get_symtab,(abfd, location),
208 unsigned int counter ;
209 if (oasys_slurp_symbol_table(abfd) == false) {
212 symbase = oasys_data(abfd)->symbols;
213 for (counter = 0; counter < abfd->symcount; counter++) {
214 *(location++) = symbase++;
217 return abfd->symcount;
220 /***********************************************************************
225 DEFUN(oasys_archive_p,(abfd),
228 oasys_archive_header_type header;
229 oasys_extarchive_header_type header_ext;
232 bfd_seek(abfd, (file_ptr) 0, false);
235 bfd_read((PTR)&header_ext, 1, sizeof(header_ext), abfd);
238 header.version = bfd_h_get_32(abfd, (bfd_byte *)header_ext.version);
239 header.mod_count = bfd_h_get_32(abfd, (bfd_byte *)header_ext.mod_count);
240 header.mod_tbl_offset = bfd_h_get_32(abfd, (bfd_byte *)header_ext.mod_tbl_offset);
241 header.sym_tbl_size = bfd_h_get_32(abfd, (bfd_byte *)header_ext.sym_tbl_size);
242 header.sym_count = bfd_h_get_32(abfd, (bfd_byte *)header_ext.sym_count);
243 header.sym_tbl_offset = bfd_h_get_32(abfd, (bfd_byte *)header_ext.sym_tbl_offset);
244 header.xref_count = bfd_h_get_32(abfd, (bfd_byte *)header_ext.xref_count);
245 header.xref_lst_offset = bfd_h_get_32(abfd, (bfd_byte *)header_ext.xref_lst_offset);
248 There isn't a magic number in an Oasys archive, so the best we
249 can do to verify reasnableness is to make sure that the values in
250 the header are too weird
253 if (header.version>10000 ||
254 header.mod_count>10000 ||
255 header.sym_count>100000 ||
256 header.xref_count > 100000) return (bfd_target *)NULL;
259 That all worked, lets buy the space for the header and read in
263 oasys_ar_data_type *ar =
264 (oasys_ar_data_type*) bfd_alloc(abfd, sizeof(oasys_ar_data_type));
267 oasys_module_info_type *module =
268 (oasys_module_info_type*)
269 bfd_alloc(abfd, sizeof(oasys_module_info_type) * header.mod_count);
272 oasys_module_table_type record;
277 ar->module_count = header.mod_count;
280 filepos = header.mod_tbl_offset;
281 for (i = 0; i < header.mod_count; i++) {
282 bfd_seek(abfd , filepos, SEEK_SET);
284 /* There are two ways of specifying the archive header */
287 oasys_extmodule_table_type_a_type record_ext;
288 bfd_read((PTR)&record_ext, 1, sizeof(record_ext), abfd);
290 record.mod_size = bfd_h_get_32(abfd, (bfd_byte *)record_ext.mod_size);
291 record.file_offset = bfd_h_get_32(abfd,
292 (bfd_byte *) record_ext.file_offset);
294 record.dep_count = bfd_h_get_32(abfd, (bfd_byte *)record_ext.dep_count);
295 record.depee_count = bfd_h_get_32(abfd,(bfd_byte *) record_ext.depee_count);
296 record.sect_count = bfd_h_get_32(abfd, (bfd_byte *) record_ext.sect_count);
299 module[i].name = bfd_alloc(abfd,33);
301 memcpy(module[i].name, record_ext.mod_name, 33);
304 record.dep_count * 4 +
305 record.depee_count * 4 +
306 record.sect_count * 8 + 187;
309 oasys_extmodule_table_type_b_type record_ext;
310 bfd_read((PTR)&record_ext, 1, sizeof(record_ext), abfd);
312 record.mod_size = bfd_h_get_32(abfd, (bfd_byte *) record_ext.mod_size);
313 record.file_offset = bfd_h_get_32(abfd,
314 (bfd_byte *)record_ext.file_offset);
316 record.dep_count = bfd_h_get_32(abfd, (bfd_byte *) record_ext.dep_count);
317 record.depee_count = bfd_h_get_32(abfd, (bfd_byte *) record_ext.depee_count);
318 record.sect_count = bfd_h_get_32(abfd, (bfd_byte *) record_ext.sect_count);
319 record.module_name_size = bfd_h_get_32(abfd, (bfd_byte *) record_ext.mod_name_length);
321 module[i].name = bfd_alloc(abfd,record.module_name_size + 1);
322 bfd_read((PTR)module[i].name, 1, record.module_name_size, abfd);
323 module[i].name[record.module_name_size] = 0;
326 record.dep_count * 4 +
327 record.module_name_size + 1;
332 module[i].size = record.mod_size;
333 module[i].pos = record.file_offset;
342 DEFUN(oasys_mkobject,(abfd),
345 oasys_data_type *oasys;
348 (oasys_data_type*)bfd_alloc(abfd, sizeof(oasys_data_type)));
349 oasys = oasys_data(abfd);
355 DEFUN(oasys_object_p,(abfd),
358 oasys_data_type *oasys;
359 oasys_data_type *save = oasys_data(abfd);
361 boolean had_usefull = false;
364 oasys_mkobject(abfd);
365 oasys = oasys_data(abfd);
366 memset((PTR)oasys->sections, 0xff, sizeof(oasys->sections));
368 /* Point to the start of the file */
369 bfd_seek(abfd, (file_ptr)0, SEEK_SET);
370 oasys->symbol_string_length = 0;
371 /* Inspect the records, but only keep the section info -
372 remember the size of the symbols
374 oasys->first_data_record = 0;
376 oasys_record_union_type record;
377 oasys_read_record(abfd, &record);
378 if ((size_t)record.header.length < (size_t)sizeof(record.header))
382 switch ((oasys_record_enum_type)(record.header.type)) {
383 case oasys_record_is_header_enum:
386 case oasys_record_is_symbol_enum:
387 case oasys_record_is_local_enum:
388 /* Count symbols and remember their size for a future malloc */
390 oasys->symbol_string_length += 1 + oasys_string_length(&record);
393 case oasys_record_is_section_enum:
397 unsigned int section_number;
398 if (record.section.header.length != sizeof(record.section))
402 buffer = bfd_alloc(abfd, 3);
403 section_number= record.section.relb & RELOCATION_SECT_BITS;
404 sprintf(buffer,"%u", section_number);
405 s = bfd_make_section(abfd,buffer);
406 oasys->sections[section_number] = s;
407 switch (record.section.relb & RELOCATION_TYPE_BITS) {
408 case RELOCATION_TYPE_ABS:
409 case RELOCATION_TYPE_REL:
411 case RELOCATION_TYPE_UND:
412 case RELOCATION_TYPE_COM:
416 s->size = bfd_h_get_32(abfd, (bfd_byte *) & record.section.value[0]) ;
417 s->vma = bfd_h_get_32(abfd, (bfd_byte *)&record.section.vma[0]);
422 case oasys_record_is_data_enum:
423 oasys->first_data_record = bfd_tell(abfd) - record.header.length;
424 case oasys_record_is_debug_enum:
425 case oasys_record_is_module_enum:
426 case oasys_record_is_named_section_enum:
427 case oasys_record_is_end_enum:
428 if (had_usefull == false) goto fail;
435 oasys->symbols = (asymbol *)NULL;
437 Oasys support several architectures, but I can't see a simple way
438 to discover which one is in a particular file - we'll guess
440 abfd->obj_arch = bfd_arch_m68k;
441 abfd->obj_machine =0;
442 if (abfd->symcount != 0) {
443 abfd->flags |= HAS_SYMS;
447 We don't know if a section has data until we've read it..
450 oasys_slurp_section_data(abfd);
456 (void) bfd_release(abfd, oasys);
457 set_tdata (abfd, save);
458 return (bfd_target *)NULL;
463 DEFUN(oasys_print_symbol,(ignore_abfd, afile, symbol, how),
467 bfd_print_symbol_enum_type how)
469 FILE *file = (FILE *)afile;
472 case bfd_print_symbol_name_enum:
473 case bfd_print_symbol_type_enum:
474 fprintf(file,"%s", symbol->name);
476 case bfd_print_symbol_all_enum:
478 CONST char *section_name = symbol->section == (asection *)NULL ?
479 "*abs" : symbol->section->name;
481 bfd_print_symbol_vandf((PTR)file,symbol);
483 fprintf(file," %-5s %s",
491 The howto table is build using the top two bits of a reloc byte to
492 index into it. The bits are PCREL,WORD/LONG
494 static reloc_howto_type howto_table[]=
497 HOWTO( 0, 0, 1, 16, false,0, true,true,0,"abs16",true,0x0000ffff, 0x0000ffff,false),
498 HOWTO( 0, 0, 2, 32, false,0, true,true,0,"abs32",true,0xffffffff, 0xffffffff,false),
499 HOWTO( 0, 0, 1, 16, true,0, true,true,0,"pcrel16",true,0x0000ffff, 0x0000ffff,false),
500 HOWTO( 0, 0, 2, 32, true,0, true,true,0,"pcrel32",true,0xffffffff, 0xffffffff,false)
503 /* Read in all the section data and relocation stuff too */
505 DEFUN(oasys_slurp_section_data,(abfd),
508 oasys_record_union_type record;
509 oasys_data_type *data = oasys_data(abfd);
512 oasys_per_section_type *per ;
516 /* See if the data has been slurped already .. */
517 for (s = abfd->sections; s != (asection *)NULL; s= s->next) {
518 per = oasys_per_section(s);
519 if (per->initialized == true)
523 if (data->first_data_record == 0) return true;
525 bfd_seek(abfd, data->first_data_record, SEEK_SET);
527 oasys_read_record(abfd, &record);
528 switch (record.header.type)
530 case oasys_record_is_header_enum:
532 case oasys_record_is_data_enum:
535 uint8e_type *src = record.data.data;
536 uint8e_type *end_src = ((uint8e_type *)&record) +
537 record.header.length;
540 bfd_byte *dst_base_ptr ;
543 data->sections[record.data.relb & RELOCATION_SECT_BITS];
545 per = oasys_per_section(section);
548 if (per->initialized == false)
550 per->data = (bfd_byte *) bfd_zalloc(abfd, section->size);
551 per->reloc_tail_ptr = (oasys_reloc_type **)&(section->relocation);
552 per->had_vma = false;
553 per->initialized = true;
554 section->reloc_count = 0;
555 section->flags = SEC_ALLOC;
558 dst_offset = bfd_h_get_32(abfd, record.data.addr) ;
559 if (per->had_vma == false) {
560 /* Take the first vma we see as the base */
562 section->vma = dst_offset;
567 dst_offset -= section->vma;
570 dst_base_ptr = oasys_per_section(section)->data;
571 dst_ptr = oasys_per_section(section)->data +
575 section->flags |= SEC_LOAD | SEC_HAS_CONTENTS;
577 while (src < end_src) {
578 uint8e_type mod_byte = *src++;
579 uint32_type gap = end_src - src;
582 if (mod_byte == 0 && gap >= 8) {
595 for (relbit = 1; count-- != 0 && src < end_src; relbit <<=1)
597 if (relbit & mod_byte)
599 uint8e_type reloc = *src;
600 /* This item needs to be relocated */
601 switch (reloc & RELOCATION_TYPE_BITS) {
602 case RELOCATION_TYPE_ABS:
606 case RELOCATION_TYPE_REL:
608 /* Relocate the item relative to the section */
609 oasys_reloc_type *r =
612 sizeof(oasys_reloc_type));
613 *(per->reloc_tail_ptr) = r;
614 per->reloc_tail_ptr = &r->next;
615 r->next= (oasys_reloc_type *)NULL;
616 /* Reference to undefined symbol */
618 /* There is no symbol */
620 /* Work out the howto */
622 data->sections[reloc & RELOCATION_SECT_BITS];
623 r->relent.addend = - r->relent.section->vma;
624 r->relent.address = dst_ptr - dst_base_ptr;
625 r->relent.howto = &howto_table[reloc>>6];
626 r->relent.sym_ptr_ptr = (asymbol **)NULL;
627 section->reloc_count++;
629 /* Fake up the data to look like it's got the -ve pc in it, this makes
630 it much easier to convert into other formats. This is done by
633 if (r->relent.howto->pc_relative == true) {
634 r->relent.addend -= dst_ptr - dst_base_ptr;
642 case RELOCATION_TYPE_UND:
644 oasys_reloc_type *r =
647 sizeof(oasys_reloc_type));
648 *(per->reloc_tail_ptr) = r;
649 per->reloc_tail_ptr = &r->next;
650 r->next= (oasys_reloc_type *)NULL;
651 /* Reference to undefined symbol */
653 /* Get symbol number */
654 r->symbol = (src[0]<<8) | src[1];
655 /* Work out the howto */
656 r->relent.section = (asection *)NULL;
657 r->relent.addend = 0;
658 r->relent.address = dst_ptr - dst_base_ptr;
659 r->relent.howto = &howto_table[reloc>>6];
660 r->relent.sym_ptr_ptr = (asymbol **)NULL;
661 section->reloc_count++;
664 /* Fake up the data to look like it's got the -ve pc in it, this makes
665 it much easier to convert into other formats. This is done by
668 if (r->relent.howto->pc_relative == true) {
669 r->relent.addend -= dst_ptr - dst_base_ptr;
676 case RELOCATION_TYPE_COM:
686 case oasys_record_is_local_enum:
687 case oasys_record_is_symbol_enum:
688 case oasys_record_is_section_enum:
701 bfd_error_vector_type bfd_error_vector;
704 DEFUN(oasys_new_section_hook,(abfd, newsect),
708 newsect->used_by_bfd = (PTR)
709 bfd_alloc(abfd, sizeof(oasys_per_section_type));
710 oasys_per_section( newsect)->data = (bfd_byte *)NULL;
711 oasys_per_section(newsect)->section = newsect;
712 oasys_per_section(newsect)->offset = 0;
713 oasys_per_section(newsect)->initialized = false;
714 newsect->alignment_power = 1;
715 /* Turn the section string into an index */
717 sscanf(newsect->name,"%u", &newsect->target_index);
724 DEFUN(oasys_get_reloc_upper_bound, (abfd, asect),
728 oasys_slurp_section_data(abfd);
729 return (asect->reloc_count+1) * sizeof(arelent *);
733 DEFUN(oasys_get_section_contents,(abfd, section, location, offset, count),
740 oasys_per_section_type *p = (oasys_per_section_type *) section->used_by_bfd;
741 oasys_slurp_section_data(abfd);
742 if (p->initialized == false)
744 (void) memset(location, 0, (int)count);
748 (void) memcpy(location,(PTR)( p->data + offset), (int)count);
755 DEFUN(oasys_canonicalize_reloc,(abfd, section, relptr, symbols),
761 unsigned int reloc_count = 0;
762 oasys_reloc_type *src = (oasys_reloc_type *)(section->relocation);
763 while (src != (oasys_reloc_type *)NULL) {
764 if (src->relent.section == (asection *)NULL)
766 src->relent.sym_ptr_ptr = symbols + src->symbol;
768 *relptr ++ = &src->relent;
772 *relptr = (arelent *)NULL;
773 return section->reloc_count = reloc_count;
778 DEFUN(oasys_set_arch_mach, (abfd, arch, machine),
780 enum bfd_architecture arch AND
781 unsigned long machine)
783 abfd->obj_arch = arch;
784 abfd->obj_machine = machine;
793 /* Calculate the checksum and write one record */
795 DEFUN(oasys_write_record,(abfd, type, record, size),
797 CONST oasys_record_enum_type type AND
798 oasys_record_union_type *record AND
804 record->header.length = size;
805 record->header.type = type;
806 record->header.check_sum = 0;
807 record->header.fill = 0;
808 ptr = &record->pad[0];
810 for (i = 0; i < size; i++) {
813 record->header.check_sum = 0xff & (- checksum);
814 bfd_write((PTR)record, 1, size, abfd);
818 /* Write out all the symbols */
820 DEFUN(oasys_write_syms, (abfd),
824 asymbol **generic = bfd_get_outsymbols(abfd);
825 unsigned int index = 0;
826 for (count = 0; count < bfd_get_symcount(abfd); count++) {
828 oasys_symbol_record_type symbol;
829 asymbol * CONST g = generic[count];
831 CONST char *src = g->name;
832 char *dst = symbol.name;
835 if (g->flags & BSF_FORT_COMM) {
836 symbol.relb = RELOCATION_TYPE_COM;
837 bfd_h_put_16(abfd, index, (uint8e_type *)(&symbol.refno[0]));
840 else if (g->flags & BSF_ABSOLUTE) {
841 symbol.relb = RELOCATION_TYPE_ABS;
842 bfd_h_put_16(abfd, 0, (uint8e_type *)(&symbol.refno[0]));
845 else if (g->flags & BSF_UNDEFINED) {
846 symbol.relb = RELOCATION_TYPE_UND ;
847 bfd_h_put_16(abfd, index, (uint8e_type *)(&symbol.refno[0]));
848 /* Overload the value field with the output index number */
851 else if (g->flags & BSF_DEBUGGING) {
856 if (g->section == (asection *)NULL) {
857 /* Sometime, the oasys tools give out a symbol with illegal
858 bits in it, we'll output it in the same broken way */
860 symbol.relb = RELOCATION_TYPE_REL | 0;
863 symbol.relb = RELOCATION_TYPE_REL |g->section->output_section->target_index;
865 bfd_h_put_16(abfd, 0, (uint8e_type *)(&symbol.refno[0]));
872 bfd_h_put_32(abfd, g->value, (bfd_byte*) symbol.value);
875 if (g->flags & BSF_LOCAL) {
876 oasys_write_record(abfd,
877 oasys_record_is_local_enum,
878 (oasys_record_union_type *) &symbol,
879 offsetof(oasys_symbol_record_type, name[0]) + l);
882 oasys_write_record(abfd,
883 oasys_record_is_symbol_enum,
884 (oasys_record_union_type *) &symbol,
885 offsetof(oasys_symbol_record_type, name[0]) + l);
892 /* Write a section header for each section */
894 DEFUN(oasys_write_sections, (abfd),
898 static oasys_section_record_type out = {0};
900 for (s = abfd->sections; s != (asection *)NULL; s = s->next) {
901 if (!isdigit(s->name[0]))
903 bfd_error_vector.nonrepresentable_section(abfd,
906 out.relb = RELOCATION_TYPE_REL | s->target_index;
907 bfd_h_put_32(abfd, s->size, (bfd_byte *) out.value);
908 bfd_h_put_32(abfd, s->vma, (bfd_byte *) out.vma);
910 oasys_write_record(abfd,
911 oasys_record_is_section_enum,
912 (oasys_record_union_type *) &out,
918 DEFUN(oasys_write_header, (abfd),
921 /* Create and write the header */
922 oasys_header_record_type r;
923 size_t length = strlen(abfd->filename);
924 if (length > (size_t)sizeof(r.module_name)) {
925 length = sizeof(r.module_name);
928 (void)memcpy(r.module_name,
931 (void)memset(r.module_name + length,
933 sizeof(r.module_name) - length);
935 r.version_number = OASYS_VERSION_NUMBER;
936 r.rev_number = OASYS_REV_NUMBER;
937 oasys_write_record(abfd,
938 oasys_record_is_header_enum,
939 (oasys_record_union_type *)&r,
940 offsetof(oasys_header_record_type, description[0]));
947 DEFUN(oasys_write_end,(abfd),
950 oasys_end_record_type end;
951 uint8e_type null = 0;
952 end.relb = RELOCATION_TYPE_ABS;
953 bfd_h_put_32(abfd, abfd->start_address, (bfd_byte *)end.entry);
954 bfd_h_put_16(abfd, 0, (bfd_byte *)end.fill);
956 oasys_write_record(abfd,
957 oasys_record_is_end_enum,
958 (oasys_record_union_type *)&end,
960 bfd_write((PTR)&null, 1, 1, abfd);
968 arelent *a = *((arelent **)ap);
969 arelent *b = *((arelent **)bp);
970 return a->address - b->address;
978 DEFUN(oasys_write_data, (abfd),
982 for (s = abfd->sections; s != (asection *)NULL; s = s->next) {
983 if (s->flags & SEC_LOAD) {
984 uint8e_type *raw_data = oasys_per_section(s)->data;
985 oasys_data_record_type processed_data;
986 bfd_size_type current_byte_index = 0;
987 unsigned int relocs_to_go = s->reloc_count;
988 arelent **p = s->orelocation;
989 if (s->reloc_count != 0) {
990 /* Sort the reloc records so it's easy to insert the relocs into the
993 qsort(s->orelocation,
998 current_byte_index = 0;
999 processed_data.relb = s->target_index | RELOCATION_TYPE_REL;
1001 while (current_byte_index < s->size)
1003 /* Scan forwards by eight bytes or however much is left and see if
1004 there are any relocations going on */
1005 uint8e_type *mod = &processed_data.data[0];
1006 uint8e_type *dst = &processed_data.data[1];
1009 unsigned int long_length = 128;
1012 bfd_h_put_32(abfd, s->vma + current_byte_index, processed_data.addr);
1013 if ((size_t)(long_length + current_byte_index) > (size_t)(s->size)) {
1014 long_length = s->size - current_byte_index;
1016 while (long_length > 0 && (dst - (uint8e_type*)&processed_data < 128)) {
1018 unsigned int length = long_length;
1023 for (i = 0; i < length; i++) {
1024 if (relocs_to_go != 0) {
1026 reloc_howto_type *CONST how=r->howto;
1027 /* There is a relocation, is it for this byte ? */
1028 if (r->address == current_byte_index) {
1029 uint8e_type rel_byte;
1034 if(how->pc_relative) {
1037 /* Also patch the raw data so that it doesn't have
1038 the -ve stuff any more */
1039 if (how->size != 2) {
1041 bfd_get_16(abfd,raw_data) +
1042 current_byte_index, raw_data);
1047 bfd_get_32(abfd,raw_data) +
1048 current_byte_index, raw_data);
1054 if (how->size ==2) {
1058 /* Is this a section relative relocation, or a symbol
1059 relative relocation ? */
1060 if (r->section != (asection*)NULL)
1062 /* The relent has a section attached, so it must be section
1064 rel_byte |= RELOCATION_TYPE_REL;
1065 rel_byte |= r->section->output_section->target_index;
1070 asymbol *p = *(r->sym_ptr_ptr);
1072 /* If this symbol has a section attached, then it
1073 has already been resolved. Change from a symbol
1074 ref to a section ref */
1075 if(p->section != (asection *)NULL) {
1076 rel_byte |= RELOCATION_TYPE_REL;
1078 p->section->output_section->target_index;
1082 rel_byte |= RELOCATION_TYPE_UND;
1086 /* Next two bytes are a symbol index - we can get
1087 this from the symbol value which has been zapped
1088 into the symbol index in the table when the
1089 symbol table was written
1091 *dst++ = p->value >> 8;
1098 /* If this is coming from an unloadable section then copy
1100 if (raw_data == (uint8e_type *)NULL) {
1104 *dst++ = *raw_data++;
1106 current_byte_index++;
1109 long_length -= length;
1112 oasys_write_record(abfd,
1113 oasys_record_is_data_enum,
1114 (oasys_record_union_type *)&processed_data,
1115 dst - (uint8e_type*)&processed_data);
1122 DEFUN(oasys_write_object_contents, (abfd),
1125 oasys_write_header(abfd);
1126 oasys_write_syms(abfd);
1127 oasys_write_sections(abfd);
1128 oasys_write_data(abfd);
1129 oasys_write_end(abfd);
1136 /** exec and core file sections */
1138 /* set section contents is complicated with OASYS since the format is
1139 * not a byte image, but a record stream.
1142 DEFUN(oasys_set_section_contents,(abfd, section, location, offset, count),
1147 bfd_size_type count)
1150 if (oasys_per_section(section)->data == (bfd_byte *)NULL )
1152 oasys_per_section(section)->data =
1153 (bfd_byte *)(bfd_alloc(abfd,section->size));
1155 (void) memcpy((PTR)(oasys_per_section(section)->data + offset),
1164 /* Native-level interface to symbols. */
1166 /* We read the symbols into a buffer, which is discarded when this
1167 function exits. We read the strings into a buffer large enough to
1168 hold them all plus all the cached symbol entries. */
1171 DEFUN(oasys_make_empty_symbol,(abfd),
1175 oasys_symbol_type *new =
1176 (oasys_symbol_type *)bfd_zalloc (abfd, sizeof (oasys_symbol_type));
1177 new->symbol.the_bfd = abfd;
1178 return &new->symbol;
1185 /* User should have checked the file flags; perhaps we should return
1186 BFD_NO_MORE_SYMBOLS if there are none? */
1189 oasys_openr_next_archived_file(arch, prev)
1193 oasys_ar_data_type *ar = oasys_ar_data(arch);
1194 oasys_module_info_type *p;
1195 /* take the next one from the arch state, or reset */
1196 if (prev == (bfd *)NULL) {
1197 /* Reset the index - the first two entries are bogus*/
1198 ar->module_index = 0;
1201 p = ar->module + ar->module_index;
1204 if (ar->module_index <= ar->module_count) {
1205 if (p->abfd == (bfd *)NULL) {
1206 p->abfd = _bfd_create_empty_archive_element_shell(arch);
1207 p->abfd->origin = p->pos;
1208 p->abfd->filename = p->name;
1210 /* Fixup a pointer to this element for the member */
1211 p->abfd->arelt_data = (PTR)p;
1216 bfd_error = no_more_archived_files;
1222 oasys_find_nearest_line(abfd,
1233 char **filename_ptr;
1234 char **functionname_ptr;
1235 unsigned int *line_ptr;
1242 DEFUN(oasys_generic_stat_arch_elt,(abfd, buf),
1246 oasys_module_info_type *mod = (oasys_module_info_type *) abfd->arelt_data;
1247 if (mod == (oasys_module_info_type *)NULL) {
1248 bfd_error = invalid_operation;
1252 buf->st_size = mod->size;
1253 buf->st_mode = 0666;
1259 DEFUN(oasys_sizeof_headers,(abfd, exec),
1266 #define oasys_core_file_failing_command (char *(*)())(bfd_nullvoidptr)
1267 #define oasys_core_file_failing_signal (int (*)())bfd_0
1268 #define oasys_core_file_matches_executable_p 0
1269 #define oasys_slurp_armap bfd_true
1270 #define oasys_slurp_extended_name_table bfd_true
1271 #define oasys_truncate_arname (void (*)())bfd_nullvoidptr
1272 #define oasys_write_armap 0
1273 #define oasys_get_lineno (struct lineno_cache_entry *(*)())bfd_nullvoidptr
1274 #define oasys_close_and_cleanup bfd_generic_close_and_cleanup
1276 #define oasys_bfd_debug_info_start bfd_void
1277 #define oasys_bfd_debug_info_end bfd_void
1278 #define oasys_bfd_debug_info_accumulate (FOO(void, (*), (bfd *, asection *)))bfd_void
1282 bfd_target oasys_vec =
1285 bfd_target_oasys_flavour_enum,
1286 true, /* target byte order */
1287 true, /* target headers byte order */
1288 (HAS_RELOC | EXEC_P | /* object flags */
1289 HAS_LINENO | HAS_DEBUG |
1290 HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
1291 (SEC_CODE|SEC_DATA|SEC_ROM|SEC_HAS_CONTENTS
1292 |SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
1293 ' ', /* ar_pad_char */
1294 16, /* ar_max_namelen */
1295 1, /* minimum alignment */
1296 _do_getb64, _do_putb64, _do_getb32, _do_putb32, _do_getb16, _do_putb16, /* data */
1297 _do_getb64, _do_putb64, _do_getb32, _do_putb32, _do_getb16, _do_putb16, /* hdrs */
1300 oasys_object_p, /* bfd_check_format */
1304 { /* bfd_set_format */
1307 _bfd_generic_mkarchive,
1310 { /* bfd_write_contents */
1312 oasys_write_object_contents,
1313 _bfd_write_archive_contents,