1 /* bfd backend for oasys objects.
2 Written by Steve Chamberlain of Cygnus Support <steve@cygnus.com> */
4 /* Copyright (C) 1990, 1991 Free Software Foundation, Inc.
6 This file is part of BFD, the Binary File Diddler.
8 BFD is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 1, or (at your option)
13 BFD is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with BFD; see the file COPYING. If not, write to
20 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
24 #define UNDERSCORE_HACK 1
25 #define offsetof(type, identifier) (size_t) &(((type *) 0)->identifier)
35 /* Read in all the section data and relocation stuff too */
36 PROTO(static boolean
,oasys_slurp_section_data
,(bfd
*CONST abfd
));
39 DEFUN(oasys_read_record
,(abfd
, record
),
41 oasys_record_union_type
*record
)
44 bfd_read((PTR
)record
, 1, sizeof(record
->header
), abfd
);
46 if ((size_t) record
->header
.length
<= (size_t) sizeof (record
->header
))
48 bfd_read((PTR
)(((char *)record
)+ sizeof(record
->header
)),
49 1, record
->header
.length
- sizeof(record
->header
),
53 DEFUN(oasys_string_length
,(record
),
54 oasys_record_union_type
*record
)
56 return record
->header
.length
57 - ((char *)record
->symbol
.name
- (char *)record
);
60 /*****************************************************************************/
64 Slurp the symbol table by reading in all the records at the start file
65 till we get to the first section record.
67 We'll sort the symbolss into two lists, defined and undefined. The
68 undefined symbols will be placed into the table according to their
71 We do this by placing all undefined symbols at the front of the table
72 moving in, and the defined symbols at the end of the table moving back.
77 DEFUN(oasys_slurp_symbol_table
,(abfd
),
80 oasys_record_union_type record
;
81 oasys_data_type
*data
= oasys_data(abfd
);
83 asymbol
*dest_defined
;
88 if (data
->symbols
!= (asymbol
*)NULL
) {
91 /* Buy enough memory for all the symbols and all the names */
93 (asymbol
*)bfd_alloc(abfd
, sizeof(asymbol
) * abfd
->symcount
);
94 #ifdef UNDERSCORE_HACK
95 /* buy 1 more char for each symbol to keep the underscore in*/
96 data
->strings
= bfd_alloc(abfd
, data
->symbol_string_length
+
99 data
->strings
= bfd_alloc(abfd
, data
->symbol_string_length
);
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
& 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
&
131 RELOCATION_SECT_BITS
];
132 if (record
.header
.type
== oasys_record_is_local_enum
)
134 dest
->flags
= BSF_LOCAL
;
135 if (dest
->section
==(asection
*)(~0)) {
136 /* It seems that sometimes internal symbols are tied up, but
137 still get output, even though there is no
147 case RELOCATION_TYPE_UND
:
148 dest
= data
->symbols
+ bfd_h_get_16(abfd
, (bfd_byte
*)&record
.symbol
.refno
[0]);
149 dest
->section
= (asection
*)NULL
;
150 dest
->flags
= BSF_UNDEFINED
;
152 case RELOCATION_TYPE_COM
:
153 dest
= dest_defined
--;
154 dest
->name
= string_ptr
;
155 dest
->the_bfd
= abfd
;
157 dest
->section
= (asection
*)NULL
;
158 dest
->flags
= BSF_FORT_COMM
;
161 dest
->name
= string_ptr
;
162 dest
->the_bfd
= abfd
;
163 dest
->udata
= (PTR
)NULL
;
164 dest
->value
= bfd_h_get_32(abfd
, &record
.symbol
.value
[0]);
166 #ifdef UNDERSCORE_HACK
167 if (record
.symbol
.name
[0] != '_') {
172 memcpy(string_ptr
, record
.symbol
.name
, length
);
175 string_ptr
[length
] =0;
176 string_ptr
+= length
+1;
188 DEFUN(oasys_get_symtab_upper_bound
,(abfd
),
191 oasys_slurp_symbol_table (abfd
);
193 return (abfd
->symcount
+1) * (sizeof (oasys_symbol_type
*));
199 extern bfd_target oasys_vec
;
202 DEFUN(oasys_get_symtab
,(abfd
, location
),
207 unsigned int counter
;
208 if (oasys_slurp_symbol_table(abfd
) == false) {
211 symbase
= oasys_data(abfd
)->symbols
;
212 for (counter
= 0; counter
< abfd
->symcount
; counter
++) {
213 *(location
++) = symbase
++;
216 return abfd
->symcount
;
219 /***********************************************************************
224 DEFUN(oasys_archive_p
,(abfd
),
227 oasys_archive_header_type header
;
228 oasys_external_archive_header_type header_ext
;
231 bfd_seek(abfd
, (file_ptr
) 0, false);
234 bfd_read((PTR
)&header_ext
, 1, sizeof(header_ext
), abfd
);
237 header
.version
= bfd_h_get_32(abfd
, header_ext
.version
);
238 header
.mod_count
= bfd_h_get_32(abfd
, header_ext
.mod_count
);
239 header
.mod_tbl_offset
= bfd_h_get_32(abfd
, header_ext
.mod_tbl_offset
);
240 header
.sym_tbl_size
= bfd_h_get_32(abfd
, header_ext
.sym_tbl_size
);
241 header
.sym_count
= bfd_h_get_32(abfd
, header_ext
.sym_count
);
242 header
.sym_tbl_offset
= bfd_h_get_32(abfd
, header_ext
.sym_tbl_offset
);
243 header
.xref_count
= bfd_h_get_32(abfd
, header_ext
.xref_count
);
244 header
.xref_lst_offset
= bfd_h_get_32(abfd
, header_ext
.xref_lst_offset
);
247 There isn't a magic number in an Oasys archive, so the best we
248 can do to verify reasnableness is to make sure that the values in
249 the header are too weird
252 if (header
.version
>10000 ||
253 header
.mod_count
>10000 ||
254 header
.sym_count
>100000 ||
255 header
.xref_count
> 100000) return (bfd_target
*)NULL
;
258 That all worked, lets buy the space for the header and read in
262 oasys_ar_data_type
*ar
=
263 (oasys_ar_data_type
*) bfd_alloc(abfd
, sizeof(oasys_ar_data_type
));
266 oasys_module_info_type
*module
=
267 (oasys_module_info_type
*)
268 bfd_alloc(abfd
, sizeof(oasys_module_info_type
) * header
.mod_count
);
271 oasys_module_table_type record
;
276 ar
->module_count
= header
.mod_count
;
279 filepos
= header
.mod_tbl_offset
;
280 for (i
= 0; i
< header
.mod_count
; i
++) {
281 bfd_seek(abfd
, filepos
, SEEK_SET
);
283 /* There are two ways of specifying the archive header */
286 oasys_external_module_table_type_a_type record_ext
;
287 bfd_read((PTR
)&record_ext
, 1, sizeof(record_ext
), abfd
);
289 record
.mod_size
= bfd_h_get_32(abfd
, record_ext
.mod_size
);
290 record
.file_offset
= bfd_h_get_32(abfd
,
291 record_ext
.file_offset
);
293 record
.dep_count
= bfd_h_get_32(abfd
, record_ext
.dep_count
);
294 record
.depee_count
= bfd_h_get_32(abfd
, record_ext
.depee_count
);
295 record
.sect_count
= bfd_h_get_32(abfd
, record_ext
.sect_count
);
298 module
[i
].name
= bfd_alloc(abfd
,33);
300 memcpy(module
[i
].name
, record_ext
.mod_name
, 33);
303 record
.dep_count
* 4 +
304 record
.depee_count
* 4 +
305 record
.sect_count
* 8 + 187;
308 oasys_external_module_table_type_b_type record_ext
;
309 bfd_read((PTR
)&record_ext
, 1, sizeof(record_ext
), abfd
);
311 record
.mod_size
= bfd_h_get_32(abfd
, record_ext
.mod_size
);
312 record
.file_offset
= bfd_h_get_32(abfd
,
313 record_ext
.file_offset
);
315 record
.dep_count
= bfd_h_get_32(abfd
, record_ext
.dep_count
);
316 record
.depee_count
= bfd_h_get_32(abfd
, record_ext
.depee_count
);
317 record
.sect_count
= bfd_h_get_32(abfd
, record_ext
.sect_count
);
318 record
.module_name_size
= bfd_h_get_32(abfd
, record_ext
.mod_name_length
);
320 module
[i
].name
= bfd_alloc(abfd
,record
.module_name_size
+ 1);
321 bfd_read((PTR
)module
[i
].name
, 1, record
.module_name_size
, abfd
);
322 module
[i
].name
[record
.module_name_size
] = 0;
325 record
.dep_count
* 4 +
326 record
.module_name_size
+ 1;
331 module
[i
].size
= record
.mod_size
;
332 module
[i
].pos
= record
.file_offset
;
341 DEFUN(oasys_mkobject
,(abfd
),
344 oasys_data_type
*oasys
;
347 (oasys_data_type
*)bfd_alloc(abfd
, sizeof(oasys_data_type
)));
348 oasys
= oasys_data(abfd
);
354 DEFUN(oasys_object_p
,(abfd
),
357 oasys_data_type
*oasys
;
358 oasys_data_type
*save
= oasys_data(abfd
);
360 boolean had_usefull
= false;
363 oasys_mkobject(abfd
);
364 oasys
= oasys_data(abfd
);
365 memset((PTR
)oasys
->sections
, 0xff, sizeof(oasys
->sections
));
367 /* Point to the start of the file */
368 bfd_seek(abfd
, (file_ptr
)0, SEEK_SET
);
369 oasys
->symbol_string_length
= 0;
370 /* Inspect the records, but only keep the section info -
371 remember the size of the symbols
373 oasys
->first_data_record
= 0;
375 oasys_record_union_type record
;
376 oasys_read_record(abfd
, &record
);
377 if ((size_t)record
.header
.length
< (size_t)sizeof(record
.header
))
381 switch ((oasys_record_enum_type
)(record
.header
.type
)) {
382 case oasys_record_is_header_enum
:
385 case oasys_record_is_symbol_enum
:
386 case oasys_record_is_local_enum
:
387 /* Count symbols and remember their size for a future malloc */
389 oasys
->symbol_string_length
+= 1 + oasys_string_length(&record
);
392 case oasys_record_is_section_enum
:
396 unsigned int section_number
;
397 if (record
.section
.header
.length
!= sizeof(record
.section
))
401 buffer
= bfd_alloc(abfd
, 3);
402 section_number
= record
.section
.relb
& RELOCATION_SECT_BITS
;
403 sprintf(buffer
,"%u", section_number
);
404 s
= bfd_make_section(abfd
,buffer
);
405 oasys
->sections
[section_number
] = s
;
406 switch (record
.section
.relb
& RELOCATION_TYPE_BITS
) {
407 case RELOCATION_TYPE_ABS
:
408 case RELOCATION_TYPE_REL
:
410 case RELOCATION_TYPE_UND
:
411 case RELOCATION_TYPE_COM
:
415 s
->size
= bfd_h_get_32(abfd
, & record
.section
.value
[0]) ;
416 s
->vma
= bfd_h_get_32(abfd
, &record
.section
.vma
[0]);
421 case oasys_record_is_data_enum
:
422 oasys
->first_data_record
= bfd_tell(abfd
) - record
.header
.length
;
423 case oasys_record_is_debug_enum
:
424 case oasys_record_is_module_enum
:
425 case oasys_record_is_named_section_enum
:
426 case oasys_record_is_end_enum
:
427 if (had_usefull
== false) goto fail
;
434 oasys
->symbols
= (asymbol
*)NULL
;
436 Oasys support several architectures, but I can't see a simple way
437 to discover which one is in a particular file - we'll guess
439 abfd
->obj_arch
= bfd_arch_m68k
;
440 abfd
->obj_machine
=0;
441 if (abfd
->symcount
!= 0) {
442 abfd
->flags
|= HAS_SYMS
;
446 We don't know if a section has data until we've read it..
449 oasys_slurp_section_data(abfd
);
455 (void) bfd_release(abfd
, oasys
);
456 set_tdata (abfd
, save
);
457 return (bfd_target
*)NULL
;
462 DEFUN(oasys_print_symbol
,(ignore_abfd
, afile
, symbol
, how
),
466 bfd_print_symbol_enum_type how
)
468 FILE *file
= (FILE *)afile
;
471 case bfd_print_symbol_name_enum
:
472 case bfd_print_symbol_type_enum
:
473 fprintf(file
,"%s", symbol
->name
);
475 case bfd_print_symbol_all_enum
:
477 CONST
char *section_name
= symbol
->section
== (asection
*)NULL
?
478 "*abs" : symbol
->section
->name
;
480 bfd_print_symbol_vandf((PTR
)file
,symbol
);
482 fprintf(file
," %-5s %s",
490 The howto table is build using the top two bits of a reloc byte to
491 index into it. The bits are PCREL,WORD/LONG
493 static reloc_howto_type howto_table
[]=
496 HOWTO( 0, 0, 1, 16, false,0, true,true,0,"abs16",true,0x0000ffff, 0x0000ffff,false),
497 HOWTO( 0, 0, 2, 32, false,0, true,true,0,"abs32",true,0xffffffff, 0xffffffff,false),
498 HOWTO( 0, 0, 1, 16, true,0, true,true,0,"pcrel16",true,0x0000ffff, 0x0000ffff,false),
499 HOWTO( 0, 0, 2, 32, true,0, true,true,0,"pcrel32",true,0xffffffff, 0xffffffff,false)
502 /* Read in all the section data and relocation stuff too */
504 DEFUN(oasys_slurp_section_data
,(abfd
),
507 oasys_record_union_type record
;
508 oasys_data_type
*data
= oasys_data(abfd
);
511 oasys_per_section_type
*per
;
515 /* See if the data has been slurped already .. */
516 for (s
= abfd
->sections
; s
!= (asection
*)NULL
; s
= s
->next
) {
517 per
= oasys_per_section(s
);
518 if (per
->initialized
== true)
522 if (data
->first_data_record
== 0) return true;
524 bfd_seek(abfd
, data
->first_data_record
, SEEK_SET
);
526 oasys_read_record(abfd
, &record
);
527 switch (record
.header
.type
)
529 case oasys_record_is_header_enum
:
531 case oasys_record_is_data_enum
:
534 uint8e_type
*src
= record
.data
.data
;
535 uint8e_type
*end_src
= ((uint8e_type
*)&record
) +
536 record
.header
.length
;
539 bfd_byte
*dst_base_ptr
;
542 data
->sections
[record
.data
.relb
& RELOCATION_SECT_BITS
];
544 per
= oasys_per_section(section
);
547 if (per
->initialized
== false)
549 per
->data
= (bfd_byte
*) bfd_zalloc(abfd
, section
->size
);
550 per
->reloc_tail_ptr
= (oasys_reloc_type
**)&(section
->relocation
);
551 per
->had_vma
= false;
552 per
->initialized
= true;
553 section
->reloc_count
= 0;
554 section
->flags
= SEC_ALLOC
;
557 dst_offset
= bfd_h_get_32(abfd
, record
.data
.addr
) ;
558 if (per
->had_vma
== false) {
559 /* Take the first vma we see as the base */
561 section
->vma
= dst_offset
;
566 dst_offset
-= section
->vma
;
569 dst_base_ptr
= oasys_per_section(section
)->data
;
570 dst_ptr
= oasys_per_section(section
)->data
+
574 section
->flags
|= SEC_LOAD
| SEC_HAS_CONTENTS
;
576 while (src
< end_src
) {
577 uint8e_type mod_byte
= *src
++;
578 uint32_type gap
= end_src
- src
;
581 if (mod_byte
== 0 && gap
>= 8) {
594 for (relbit
= 1; count
-- != 0 && src
< end_src
; relbit
<<=1)
596 if (relbit
& mod_byte
)
598 uint8e_type reloc
= *src
;
599 /* This item needs to be relocated */
600 switch (reloc
& RELOCATION_TYPE_BITS
) {
601 case RELOCATION_TYPE_ABS
:
605 case RELOCATION_TYPE_REL
:
607 /* Relocate the item relative to the section */
608 oasys_reloc_type
*r
=
611 sizeof(oasys_reloc_type
));
612 *(per
->reloc_tail_ptr
) = r
;
613 per
->reloc_tail_ptr
= &r
->next
;
614 r
->next
= (oasys_reloc_type
*)NULL
;
615 /* Reference to undefined symbol */
617 /* There is no symbol */
619 /* Work out the howto */
621 data
->sections
[reloc
& RELOCATION_SECT_BITS
];
622 r
->relent
.addend
= - r
->relent
.section
->vma
;
623 r
->relent
.address
= dst_ptr
- dst_base_ptr
;
624 r
->relent
.howto
= &howto_table
[reloc
>>6];
625 r
->relent
.sym_ptr_ptr
= (asymbol
**)NULL
;
626 section
->reloc_count
++;
628 /* Fake up the data to look like it's got the -ve pc in it, this makes
629 it much easier to convert into other formats. This is done by
632 if (r
->relent
.howto
->pc_relative
== true) {
633 r
->relent
.addend
-= dst_ptr
- dst_base_ptr
;
641 case RELOCATION_TYPE_UND
:
643 oasys_reloc_type
*r
=
646 sizeof(oasys_reloc_type
));
647 *(per
->reloc_tail_ptr
) = r
;
648 per
->reloc_tail_ptr
= &r
->next
;
649 r
->next
= (oasys_reloc_type
*)NULL
;
650 /* Reference to undefined symbol */
652 /* Get symbol number */
653 r
->symbol
= (src
[0]<<8) | src
[1];
654 /* Work out the howto */
655 r
->relent
.section
= (asection
*)NULL
;
656 r
->relent
.addend
= 0;
657 r
->relent
.address
= dst_ptr
- dst_base_ptr
;
658 r
->relent
.howto
= &howto_table
[reloc
>>6];
659 r
->relent
.sym_ptr_ptr
= (asymbol
**)NULL
;
660 section
->reloc_count
++;
663 /* Fake up the data to look like it's got the -ve pc in it, this makes
664 it much easier to convert into other formats. This is done by
667 if (r
->relent
.howto
->pc_relative
== true) {
668 r
->relent
.addend
-= dst_ptr
- dst_base_ptr
;
675 case RELOCATION_TYPE_COM
:
685 case oasys_record_is_local_enum
:
686 case oasys_record_is_symbol_enum
:
687 case oasys_record_is_section_enum
:
700 bfd_error_vector_type bfd_error_vector
;
703 DEFUN(oasys_new_section_hook
,(abfd
, newsect
),
707 newsect
->used_by_bfd
= (PTR
)
708 bfd_alloc(abfd
, sizeof(oasys_per_section_type
));
709 oasys_per_section( newsect
)->data
= (bfd_byte
*)NULL
;
710 oasys_per_section(newsect
)->section
= newsect
;
711 oasys_per_section(newsect
)->offset
= 0;
712 oasys_per_section(newsect
)->initialized
= false;
713 newsect
->alignment_power
= 1;
714 /* Turn the section string into an index */
716 sscanf(newsect
->name
,"%u", &newsect
->target_index
);
723 DEFUN(oasys_get_reloc_upper_bound
, (abfd
, asect
),
727 oasys_slurp_section_data(abfd
);
728 return (asect
->reloc_count
+1) * sizeof(arelent
*);
732 DEFUN(oasys_get_section_contents
,(abfd
, section
, location
, offset
, count
),
739 oasys_per_section_type
*p
= (oasys_per_section_type
*) section
->used_by_bfd
;
740 oasys_slurp_section_data(abfd
);
741 if (p
->initialized
== false)
743 (void) memset(location
, 0, (int)count
);
747 (void) memcpy(location
, p
->data
+ offset
, (int)count
);
754 DEFUN(oasys_canonicalize_reloc
,(abfd
, section
, relptr
, symbols
),
760 unsigned int reloc_count
= 0;
761 oasys_reloc_type
*src
= (oasys_reloc_type
*)(section
->relocation
);
762 while (src
!= (oasys_reloc_type
*)NULL
) {
763 if (src
->relent
.section
== (asection
*)NULL
)
765 src
->relent
.sym_ptr_ptr
= symbols
+ src
->symbol
;
767 *relptr
++ = &src
->relent
;
771 *relptr
= (arelent
*)NULL
;
772 return section
->reloc_count
= reloc_count
;
777 DEFUN(oasys_set_arch_mach
, (abfd
, arch
, machine
),
779 enum bfd_architecture arch AND
780 unsigned long machine
)
782 abfd
->obj_arch
= arch
;
783 abfd
->obj_machine
= machine
;
792 /* Calculate the checksum and write one record */
794 DEFUN(oasys_write_record
,(abfd
, type
, record
, size
),
796 CONST oasys_record_enum_type type AND
797 oasys_record_union_type
*record AND
803 record
->header
.length
= size
;
804 record
->header
.type
= type
;
805 record
->header
.check_sum
= 0;
806 record
->header
.fill
= 0;
807 ptr
= &record
->pad
[0];
809 for (i
= 0; i
< size
; i
++) {
812 record
->header
.check_sum
= 0xff & (- checksum
);
813 bfd_write((PTR
)record
, 1, size
, abfd
);
817 /* Write out all the symbols */
819 DEFUN(oasys_write_syms
, (abfd
),
823 asymbol
**generic
= bfd_get_outsymbols(abfd
);
824 unsigned int index
= 0;
825 for (count
= 0; count
< bfd_get_symcount(abfd
); count
++) {
827 oasys_symbol_record_type symbol
;
828 asymbol
* CONST g
= generic
[count
];
830 CONST
char *src
= g
->name
;
831 char *dst
= symbol
.name
;
834 if (g
->flags
& BSF_FORT_COMM
) {
835 symbol
.relb
= RELOCATION_TYPE_COM
;
836 bfd_h_put_16(abfd
, index
, (uint8e_type
*)(&symbol
.refno
[0]));
839 else if (g
->flags
& BSF_ABSOLUTE
) {
840 symbol
.relb
= RELOCATION_TYPE_ABS
;
841 bfd_h_put_16(abfd
, 0, (uint8e_type
*)(&symbol
.refno
[0]));
844 else if (g
->flags
& BSF_UNDEFINED
) {
845 symbol
.relb
= RELOCATION_TYPE_UND
;
846 bfd_h_put_16(abfd
, index
, (uint8e_type
*)(&symbol
.refno
[0]));
847 /* Overload the value field with the output index number */
850 else if (g
->flags
& BSF_DEBUGGING
) {
855 if (g
->section
== (asection
*)NULL
) {
856 /* Sometime, the oasys tools give out a symbol with illegal
857 bits in it, we'll output it in the same broken way */
859 symbol
.relb
= RELOCATION_TYPE_REL
| 0;
862 symbol
.relb
= RELOCATION_TYPE_REL
|g
->section
->output_section
->target_index
;
864 bfd_h_put_16(abfd
, 0, (uint8e_type
*)(&symbol
.refno
[0]));
871 bfd_h_put_32(abfd
, g
->value
, symbol
.value
);
874 if (g
->flags
& BSF_LOCAL
) {
875 oasys_write_record(abfd
,
876 oasys_record_is_local_enum
,
877 (oasys_record_union_type
*) &symbol
,
878 offsetof(oasys_symbol_record_type
, name
[0]) + l
);
881 oasys_write_record(abfd
,
882 oasys_record_is_symbol_enum
,
883 (oasys_record_union_type
*) &symbol
,
884 offsetof(oasys_symbol_record_type
, name
[0]) + l
);
891 /* Write a section header for each section */
893 DEFUN(oasys_write_sections
, (abfd
),
897 static oasys_section_record_type out
= {0};
899 for (s
= abfd
->sections
; s
!= (asection
*)NULL
; s
= s
->next
) {
900 if (!isdigit(s
->name
[0]))
902 bfd_error_vector
.nonrepresentable_section(abfd
,
905 out
.relb
= RELOCATION_TYPE_REL
| s
->target_index
;
906 bfd_h_put_32(abfd
, s
->size
, out
.value
);
907 bfd_h_put_32(abfd
, s
->vma
, out
.vma
);
909 oasys_write_record(abfd
,
910 oasys_record_is_section_enum
,
911 (oasys_record_union_type
*) &out
,
917 DEFUN(oasys_write_header
, (abfd
),
920 /* Create and write the header */
921 oasys_header_record_type r
;
922 size_t length
= strlen(abfd
->filename
);
923 if (length
> (size_t)sizeof(r
.module_name
)) {
924 length
= sizeof(r
.module_name
);
927 (void)memcpy(r
.module_name
,
930 (void)memset(r
.module_name
+ length
,
932 sizeof(r
.module_name
) - length
);
934 r
.version_number
= OASYS_VERSION_NUMBER
;
935 r
.rev_number
= OASYS_REV_NUMBER
;
936 oasys_write_record(abfd
,
937 oasys_record_is_header_enum
,
938 (oasys_record_union_type
*)&r
,
939 offsetof(oasys_header_record_type
, description
[0]));
946 DEFUN(oasys_write_end
,(abfd
),
949 oasys_end_record_type end
;
950 uint8e_type null
= 0;
951 end
.relb
= RELOCATION_TYPE_ABS
;
952 bfd_h_put_32(abfd
, abfd
->start_address
, end
.entry
);
953 bfd_h_put_16(abfd
, 0, end
.fill
);
955 oasys_write_record(abfd
,
956 oasys_record_is_end_enum
,
957 (oasys_record_union_type
*)&end
,
959 bfd_write((PTR
)&null
, 1, 1, abfd
);
967 arelent
*a
= *((arelent
**)ap
);
968 arelent
*b
= *((arelent
**)bp
);
969 return a
->address
- b
->address
;
977 DEFUN(oasys_write_data
, (abfd
),
981 for (s
= abfd
->sections
; s
!= (asection
*)NULL
; s
= s
->next
) {
982 if (s
->flags
& SEC_LOAD
) {
983 uint8e_type
*raw_data
= oasys_per_section(s
)->data
;
984 oasys_data_record_type processed_data
;
985 bfd_size_type current_byte_index
= 0;
986 unsigned int relocs_to_go
= s
->reloc_count
;
987 arelent
**p
= s
->orelocation
;
988 if (s
->reloc_count
!= 0) {
989 /* Sort the reloc records so it's easy to insert the relocs into the
992 qsort(s
->orelocation
,
997 current_byte_index
= 0;
998 processed_data
.relb
= s
->target_index
| RELOCATION_TYPE_REL
;
1000 while (current_byte_index
< s
->size
)
1002 /* Scan forwards by eight bytes or however much is left and see if
1003 there are any relocations going on */
1004 uint8e_type
*mod
= &processed_data
.data
[0];
1005 uint8e_type
*dst
= &processed_data
.data
[1];
1008 unsigned int long_length
= 128;
1011 bfd_h_put_32(abfd
, s
->vma
+ current_byte_index
, processed_data
.addr
);
1012 if ((size_t)(long_length
+ current_byte_index
) > (size_t)(s
->size
)) {
1013 long_length
= s
->size
- current_byte_index
;
1015 while (long_length
> 0 && (dst
- (uint8e_type
*)&processed_data
< 128)) {
1017 unsigned int length
= long_length
;
1022 for (i
= 0; i
< length
; i
++) {
1023 if (relocs_to_go
!= 0) {
1025 reloc_howto_type
*CONST how
=r
->howto
;
1026 /* There is a relocation, is it for this byte ? */
1027 if (r
->address
== current_byte_index
) {
1028 uint8e_type rel_byte
;
1033 if(how
->pc_relative
) {
1036 /* Also patch the raw data so that it doesn't have
1037 the -ve stuff any more */
1038 if (how
->size
!= 2) {
1040 bfd_get_16(abfd
,raw_data
) +
1041 current_byte_index
, raw_data
);
1046 bfd_get_32(abfd
,raw_data
) +
1047 current_byte_index
, raw_data
);
1053 if (how
->size
==2) {
1057 /* Is this a section relative relocation, or a symbol
1058 relative relocation ? */
1059 if (r
->section
!= (asection
*)NULL
)
1061 /* The relent has a section attatched, so it must be section
1063 rel_byte
|= RELOCATION_TYPE_REL
;
1064 rel_byte
|= r
->section
->output_section
->target_index
;
1069 asymbol
*p
= *(r
->sym_ptr_ptr
);
1071 /* If this symbol has a section attatched, then it
1072 has already been resolved. Change from a symbol
1073 ref to a section ref */
1074 if(p
->section
!= (asection
*)NULL
) {
1075 rel_byte
|= RELOCATION_TYPE_REL
;
1077 p
->section
->output_section
->target_index
;
1081 rel_byte
|= RELOCATION_TYPE_UND
;
1085 /* Next two bytes are a symbol index - we can get
1086 this from the symbol value which has been zapped
1087 into the symbol index in the table when the
1088 symbol table was written
1090 *dst
++ = p
->value
>> 8;
1097 /* If this is coming from an unloadable section then copy
1099 if (raw_data
== (uint8e_type
*)NULL
) {
1103 *dst
++ = *raw_data
++;
1105 current_byte_index
++;
1108 long_length
-= length
;
1111 oasys_write_record(abfd
,
1112 oasys_record_is_data_enum
,
1113 (oasys_record_union_type
*)&processed_data
,
1114 dst
- (uint8e_type
*)&processed_data
);
1121 DEFUN(oasys_write_object_contents
, (abfd
),
1124 oasys_write_header(abfd
);
1125 oasys_write_syms(abfd
);
1126 oasys_write_sections(abfd
);
1127 oasys_write_data(abfd
);
1128 oasys_write_end(abfd
);
1135 /** exec and core file sections */
1137 /* set section contents is complicated with OASYS since the format is
1138 * not a byte image, but a record stream.
1141 DEFUN(oasys_set_section_contents
,(abfd
, section
, location
, offset
, count
),
1146 bfd_size_type count
)
1149 if (oasys_per_section(section
)->data
== (bfd_byte
*)NULL
)
1151 oasys_per_section(section
)->data
=
1152 (bfd_byte
*)(bfd_alloc(abfd
,section
->size
));
1154 (void) memcpy(oasys_per_section(section
)->data
+ offset
,
1163 /* Native-level interface to symbols. */
1165 /* We read the symbols into a buffer, which is discarded when this
1166 function exits. We read the strings into a buffer large enough to
1167 hold them all plus all the cached symbol entries. */
1170 DEFUN(oasys_make_empty_symbol
,(abfd
),
1174 oasys_symbol_type
*new =
1175 (oasys_symbol_type
*)bfd_zalloc (abfd
, sizeof (oasys_symbol_type
));
1176 new->symbol
.the_bfd
= abfd
;
1177 return &new->symbol
;
1184 /* User should have checked the file flags; perhaps we should return
1185 BFD_NO_MORE_SYMBOLS if there are none? */
1188 oasys_openr_next_archived_file(arch
, prev
)
1192 oasys_ar_data_type
*ar
= oasys_ar_data(arch
);
1193 oasys_module_info_type
*p
;
1194 /* take the next one from the arch state, or reset */
1195 if (prev
== (bfd
*)NULL
) {
1196 /* Reset the index - the first two entries are bogus*/
1197 ar
->module_index
= 0;
1200 p
= ar
->module
+ ar
->module_index
;
1203 if (ar
->module_index
<= ar
->module_count
) {
1204 if (p
->abfd
== (bfd
*)NULL
) {
1205 p
->abfd
= _bfd_create_empty_archive_element_shell(arch
);
1206 p
->abfd
->origin
= p
->pos
;
1207 p
->abfd
->filename
= p
->name
;
1209 /* Fixup a pointer to this element for the member */
1210 p
->abfd
->arelt_data
= (PTR
)p
;
1215 bfd_error
= no_more_archived_files
;
1221 oasys_find_nearest_line(abfd
,
1232 char **filename_ptr
;
1233 char **functionname_ptr
;
1234 unsigned int *line_ptr
;
1241 DEFUN(oasys_generic_stat_arch_elt
,(abfd
, buf
),
1245 oasys_module_info_type
*mod
= (oasys_module_info_type
*) abfd
->arelt_data
;
1246 if (mod
== (oasys_module_info_type
*)NULL
) {
1247 bfd_error
= invalid_operation
;
1251 buf
->st_size
= mod
->size
;
1252 buf
->st_mode
= 0666;
1258 DEFUN(oasys_sizeof_headers
,(abfd
, exec
),
1265 #define oasys_core_file_failing_command (char *(*)())(bfd_nullvoidptr)
1266 #define oasys_core_file_failing_signal (int (*)())bfd_0
1267 #define oasys_core_file_matches_executable_p 0
1268 #define oasys_slurp_armap bfd_true
1269 #define oasys_slurp_extended_name_table bfd_true
1270 #define oasys_truncate_arname (void (*)())bfd_nullvoidptr
1271 #define oasys_write_armap 0
1272 #define oasys_get_lineno (struct lineno_cache_entry *(*)())bfd_nullvoidptr
1273 #define oasys_close_and_cleanup bfd_generic_close_and_cleanup
1275 #define oasys_bfd_debug_info_start bfd_void
1276 #define oasys_bfd_debug_info_end bfd_void
1277 #define oasys_bfd_debug_info_accumulate (FOO(void, (*), (bfd *, asection *)))bfd_void
1281 bfd_target oasys_vec
=
1284 bfd_target_oasys_flavour_enum
,
1285 true, /* target byte order */
1286 true, /* target headers byte order */
1287 (HAS_RELOC
| EXEC_P
| /* object flags */
1288 HAS_LINENO
| HAS_DEBUG
|
1289 HAS_SYMS
| HAS_LOCALS
| DYNAMIC
| WP_TEXT
| D_PAGED
),
1290 (SEC_CODE
|SEC_DATA
|SEC_ROM
|SEC_HAS_CONTENTS
1291 |SEC_ALLOC
| SEC_LOAD
| SEC_RELOC
), /* section flags */
1292 ' ', /* ar_pad_char */
1293 16, /* ar_max_namelen */
1294 1, /* minimum alignment */
1295 _do_getb64
, _do_putb64
, _do_getb32
, _do_putb32
, _do_getb16
, _do_putb16
, /* data */
1296 _do_getb64
, _do_putb64
, _do_getb32
, _do_putb32
, _do_getb16
, _do_putb16
, /* hdrs */
1299 oasys_object_p
, /* bfd_check_format */
1303 { /* bfd_set_format */
1306 _bfd_generic_mkarchive
,
1309 { /* bfd_write_contents */
1311 oasys_write_object_contents
,
1312 _bfd_write_archive_contents
,