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
24 #define offsetof(type, identifier) (size_t) &(((type *) 0)->identifier)
34 /* Read in all the section data and relocation stuff too */
35 PROTO(static boolean,oasys_slurp_section_data,(bfd *CONST abfd));
38 DEFUN(oasys_read_record,(abfd, record),
40 oasys_record_union_type *record)
43 bfd_read((PTR)record, 1, sizeof(record->header), abfd);
45 if ((size_t) record->header.length <= (size_t) sizeof (record->header))
47 bfd_read((PTR)(((char *)record )+ sizeof(record->header)),
48 1, record->header.length - sizeof(record->header),
52 DEFUN(oasys_string_length,(record),
53 oasys_record_union_type *record)
55 return record->header.length
56 - ((char *)record->symbol.name - (char *)record);
59 /*****************************************************************************/
63 Slurp the symbol table by reading in all the records at the start file
64 till we get to the first section record.
66 We'll sort the symbolss into two lists, defined and undefined. The
67 undefined symbols will be placed into the table according to their
70 We do this by placing all undefined symbols at the front of the table
71 moving in, and the defined symbols at the end of the table moving back.
76 DEFUN(oasys_slurp_symbol_table,(abfd),
79 oasys_record_union_type record;
80 oasys_data_type *data = oasys_data(abfd);
82 asymbol *dest_defined;
87 if (data->symbols != (asymbol *)NULL) {
90 /* Buy enough memory for all the symbols and all the names */
92 (asymbol *)bfd_alloc(abfd, sizeof(asymbol) * abfd->symcount);
93 #ifdef UNDERSCORE_HACK
94 /* buy 1 more char for each symbol to keep the underscore in*/
95 data->strings = bfd_alloc(abfd, data->symbol_string_length +
98 data->strings = bfd_alloc(abfd, data->symbol_string_length);
102 dest_defined = data->symbols + abfd->symcount -1;
104 string_ptr = data->strings;
105 bfd_seek(abfd, (file_ptr)0, SEEK_SET);
108 oasys_read_record(abfd, &record);
109 switch (record.header.type) {
110 case oasys_record_is_header_enum:
112 case oasys_record_is_local_enum:
113 case oasys_record_is_symbol_enum:
115 int flag = record.header.type == oasys_record_is_local_enum ?
116 (BSF_LOCAL) : (BSF_GLOBAL | BSF_EXPORT);
119 size_t length = oasys_string_length(&record);
120 switch (record.symbol.relb & RELOCATION_TYPE_BITS) {
121 case RELOCATION_TYPE_ABS:
122 dest = dest_defined--;
124 dest->flags = BSF_ABSOLUTE | flag;
126 case RELOCATION_TYPE_REL:
127 dest = dest_defined--;
129 oasys_data(abfd)->sections[record.symbol.relb &
130 RELOCATION_SECT_BITS];
131 if (record.header.type == oasys_record_is_local_enum)
133 dest->flags = BSF_LOCAL;
134 if (dest->section ==(asection *)(~0)) {
135 /* It seems that sometimes internal symbols are tied up, but
136 still get output, even though there is no
146 case RELOCATION_TYPE_UND:
147 dest = data->symbols + bfd_h_get_16(abfd, (bfd_byte *)&record.symbol.refno[0]);
148 dest->section = (asection *)NULL;
149 dest->flags = BSF_UNDEFINED;
151 case RELOCATION_TYPE_COM:
152 dest = dest_defined--;
153 dest->name = string_ptr;
154 dest->the_bfd = abfd;
156 dest->section = (asection *)NULL;
157 dest->flags = BSF_FORT_COMM;
160 dest->name = string_ptr;
161 dest->the_bfd = abfd;
162 dest->udata = (PTR)NULL;
163 dest->value = bfd_h_get_32(abfd, (bfd_byte *)&record.symbol.value[0]);
165 #ifdef UNDERSCORE_HACK
166 if (record.symbol.name[0] != '_') {
171 memcpy(string_ptr, record.symbol.name, length);
174 string_ptr[length] =0;
175 string_ptr += length +1;
187 DEFUN(oasys_get_symtab_upper_bound,(abfd),
190 oasys_slurp_symbol_table (abfd);
192 return (abfd->symcount+1) * (sizeof (oasys_symbol_type *));
198 extern bfd_target oasys_vec;
201 DEFUN(oasys_get_symtab,(abfd, location),
206 unsigned int counter ;
207 if (oasys_slurp_symbol_table(abfd) == false) {
210 symbase = oasys_data(abfd)->symbols;
211 for (counter = 0; counter < abfd->symcount; counter++) {
212 *(location++) = symbase++;
215 return abfd->symcount;
218 /***********************************************************************
223 DEFUN(oasys_archive_p,(abfd),
226 oasys_archive_header_type header;
227 oasys_extarchive_header_type header_ext;
230 bfd_seek(abfd, (file_ptr) 0, false);
233 bfd_read((PTR)&header_ext, 1, sizeof(header_ext), abfd);
236 header.version = bfd_h_get_32(abfd, (bfd_byte *)header_ext.version);
237 header.mod_count = bfd_h_get_32(abfd, (bfd_byte *)header_ext.mod_count);
238 header.mod_tbl_offset = bfd_h_get_32(abfd, (bfd_byte *)header_ext.mod_tbl_offset);
239 header.sym_tbl_size = bfd_h_get_32(abfd, (bfd_byte *)header_ext.sym_tbl_size);
240 header.sym_count = bfd_h_get_32(abfd, (bfd_byte *)header_ext.sym_count);
241 header.sym_tbl_offset = bfd_h_get_32(abfd, (bfd_byte *)header_ext.sym_tbl_offset);
242 header.xref_count = bfd_h_get_32(abfd, (bfd_byte *)header_ext.xref_count);
243 header.xref_lst_offset = bfd_h_get_32(abfd, (bfd_byte *)header_ext.xref_lst_offset);
246 There isn't a magic number in an Oasys archive, so the best we
247 can do to verify reasnableness is to make sure that the values in
248 the header are too weird
251 if (header.version>10000 ||
252 header.mod_count>10000 ||
253 header.sym_count>100000 ||
254 header.xref_count > 100000) return (bfd_target *)NULL;
257 That all worked, lets buy the space for the header and read in
261 oasys_ar_data_type *ar =
262 (oasys_ar_data_type*) bfd_alloc(abfd, sizeof(oasys_ar_data_type));
265 oasys_module_info_type *module =
266 (oasys_module_info_type*)
267 bfd_alloc(abfd, sizeof(oasys_module_info_type) * header.mod_count);
270 oasys_module_table_type record;
275 ar->module_count = header.mod_count;
278 filepos = header.mod_tbl_offset;
279 for (i = 0; i < header.mod_count; i++) {
280 bfd_seek(abfd , filepos, SEEK_SET);
282 /* There are two ways of specifying the archive header */
285 oasys_extmodule_table_type_a_type record_ext;
286 bfd_read((PTR)&record_ext, 1, sizeof(record_ext), abfd);
288 record.mod_size = bfd_h_get_32(abfd, (bfd_byte *)record_ext.mod_size);
289 record.file_offset = bfd_h_get_32(abfd,
290 (bfd_byte *) record_ext.file_offset);
292 record.dep_count = bfd_h_get_32(abfd, (bfd_byte *)record_ext.dep_count);
293 record.depee_count = bfd_h_get_32(abfd,(bfd_byte *) record_ext.depee_count);
294 record.sect_count = bfd_h_get_32(abfd, (bfd_byte *) record_ext.sect_count);
297 module[i].name = bfd_alloc(abfd,33);
299 memcpy(module[i].name, record_ext.mod_name, 33);
302 record.dep_count * 4 +
303 record.depee_count * 4 +
304 record.sect_count * 8 + 187;
307 oasys_extmodule_table_type_b_type record_ext;
308 bfd_read((PTR)&record_ext, 1, sizeof(record_ext), abfd);
310 record.mod_size = bfd_h_get_32(abfd, (bfd_byte *) record_ext.mod_size);
311 record.file_offset = bfd_h_get_32(abfd,
312 (bfd_byte *)record_ext.file_offset);
314 record.dep_count = bfd_h_get_32(abfd, (bfd_byte *) record_ext.dep_count);
315 record.depee_count = bfd_h_get_32(abfd, (bfd_byte *) record_ext.depee_count);
316 record.sect_count = bfd_h_get_32(abfd, (bfd_byte *) record_ext.sect_count);
317 record.module_name_size = bfd_h_get_32(abfd, (bfd_byte *) record_ext.mod_name_length);
319 module[i].name = bfd_alloc(abfd,record.module_name_size + 1);
320 bfd_read((PTR)module[i].name, 1, record.module_name_size, abfd);
321 module[i].name[record.module_name_size] = 0;
324 record.dep_count * 4 +
325 record.module_name_size + 1;
330 module[i].size = record.mod_size;
331 module[i].pos = record.file_offset;
340 DEFUN(oasys_mkobject,(abfd),
343 oasys_data_type *oasys;
346 (oasys_data_type*)bfd_alloc(abfd, sizeof(oasys_data_type)));
347 oasys = oasys_data(abfd);
353 DEFUN(oasys_object_p,(abfd),
356 oasys_data_type *oasys;
357 oasys_data_type *save = oasys_data(abfd);
359 boolean had_usefull = false;
362 oasys_mkobject(abfd);
363 oasys = oasys_data(abfd);
364 memset((PTR)oasys->sections, 0xff, sizeof(oasys->sections));
366 /* Point to the start of the file */
367 bfd_seek(abfd, (file_ptr)0, SEEK_SET);
368 oasys->symbol_string_length = 0;
369 /* Inspect the records, but only keep the section info -
370 remember the size of the symbols
372 oasys->first_data_record = 0;
374 oasys_record_union_type record;
375 oasys_read_record(abfd, &record);
376 if ((size_t)record.header.length < (size_t)sizeof(record.header))
380 switch ((oasys_record_enum_type)(record.header.type)) {
381 case oasys_record_is_header_enum:
384 case oasys_record_is_symbol_enum:
385 case oasys_record_is_local_enum:
386 /* Count symbols and remember their size for a future malloc */
388 oasys->symbol_string_length += 1 + oasys_string_length(&record);
391 case oasys_record_is_section_enum:
395 unsigned int section_number;
396 if (record.section.header.length != sizeof(record.section))
400 buffer = bfd_alloc(abfd, 3);
401 section_number= record.section.relb & RELOCATION_SECT_BITS;
402 sprintf(buffer,"%u", section_number);
403 s = bfd_make_section(abfd,buffer);
404 oasys->sections[section_number] = s;
405 switch (record.section.relb & RELOCATION_TYPE_BITS) {
406 case RELOCATION_TYPE_ABS:
407 case RELOCATION_TYPE_REL:
409 case RELOCATION_TYPE_UND:
410 case RELOCATION_TYPE_COM:
414 s->size = bfd_h_get_32(abfd, (bfd_byte *) & record.section.value[0]) ;
415 s->vma = bfd_h_get_32(abfd, (bfd_byte *)&record.section.vma[0]);
420 case oasys_record_is_data_enum:
421 oasys->first_data_record = bfd_tell(abfd) - record.header.length;
422 case oasys_record_is_debug_enum:
423 case oasys_record_is_module_enum:
424 case oasys_record_is_named_section_enum:
425 case oasys_record_is_end_enum:
426 if (had_usefull == false) goto fail;
433 oasys->symbols = (asymbol *)NULL;
435 Oasys support several architectures, but I can't see a simple way
436 to discover which one is in a particular file - we'll guess
438 abfd->obj_arch = bfd_arch_m68k;
439 abfd->obj_machine =0;
440 if (abfd->symcount != 0) {
441 abfd->flags |= HAS_SYMS;
445 We don't know if a section has data until we've read it..
448 oasys_slurp_section_data(abfd);
454 (void) bfd_release(abfd, oasys);
455 set_tdata (abfd, save);
456 return (bfd_target *)NULL;
461 DEFUN(oasys_print_symbol,(ignore_abfd, afile, symbol, how),
465 bfd_print_symbol_enum_type how)
467 FILE *file = (FILE *)afile;
470 case bfd_print_symbol_name_enum:
471 case bfd_print_symbol_type_enum:
472 fprintf(file,"%s", symbol->name);
474 case bfd_print_symbol_all_enum:
476 CONST char *section_name = symbol->section == (asection *)NULL ?
477 "*abs" : symbol->section->name;
479 bfd_print_symbol_vandf((PTR)file,symbol);
481 fprintf(file," %-5s %s",
489 The howto table is build using the top two bits of a reloc byte to
490 index into it. The bits are PCREL,WORD/LONG
492 static reloc_howto_type howto_table[]=
495 HOWTO( 0, 0, 1, 16, false,0, true,true,0,"abs16",true,0x0000ffff, 0x0000ffff,false),
496 HOWTO( 0, 0, 2, 32, false,0, true,true,0,"abs32",true,0xffffffff, 0xffffffff,false),
497 HOWTO( 0, 0, 1, 16, true,0, true,true,0,"pcrel16",true,0x0000ffff, 0x0000ffff,false),
498 HOWTO( 0, 0, 2, 32, true,0, true,true,0,"pcrel32",true,0xffffffff, 0xffffffff,false)
501 /* Read in all the section data and relocation stuff too */
503 DEFUN(oasys_slurp_section_data,(abfd),
506 oasys_record_union_type record;
507 oasys_data_type *data = oasys_data(abfd);
510 oasys_per_section_type *per ;
514 /* See if the data has been slurped already .. */
515 for (s = abfd->sections; s != (asection *)NULL; s= s->next) {
516 per = oasys_per_section(s);
517 if (per->initialized == true)
521 if (data->first_data_record == 0) return true;
523 bfd_seek(abfd, data->first_data_record, SEEK_SET);
525 oasys_read_record(abfd, &record);
526 switch (record.header.type)
528 case oasys_record_is_header_enum:
530 case oasys_record_is_data_enum:
533 uint8e_type *src = record.data.data;
534 uint8e_type *end_src = ((uint8e_type *)&record) +
535 record.header.length;
538 bfd_byte *dst_base_ptr ;
541 data->sections[record.data.relb & RELOCATION_SECT_BITS];
543 per = oasys_per_section(section);
546 if (per->initialized == false)
548 per->data = (bfd_byte *) bfd_zalloc(abfd, section->size);
549 per->reloc_tail_ptr = (oasys_reloc_type **)&(section->relocation);
550 per->had_vma = false;
551 per->initialized = true;
552 section->reloc_count = 0;
553 section->flags = SEC_ALLOC;
556 dst_offset = bfd_h_get_32(abfd, record.data.addr) ;
557 if (per->had_vma == false) {
558 /* Take the first vma we see as the base */
560 section->vma = dst_offset;
565 dst_offset -= section->vma;
568 dst_base_ptr = oasys_per_section(section)->data;
569 dst_ptr = oasys_per_section(section)->data +
573 section->flags |= SEC_LOAD | SEC_HAS_CONTENTS;
575 while (src < end_src) {
576 uint8e_type mod_byte = *src++;
577 uint32_type gap = end_src - src;
580 if (mod_byte == 0 && gap >= 8) {
593 for (relbit = 1; count-- != 0 && src < end_src; relbit <<=1)
595 if (relbit & mod_byte)
597 uint8e_type reloc = *src;
598 /* This item needs to be relocated */
599 switch (reloc & RELOCATION_TYPE_BITS) {
600 case RELOCATION_TYPE_ABS:
604 case RELOCATION_TYPE_REL:
606 /* Relocate the item relative to the section */
607 oasys_reloc_type *r =
610 sizeof(oasys_reloc_type));
611 *(per->reloc_tail_ptr) = r;
612 per->reloc_tail_ptr = &r->next;
613 r->next= (oasys_reloc_type *)NULL;
614 /* Reference to undefined symbol */
616 /* There is no symbol */
618 /* Work out the howto */
620 data->sections[reloc & RELOCATION_SECT_BITS];
621 r->relent.addend = - r->relent.section->vma;
622 r->relent.address = dst_ptr - dst_base_ptr;
623 r->relent.howto = &howto_table[reloc>>6];
624 r->relent.sym_ptr_ptr = (asymbol **)NULL;
625 section->reloc_count++;
627 /* Fake up the data to look like it's got the -ve pc in it, this makes
628 it much easier to convert into other formats. This is done by
631 if (r->relent.howto->pc_relative == true) {
632 r->relent.addend -= dst_ptr - dst_base_ptr;
640 case RELOCATION_TYPE_UND:
642 oasys_reloc_type *r =
645 sizeof(oasys_reloc_type));
646 *(per->reloc_tail_ptr) = r;
647 per->reloc_tail_ptr = &r->next;
648 r->next= (oasys_reloc_type *)NULL;
649 /* Reference to undefined symbol */
651 /* Get symbol number */
652 r->symbol = (src[0]<<8) | src[1];
653 /* Work out the howto */
654 r->relent.section = (asection *)NULL;
655 r->relent.addend = 0;
656 r->relent.address = dst_ptr - dst_base_ptr;
657 r->relent.howto = &howto_table[reloc>>6];
658 r->relent.sym_ptr_ptr = (asymbol **)NULL;
659 section->reloc_count++;
662 /* Fake up the data to look like it's got the -ve pc in it, this makes
663 it much easier to convert into other formats. This is done by
666 if (r->relent.howto->pc_relative == true) {
667 r->relent.addend -= dst_ptr - dst_base_ptr;
674 case RELOCATION_TYPE_COM:
684 case oasys_record_is_local_enum:
685 case oasys_record_is_symbol_enum:
686 case oasys_record_is_section_enum:
699 bfd_error_vector_type bfd_error_vector;
702 DEFUN(oasys_new_section_hook,(abfd, newsect),
706 newsect->used_by_bfd = (PTR)
707 bfd_alloc(abfd, sizeof(oasys_per_section_type));
708 oasys_per_section( newsect)->data = (bfd_byte *)NULL;
709 oasys_per_section(newsect)->section = newsect;
710 oasys_per_section(newsect)->offset = 0;
711 oasys_per_section(newsect)->initialized = false;
712 newsect->alignment_power = 1;
713 /* Turn the section string into an index */
715 sscanf(newsect->name,"%u", &newsect->target_index);
722 DEFUN(oasys_get_reloc_upper_bound, (abfd, asect),
726 oasys_slurp_section_data(abfd);
727 return (asect->reloc_count+1) * sizeof(arelent *);
731 DEFUN(oasys_get_section_contents,(abfd, section, location, offset, count),
738 oasys_per_section_type *p = (oasys_per_section_type *) section->used_by_bfd;
739 oasys_slurp_section_data(abfd);
740 if (p->initialized == false)
742 (void) memset(location, 0, (int)count);
746 (void) memcpy(location,(PTR)( p->data + offset), (int)count);
753 DEFUN(oasys_canonicalize_reloc,(abfd, section, relptr, symbols),
759 unsigned int reloc_count = 0;
760 oasys_reloc_type *src = (oasys_reloc_type *)(section->relocation);
761 while (src != (oasys_reloc_type *)NULL) {
762 if (src->relent.section == (asection *)NULL)
764 src->relent.sym_ptr_ptr = symbols + src->symbol;
766 *relptr ++ = &src->relent;
770 *relptr = (arelent *)NULL;
771 return section->reloc_count = reloc_count;
776 DEFUN(oasys_set_arch_mach, (abfd, arch, machine),
778 enum bfd_architecture arch AND
779 unsigned long machine)
781 abfd->obj_arch = arch;
782 abfd->obj_machine = machine;
791 /* Calculate the checksum and write one record */
793 DEFUN(oasys_write_record,(abfd, type, record, size),
795 CONST oasys_record_enum_type type AND
796 oasys_record_union_type *record AND
802 record->header.length = size;
803 record->header.type = type;
804 record->header.check_sum = 0;
805 record->header.fill = 0;
806 ptr = &record->pad[0];
808 for (i = 0; i < size; i++) {
811 record->header.check_sum = 0xff & (- checksum);
812 bfd_write((PTR)record, 1, size, abfd);
816 /* Write out all the symbols */
818 DEFUN(oasys_write_syms, (abfd),
822 asymbol **generic = bfd_get_outsymbols(abfd);
823 unsigned int index = 0;
824 for (count = 0; count < bfd_get_symcount(abfd); count++) {
826 oasys_symbol_record_type symbol;
827 asymbol * CONST g = generic[count];
829 CONST char *src = g->name;
830 char *dst = symbol.name;
833 if (g->flags & BSF_FORT_COMM) {
834 symbol.relb = RELOCATION_TYPE_COM;
835 bfd_h_put_16(abfd, index, (uint8e_type *)(&symbol.refno[0]));
838 else if (g->flags & BSF_ABSOLUTE) {
839 symbol.relb = RELOCATION_TYPE_ABS;
840 bfd_h_put_16(abfd, 0, (uint8e_type *)(&symbol.refno[0]));
843 else if (g->flags & BSF_UNDEFINED) {
844 symbol.relb = RELOCATION_TYPE_UND ;
845 bfd_h_put_16(abfd, index, (uint8e_type *)(&symbol.refno[0]));
846 /* Overload the value field with the output index number */
849 else if (g->flags & BSF_DEBUGGING) {
854 if (g->section == (asection *)NULL) {
855 /* Sometime, the oasys tools give out a symbol with illegal
856 bits in it, we'll output it in the same broken way */
858 symbol.relb = RELOCATION_TYPE_REL | 0;
861 symbol.relb = RELOCATION_TYPE_REL |g->section->output_section->target_index;
863 bfd_h_put_16(abfd, 0, (uint8e_type *)(&symbol.refno[0]));
870 bfd_h_put_32(abfd, g->value, (bfd_byte*) symbol.value);
873 if (g->flags & BSF_LOCAL) {
874 oasys_write_record(abfd,
875 oasys_record_is_local_enum,
876 (oasys_record_union_type *) &symbol,
877 offsetof(oasys_symbol_record_type, name[0]) + l);
880 oasys_write_record(abfd,
881 oasys_record_is_symbol_enum,
882 (oasys_record_union_type *) &symbol,
883 offsetof(oasys_symbol_record_type, name[0]) + l);
890 /* Write a section header for each section */
892 DEFUN(oasys_write_sections, (abfd),
896 static oasys_section_record_type out = {0};
898 for (s = abfd->sections; s != (asection *)NULL; s = s->next) {
899 if (!isdigit(s->name[0]))
901 bfd_error_vector.nonrepresentable_section(abfd,
904 out.relb = RELOCATION_TYPE_REL | s->target_index;
905 bfd_h_put_32(abfd, s->size, (bfd_byte *) out.value);
906 bfd_h_put_32(abfd, s->vma, (bfd_byte *) out.vma);
908 oasys_write_record(abfd,
909 oasys_record_is_section_enum,
910 (oasys_record_union_type *) &out,
916 DEFUN(oasys_write_header, (abfd),
919 /* Create and write the header */
920 oasys_header_record_type r;
921 size_t length = strlen(abfd->filename);
922 if (length > (size_t)sizeof(r.module_name)) {
923 length = sizeof(r.module_name);
926 (void)memcpy(r.module_name,
929 (void)memset(r.module_name + length,
931 sizeof(r.module_name) - length);
933 r.version_number = OASYS_VERSION_NUMBER;
934 r.rev_number = OASYS_REV_NUMBER;
935 oasys_write_record(abfd,
936 oasys_record_is_header_enum,
937 (oasys_record_union_type *)&r,
938 offsetof(oasys_header_record_type, description[0]));
945 DEFUN(oasys_write_end,(abfd),
948 oasys_end_record_type end;
949 uint8e_type null = 0;
950 end.relb = RELOCATION_TYPE_ABS;
951 bfd_h_put_32(abfd, abfd->start_address, (bfd_byte *)end.entry);
952 bfd_h_put_16(abfd, 0, (bfd_byte *)end.fill);
954 oasys_write_record(abfd,
955 oasys_record_is_end_enum,
956 (oasys_record_union_type *)&end,
958 bfd_write((PTR)&null, 1, 1, abfd);
966 arelent *a = *((arelent **)ap);
967 arelent *b = *((arelent **)bp);
968 return a->address - b->address;
976 DEFUN(oasys_write_data, (abfd),
980 for (s = abfd->sections; s != (asection *)NULL; s = s->next) {
981 if (s->flags & SEC_LOAD) {
982 uint8e_type *raw_data = oasys_per_section(s)->data;
983 oasys_data_record_type processed_data;
984 bfd_size_type current_byte_index = 0;
985 unsigned int relocs_to_go = s->reloc_count;
986 arelent **p = s->orelocation;
987 if (s->reloc_count != 0) {
988 /* Sort the reloc records so it's easy to insert the relocs into the
991 qsort(s->orelocation,
996 current_byte_index = 0;
997 processed_data.relb = s->target_index | RELOCATION_TYPE_REL;
999 while (current_byte_index < s->size)
1001 /* Scan forwards by eight bytes or however much is left and see if
1002 there are any relocations going on */
1003 uint8e_type *mod = &processed_data.data[0];
1004 uint8e_type *dst = &processed_data.data[1];
1007 unsigned int long_length = 128;
1010 bfd_h_put_32(abfd, s->vma + current_byte_index, processed_data.addr);
1011 if ((size_t)(long_length + current_byte_index) > (size_t)(s->size)) {
1012 long_length = s->size - current_byte_index;
1014 while (long_length > 0 && (dst - (uint8e_type*)&processed_data < 128)) {
1016 unsigned int length = long_length;
1021 for (i = 0; i < length; i++) {
1022 if (relocs_to_go != 0) {
1024 reloc_howto_type *CONST how=r->howto;
1025 /* There is a relocation, is it for this byte ? */
1026 if (r->address == current_byte_index) {
1027 uint8e_type rel_byte;
1032 if(how->pc_relative) {
1035 /* Also patch the raw data so that it doesn't have
1036 the -ve stuff any more */
1037 if (how->size != 2) {
1039 bfd_get_16(abfd,raw_data) +
1040 current_byte_index, raw_data);
1045 bfd_get_32(abfd,raw_data) +
1046 current_byte_index, raw_data);
1052 if (how->size ==2) {
1056 /* Is this a section relative relocation, or a symbol
1057 relative relocation ? */
1058 if (r->section != (asection*)NULL)
1060 /* The relent has a section attatched, so it must be section
1062 rel_byte |= RELOCATION_TYPE_REL;
1063 rel_byte |= r->section->output_section->target_index;
1068 asymbol *p = *(r->sym_ptr_ptr);
1070 /* If this symbol has a section attatched, then it
1071 has already been resolved. Change from a symbol
1072 ref to a section ref */
1073 if(p->section != (asection *)NULL) {
1074 rel_byte |= RELOCATION_TYPE_REL;
1076 p->section->output_section->target_index;
1080 rel_byte |= RELOCATION_TYPE_UND;
1084 /* Next two bytes are a symbol index - we can get
1085 this from the symbol value which has been zapped
1086 into the symbol index in the table when the
1087 symbol table was written
1089 *dst++ = p->value >> 8;
1096 /* If this is coming from an unloadable section then copy
1098 if (raw_data == (uint8e_type *)NULL) {
1102 *dst++ = *raw_data++;
1104 current_byte_index++;
1107 long_length -= length;
1110 oasys_write_record(abfd,
1111 oasys_record_is_data_enum,
1112 (oasys_record_union_type *)&processed_data,
1113 dst - (uint8e_type*)&processed_data);
1120 DEFUN(oasys_write_object_contents, (abfd),
1123 oasys_write_header(abfd);
1124 oasys_write_syms(abfd);
1125 oasys_write_sections(abfd);
1126 oasys_write_data(abfd);
1127 oasys_write_end(abfd);
1134 /** exec and core file sections */
1136 /* set section contents is complicated with OASYS since the format is
1137 * not a byte image, but a record stream.
1140 DEFUN(oasys_set_section_contents,(abfd, section, location, offset, count),
1145 bfd_size_type count)
1148 if (oasys_per_section(section)->data == (bfd_byte *)NULL )
1150 oasys_per_section(section)->data =
1151 (bfd_byte *)(bfd_alloc(abfd,section->size));
1153 (void) memcpy((PTR)(oasys_per_section(section)->data + offset),
1162 /* Native-level interface to symbols. */
1164 /* We read the symbols into a buffer, which is discarded when this
1165 function exits. We read the strings into a buffer large enough to
1166 hold them all plus all the cached symbol entries. */
1169 DEFUN(oasys_make_empty_symbol,(abfd),
1173 oasys_symbol_type *new =
1174 (oasys_symbol_type *)bfd_zalloc (abfd, sizeof (oasys_symbol_type));
1175 new->symbol.the_bfd = abfd;
1176 return &new->symbol;
1183 /* User should have checked the file flags; perhaps we should return
1184 BFD_NO_MORE_SYMBOLS if there are none? */
1187 oasys_openr_next_archived_file(arch, prev)
1191 oasys_ar_data_type *ar = oasys_ar_data(arch);
1192 oasys_module_info_type *p;
1193 /* take the next one from the arch state, or reset */
1194 if (prev == (bfd *)NULL) {
1195 /* Reset the index - the first two entries are bogus*/
1196 ar->module_index = 0;
1199 p = ar->module + ar->module_index;
1202 if (ar->module_index <= ar->module_count) {
1203 if (p->abfd == (bfd *)NULL) {
1204 p->abfd = _bfd_create_empty_archive_element_shell(arch);
1205 p->abfd->origin = p->pos;
1206 p->abfd->filename = p->name;
1208 /* Fixup a pointer to this element for the member */
1209 p->abfd->arelt_data = (PTR)p;
1214 bfd_error = no_more_archived_files;
1220 oasys_find_nearest_line(abfd,
1231 char **filename_ptr;
1232 char **functionname_ptr;
1233 unsigned int *line_ptr;
1240 DEFUN(oasys_generic_stat_arch_elt,(abfd, buf),
1244 oasys_module_info_type *mod = (oasys_module_info_type *) abfd->arelt_data;
1245 if (mod == (oasys_module_info_type *)NULL) {
1246 bfd_error = invalid_operation;
1250 buf->st_size = mod->size;
1251 buf->st_mode = 0666;
1257 DEFUN(oasys_sizeof_headers,(abfd, exec),
1264 #define oasys_core_file_failing_command (char *(*)())(bfd_nullvoidptr)
1265 #define oasys_core_file_failing_signal (int (*)())bfd_0
1266 #define oasys_core_file_matches_executable_p 0
1267 #define oasys_slurp_armap bfd_true
1268 #define oasys_slurp_extended_name_table bfd_true
1269 #define oasys_truncate_arname (void (*)())bfd_nullvoidptr
1270 #define oasys_write_armap 0
1271 #define oasys_get_lineno (struct lineno_cache_entry *(*)())bfd_nullvoidptr
1272 #define oasys_close_and_cleanup bfd_generic_close_and_cleanup
1274 #define oasys_bfd_debug_info_start bfd_void
1275 #define oasys_bfd_debug_info_end bfd_void
1276 #define oasys_bfd_debug_info_accumulate (FOO(void, (*), (bfd *, asection *)))bfd_void
1280 bfd_target oasys_vec =
1283 bfd_target_oasys_flavour_enum,
1284 true, /* target byte order */
1285 true, /* target headers byte order */
1286 (HAS_RELOC | EXEC_P | /* object flags */
1287 HAS_LINENO | HAS_DEBUG |
1288 HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
1289 (SEC_CODE|SEC_DATA|SEC_ROM|SEC_HAS_CONTENTS
1290 |SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
1291 ' ', /* ar_pad_char */
1292 16, /* ar_max_namelen */
1293 1, /* minimum alignment */
1294 _do_getb64, _do_putb64, _do_getb32, _do_putb32, _do_getb16, _do_putb16, /* data */
1295 _do_getb64, _do_putb64, _do_getb32, _do_putb32, _do_getb16, _do_putb16, /* hdrs */
1298 oasys_object_p, /* bfd_check_format */
1302 { /* bfd_set_format */
1305 _bfd_generic_mkarchive,
1308 { /* bfd_write_contents */
1310 oasys_write_object_contents,
1311 _bfd_write_archive_contents,