1 /* BFD back-end for oasys objects.
2 Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2001,
3 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
4 Written by Steve Chamberlain of Cygnus Support, <sac@cygnus.com>.
6 This file is part of BFD, the Binary File Descriptor library.
8 This program 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 3 of the License, or
11 (at your option) any later version.
13 This program 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 this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
21 MA 02110-1301, USA. */
23 #define UNDERSCORE_HACK 1
26 #include "safe-ctype.h"
31 /* Read in all the section data and relocation stuff too. */
34 oasys_read_record (bfd
*abfd
, oasys_record_union_type
*record
)
36 bfd_size_type amt
= sizeof (record
->header
);
38 if (bfd_bread ((void *) record
, amt
, abfd
) != amt
)
41 amt
= record
->header
.length
- sizeof (record
->header
);
44 if (bfd_bread ((void *) ((char *) record
+ sizeof (record
->header
)), amt
, abfd
)
51 oasys_string_length (oasys_record_union_type
*record
)
53 return record
->header
.length
54 - ((char *) record
->symbol
.name
- (char *) record
);
57 /* Slurp the symbol table by reading in all the records at the start file
58 till we get to the first section record.
60 We'll sort the symbolss into two lists, defined and undefined. The
61 undefined symbols will be placed into the table according to their
64 We do this by placing all undefined symbols at the front of the table
65 moving in, and the defined symbols at the end of the table moving back. */
68 oasys_slurp_symbol_table (bfd
*const abfd
)
70 oasys_record_union_type record
;
71 oasys_data_type
*data
= OASYS_DATA (abfd
);
72 bfd_boolean loop
= TRUE
;
73 asymbol
*dest_defined
;
78 if (data
->symbols
!= NULL
)
81 /* Buy enough memory for all the symbols and all the names. */
83 amt
*= sizeof (asymbol
);
84 data
->symbols
= bfd_alloc (abfd
, amt
);
86 amt
= data
->symbol_string_length
;
87 #ifdef UNDERSCORE_HACK
88 /* Buy 1 more char for each symbol to keep the underscore in. */
89 amt
+= abfd
->symcount
;
91 data
->strings
= bfd_alloc (abfd
, amt
);
93 if (!data
->symbols
|| !data
->strings
)
96 dest_defined
= data
->symbols
+ abfd
->symcount
- 1;
98 string_ptr
= data
->strings
;
99 if (bfd_seek (abfd
, (file_ptr
) 0, SEEK_SET
) != 0)
103 if (! oasys_read_record (abfd
, &record
))
106 switch (record
.header
.type
)
108 case oasys_record_is_header_enum
:
110 case oasys_record_is_local_enum
:
111 case oasys_record_is_symbol_enum
:
113 int flag
= record
.header
.type
== (int) oasys_record_is_local_enum
?
114 (BSF_LOCAL
) : (BSF_GLOBAL
| BSF_EXPORT
);
116 size_t length
= oasys_string_length (&record
);
117 switch (record
.symbol
.relb
& RELOCATION_TYPE_BITS
)
119 case RELOCATION_TYPE_ABS
:
120 dest
= dest_defined
--;
121 dest
->section
= bfd_abs_section_ptr
;
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
== (int) oasys_record_is_local_enum
)
132 dest
->flags
= BSF_LOCAL
;
133 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
144 case RELOCATION_TYPE_UND
:
145 dest
= data
->symbols
+ H_GET_16 (abfd
, record
.symbol
.refno
);
146 dest
->section
= bfd_und_section_ptr
;
148 case RELOCATION_TYPE_COM
:
149 dest
= dest_defined
--;
150 dest
->name
= string_ptr
;
151 dest
->the_bfd
= abfd
;
152 dest
->section
= bfd_com_section_ptr
;
155 dest
= dest_defined
--;
159 dest
->name
= string_ptr
;
160 dest
->the_bfd
= abfd
;
161 dest
->udata
.p
= NULL
;
162 dest
->value
= H_GET_32 (abfd
, record
.symbol
.value
);
164 #ifdef UNDERSCORE_HACK
165 if (record
.symbol
.name
[0] != '_')
171 memcpy (string_ptr
, record
.symbol
.name
, length
);
173 string_ptr
[length
] = 0;
174 string_ptr
+= length
+ 1;
185 oasys_get_symtab_upper_bound (bfd
*const abfd
)
187 if (! oasys_slurp_symbol_table (abfd
))
190 return (abfd
->symcount
+ 1) * (sizeof (oasys_symbol_type
*));
193 extern const bfd_target oasys_vec
;
196 oasys_canonicalize_symtab (bfd
*abfd
, asymbol
**location
)
199 unsigned int counter
;
201 if (! oasys_slurp_symbol_table (abfd
))
204 symbase
= OASYS_DATA (abfd
)->symbols
;
205 for (counter
= 0; counter
< abfd
->symcount
; counter
++)
206 *(location
++) = symbase
++;
209 return abfd
->symcount
;
214 static const bfd_target
*
215 oasys_archive_p (bfd
*abfd
)
217 oasys_archive_header_type header
;
218 oasys_extarchive_header_type header_ext
;
223 amt
= sizeof (header_ext
);
224 if (bfd_seek (abfd
, (file_ptr
) 0, 0) != 0
225 || bfd_bread ((void *) &header_ext
, amt
, abfd
) != amt
)
227 if (bfd_get_error () != bfd_error_system_call
)
228 bfd_set_error (bfd_error_wrong_format
);
232 header
.version
= H_GET_32 (abfd
, header_ext
.version
);
233 header
.mod_count
= H_GET_32 (abfd
, header_ext
.mod_count
);
234 header
.mod_tbl_offset
= H_GET_32 (abfd
, header_ext
.mod_tbl_offset
);
235 header
.sym_tbl_size
= H_GET_32 (abfd
, header_ext
.sym_tbl_size
);
236 header
.sym_count
= H_GET_32 (abfd
, header_ext
.sym_count
);
237 header
.sym_tbl_offset
= H_GET_32 (abfd
, header_ext
.sym_tbl_offset
);
238 header
.xref_count
= H_GET_32 (abfd
, header_ext
.xref_count
);
239 header
.xref_lst_offset
= H_GET_32 (abfd
, header_ext
.xref_lst_offset
);
241 /* There isn't a magic number in an Oasys archive, so the best we
242 can do to verify reasonableness is to make sure that the values in
243 the header are too weird. */
245 if (header
.version
> 10000
246 || header
.mod_count
> 10000
247 || header
.sym_count
> 100000
248 || header
.xref_count
> 100000)
251 /* That all worked, let's buy the space for the header and read in
254 oasys_ar_data_type
*ar
;
255 oasys_module_info_type
*module
;
256 oasys_module_table_type record
;
258 amt
= sizeof (oasys_ar_data_type
);
259 ar
= bfd_alloc (abfd
, amt
);
261 amt
= header
.mod_count
;
262 amt
*= sizeof (oasys_module_info_type
);
263 module
= bfd_alloc (abfd
, amt
);
268 abfd
->tdata
.oasys_ar_data
= ar
;
270 ar
->module_count
= header
.mod_count
;
272 filepos
= header
.mod_tbl_offset
;
273 for (i
= 0; i
< header
.mod_count
; i
++)
275 if (bfd_seek (abfd
, filepos
, SEEK_SET
) != 0)
278 /* There are two ways of specifying the archive header. */
280 oasys_extmodule_table_type_b_type record_ext
;
282 amt
= sizeof (record_ext
);
283 if (bfd_bread ((void *) &record_ext
, amt
, abfd
) != amt
)
286 record
.mod_size
= H_GET_32 (abfd
, record_ext
.mod_size
);
287 record
.file_offset
= H_GET_32 (abfd
, record_ext
.file_offset
);
289 record
.dep_count
= H_GET_32 (abfd
, record_ext
.dep_count
);
290 record
.depee_count
= H_GET_32 (abfd
, record_ext
.depee_count
);
291 record
.sect_count
= H_GET_32 (abfd
, record_ext
.sect_count
);
292 record
.module_name_size
= H_GET_32 (abfd
,
293 record_ext
.mod_name_length
);
295 amt
= record
.module_name_size
;
296 module
[i
].name
= bfd_alloc (abfd
, amt
+ 1);
299 if (bfd_bread ((void *) module
[i
].name
, amt
, abfd
) != amt
)
301 module
[i
].name
[record
.module_name_size
] = 0;
302 filepos
+= (sizeof (record_ext
)
303 + record
.dep_count
* 4
304 + record
.module_name_size
+ 1);
307 module
[i
].size
= record
.mod_size
;
308 module
[i
].pos
= record
.file_offset
;
316 oasys_mkobject (bfd
*abfd
)
318 bfd_size_type amt
= sizeof (oasys_data_type
);
320 abfd
->tdata
.oasys_obj_data
= bfd_alloc (abfd
, amt
);
322 return abfd
->tdata
.oasys_obj_data
!= NULL
;
325 /* The howto table is build using the top two bits of a reloc byte to
326 index into it. The bits are PCREL,WORD/LONG. */
328 static reloc_howto_type howto_table
[] =
331 HOWTO (0, 0, 1, 16, FALSE
, 0, complain_overflow_bitfield
, 0, "abs16", TRUE
, 0x0000ffff, 0x0000ffff, FALSE
),
332 HOWTO (0, 0, 2, 32, FALSE
, 0, complain_overflow_bitfield
, 0, "abs32", TRUE
, 0xffffffff, 0xffffffff, FALSE
),
333 HOWTO (0, 0, 1, 16, TRUE
, 0, complain_overflow_signed
, 0, "pcrel16", TRUE
, 0x0000ffff, 0x0000ffff, FALSE
),
334 HOWTO (0, 0, 2, 32, TRUE
, 0, complain_overflow_signed
, 0, "pcrel32", TRUE
, 0xffffffff, 0xffffffff, FALSE
)
337 /* Read in all the section data and relocation stuff too. */
340 oasys_slurp_section_data (bfd
*const abfd
)
342 oasys_record_union_type record
;
343 oasys_data_type
*data
= OASYS_DATA (abfd
);
344 bfd_boolean loop
= TRUE
;
345 oasys_per_section_type
*per
;
349 /* See if the data has been slurped already. */
350 for (s
= abfd
->sections
; s
!= NULL
; s
= s
->next
)
352 per
= oasys_per_section (s
);
353 if (per
->initialized
)
357 if (data
->first_data_record
== 0)
360 if (bfd_seek (abfd
, data
->first_data_record
, SEEK_SET
) != 0)
365 if (! oasys_read_record (abfd
, &record
))
368 switch (record
.header
.type
)
370 case oasys_record_is_header_enum
:
372 case oasys_record_is_data_enum
:
374 bfd_byte
*src
= record
.data
.data
;
375 bfd_byte
*end_src
= ((bfd_byte
*) & record
) + record
.header
.length
;
377 bfd_byte
*dst_base_ptr
;
381 data
->sections
[record
.data
.relb
& RELOCATION_SECT_BITS
];
384 per
= oasys_per_section (section
);
386 if (! per
->initialized
)
390 per
->data
= bfd_zalloc (abfd
, section
->size
);
393 relpp
= §ion
->relocation
;
394 per
->reloc_tail_ptr
= (oasys_reloc_type
**) relpp
;
395 per
->had_vma
= FALSE
;
396 per
->initialized
= TRUE
;
397 section
->reloc_count
= 0;
398 section
->flags
= SEC_ALLOC
;
401 dst_offset
= H_GET_32 (abfd
, record
.data
.addr
);
404 /* Take the first vma we see as the base. */
405 section
->vma
= dst_offset
;
409 dst_offset
-= section
->vma
;
411 dst_base_ptr
= oasys_per_section (section
)->data
;
412 dst_ptr
= oasys_per_section (section
)->data
+
416 section
->flags
|= SEC_LOAD
| SEC_HAS_CONTENTS
;
418 while (src
< end_src
)
420 unsigned char mod_byte
= *src
++;
421 size_t gap
= end_src
- src
;
424 if (mod_byte
== 0 && gap
>= 8)
439 for (relbit
= 1; count
-- != 0 && src
< end_src
; relbit
<<= 1)
441 if (relbit
& mod_byte
)
443 unsigned char reloc
= *src
;
444 /* This item needs to be relocated. */
445 switch (reloc
& RELOCATION_TYPE_BITS
)
447 case RELOCATION_TYPE_ABS
:
450 case RELOCATION_TYPE_REL
:
452 /* Relocate the item relative to the section. */
455 amt
= sizeof (oasys_reloc_type
);
456 r
= bfd_alloc (abfd
, amt
);
459 *(per
->reloc_tail_ptr
) = r
;
460 per
->reloc_tail_ptr
= &r
->next
;
462 /* Reference to undefined symbol. */
464 /* There is no symbol. */
466 /* Work out the howto. */
468 r
->relent
.address
= dst_ptr
- dst_base_ptr
;
469 r
->relent
.howto
= &howto_table
[reloc
>> 6];
470 r
->relent
.sym_ptr_ptr
= NULL
;
471 section
->reloc_count
++;
473 /* Fake up the data to look like
474 it's got the -ve pc in it, this
475 makes it much easier to convert
476 into other formats. This is done
477 by hitting the addend. */
478 if (r
->relent
.howto
->pc_relative
)
479 r
->relent
.addend
-= dst_ptr
- dst_base_ptr
;
483 case RELOCATION_TYPE_UND
:
487 amt
= sizeof (oasys_reloc_type
);
488 r
= bfd_alloc (abfd
, amt
);
491 *(per
->reloc_tail_ptr
) = r
;
492 per
->reloc_tail_ptr
= &r
->next
;
494 /* Reference to undefined symbol. */
496 /* Get symbol number. */
497 r
->symbol
= (src
[0] << 8) | src
[1];
498 /* Work out the howto. */
501 r
->relent
.addend
= 0;
502 r
->relent
.address
= dst_ptr
- dst_base_ptr
;
503 r
->relent
.howto
= &howto_table
[reloc
>> 6];
504 r
->relent
.sym_ptr_ptr
= NULL
;
505 section
->reloc_count
++;
508 /* Fake up the data to look like
509 it's got the -ve pc in it, this
510 makes it much easier to convert
511 into other formats. This is done
512 by hitting the addend. */
513 if (r
->relent
.howto
->pc_relative
)
514 r
->relent
.addend
-= dst_ptr
- dst_base_ptr
;
517 case RELOCATION_TYPE_COM
:
527 case oasys_record_is_local_enum
:
528 case oasys_record_is_symbol_enum
:
529 case oasys_record_is_section_enum
:
542 static const bfd_target
*
543 oasys_object_p (bfd
*abfd
)
545 oasys_data_type
*oasys
;
546 oasys_data_type
*save
= OASYS_DATA (abfd
);
547 bfd_boolean loop
= TRUE
;
548 bfd_boolean had_usefull
= FALSE
;
550 abfd
->tdata
.oasys_obj_data
= 0;
551 oasys_mkobject (abfd
);
552 oasys
= OASYS_DATA (abfd
);
553 memset ((void *) oasys
->sections
, 0xff, sizeof (oasys
->sections
));
555 /* Point to the start of the file. */
556 if (bfd_seek (abfd
, (file_ptr
) 0, SEEK_SET
) != 0)
558 oasys
->symbol_string_length
= 0;
560 /* Inspect the records, but only keep the section info -
561 remember the size of the symbols. */
562 oasys
->first_data_record
= 0;
565 oasys_record_union_type record
;
566 if (! oasys_read_record (abfd
, &record
))
568 if ((size_t) record
.header
.length
< (size_t) sizeof (record
.header
))
571 switch ((oasys_record_enum_type
) (record
.header
.type
))
573 case oasys_record_is_header_enum
:
576 case oasys_record_is_symbol_enum
:
577 case oasys_record_is_local_enum
:
578 /* Count symbols and remember their size for a future malloc. */
580 oasys
->symbol_string_length
+= 1 + oasys_string_length (&record
);
583 case oasys_record_is_section_enum
:
587 unsigned int section_number
;
589 if (record
.section
.header
.length
!= sizeof (record
.section
))
592 buffer
= bfd_alloc (abfd
, (bfd_size_type
) 3);
595 section_number
= record
.section
.relb
& RELOCATION_SECT_BITS
;
596 sprintf (buffer
, "%u", section_number
);
597 s
= bfd_make_section (abfd
, buffer
);
598 oasys
->sections
[section_number
] = s
;
599 switch (record
.section
.relb
& RELOCATION_TYPE_BITS
)
601 case RELOCATION_TYPE_ABS
:
602 case RELOCATION_TYPE_REL
:
604 case RELOCATION_TYPE_UND
:
605 case RELOCATION_TYPE_COM
:
609 s
->size
= H_GET_32 (abfd
, record
.section
.value
);
610 s
->vma
= H_GET_32 (abfd
, record
.section
.vma
);
615 case oasys_record_is_data_enum
:
616 oasys
->first_data_record
= bfd_tell (abfd
) - record
.header
.length
;
617 case oasys_record_is_debug_enum
:
618 case oasys_record_is_module_enum
:
619 case oasys_record_is_named_section_enum
:
620 case oasys_record_is_end_enum
:
629 oasys
->symbols
= NULL
;
631 /* Oasys support several architectures, but I can't see a simple way
632 to discover which one is in a particular file - we'll guess. */
633 bfd_default_set_arch_mach (abfd
, bfd_arch_m68k
, 0);
634 if (abfd
->symcount
!= 0)
635 abfd
->flags
|= HAS_SYMS
;
637 /* We don't know if a section has data until we've read it. */
638 oasys_slurp_section_data (abfd
);
643 (void) bfd_release (abfd
, oasys
);
644 abfd
->tdata
.oasys_obj_data
= save
;
650 oasys_get_symbol_info (bfd
*ignore_abfd ATTRIBUTE_UNUSED
,
654 bfd_symbol_info (symbol
, ret
);
656 if (!symbol
->section
)
657 ret
->type
= (symbol
->flags
& BSF_LOCAL
) ? 'a' : 'A';
661 oasys_print_symbol (bfd
*abfd
, void * afile
, asymbol
*symbol
, bfd_print_symbol_type how
)
663 FILE *file
= (FILE *) afile
;
667 case bfd_print_symbol_name
:
668 case bfd_print_symbol_more
:
669 fprintf (file
, "%s", symbol
->name
);
671 case bfd_print_symbol_all
:
673 const char *section_name
= symbol
->section
== NULL
?
674 (const char *) "*abs" : symbol
->section
->name
;
676 bfd_print_symbol_vandf (abfd
, (void *) file
, symbol
);
678 fprintf (file
, " %-5s %s",
687 oasys_new_section_hook (bfd
*abfd
, asection
*newsect
)
689 if (!newsect
->used_by_bfd
)
692 = bfd_alloc (abfd
, (bfd_size_type
) sizeof (oasys_per_section_type
));
693 if (!newsect
->used_by_bfd
)
696 oasys_per_section (newsect
)->data
= NULL
;
697 oasys_per_section (newsect
)->section
= newsect
;
698 oasys_per_section (newsect
)->offset
= 0;
699 oasys_per_section (newsect
)->initialized
= FALSE
;
700 newsect
->alignment_power
= 1;
702 /* Turn the section string into an index. */
703 sscanf (newsect
->name
, "%u", &newsect
->target_index
);
705 return _bfd_generic_new_section_hook (abfd
, newsect
);
710 oasys_get_reloc_upper_bound (bfd
*abfd
, sec_ptr asect
)
712 if (! oasys_slurp_section_data (abfd
))
714 return (asect
->reloc_count
+ 1) * sizeof (arelent
*);
718 oasys_get_section_contents (bfd
*abfd
,
724 oasys_per_section_type
*p
= oasys_per_section (section
);
726 oasys_slurp_section_data (abfd
);
728 if (! p
->initialized
)
729 (void) memset (location
, 0, (size_t) count
);
731 (void) memcpy (location
, (void *) (p
->data
+ offset
), (size_t) count
);
737 oasys_canonicalize_reloc (bfd
*ignore_abfd ATTRIBUTE_UNUSED
,
740 asymbol
**symbols ATTRIBUTE_UNUSED
)
742 unsigned int reloc_count
= 0;
743 oasys_reloc_type
*src
= (oasys_reloc_type
*) (section
->relocation
);
749 return section
->reloc_count
= reloc_count
;
755 /* Calculate the checksum and write one record. */
758 oasys_write_record (bfd
*abfd
,
759 oasys_record_enum_type type
,
760 oasys_record_union_type
*record
,
767 record
->header
.length
= size
;
768 record
->header
.type
= (int) type
;
769 record
->header
.check_sum
= 0;
770 record
->header
.fill
= 0;
771 ptr
= (unsigned char *) &record
->pad
[0];
773 for (i
= 0; i
< size
; i
++)
775 record
->header
.check_sum
= 0xff & (-checksum
);
776 if (bfd_bwrite ((void *) record
, (bfd_size_type
) size
, abfd
) != size
)
782 /* Write out all the symbols. */
785 oasys_write_syms (bfd
*abfd
)
788 asymbol
**generic
= bfd_get_outsymbols (abfd
);
789 unsigned int index
= 0;
791 for (count
= 0; count
< bfd_get_symcount (abfd
); count
++)
793 oasys_symbol_record_type symbol
;
794 asymbol
*const g
= generic
[count
];
795 const char *src
= g
->name
;
796 char *dst
= symbol
.name
;
799 if (bfd_is_com_section (g
->section
))
801 symbol
.relb
= RELOCATION_TYPE_COM
;
802 H_PUT_16 (abfd
, index
, symbol
.refno
);
805 else if (bfd_is_abs_section (g
->section
))
807 symbol
.relb
= RELOCATION_TYPE_ABS
;
808 H_PUT_16 (abfd
, 0, symbol
.refno
);
810 else if (bfd_is_und_section (g
->section
))
812 symbol
.relb
= RELOCATION_TYPE_UND
;
813 H_PUT_16 (abfd
, index
, symbol
.refno
);
814 /* Overload the value field with the output index number */
817 else if (g
->flags
& BSF_DEBUGGING
)
822 if (g
->section
== NULL
)
823 /* Sometime, the oasys tools give out a symbol with illegal
824 bits in it, we'll output it in the same broken way. */
825 symbol
.relb
= RELOCATION_TYPE_REL
| 0;
827 symbol
.relb
= RELOCATION_TYPE_REL
| g
->section
->output_section
->target_index
;
829 H_PUT_16 (abfd
, 0, symbol
.refno
);
832 #ifdef UNDERSCORE_HACK
842 H_PUT_32 (abfd
, g
->value
, symbol
.value
);
844 if (g
->flags
& BSF_LOCAL
)
846 if (! oasys_write_record (abfd
,
847 oasys_record_is_local_enum
,
848 (oasys_record_union_type
*) & symbol
,
849 offsetof (oasys_symbol_record_type
,
855 if (! oasys_write_record (abfd
,
856 oasys_record_is_symbol_enum
,
857 (oasys_record_union_type
*) & symbol
,
858 offsetof (oasys_symbol_record_type
,
862 g
->value
= index
- 1;
868 /* Write a section header for each section. */
871 oasys_write_sections (bfd
*abfd
)
874 static oasys_section_record_type out
;
876 for (s
= abfd
->sections
; s
!= NULL
; s
= s
->next
)
878 if (!ISDIGIT (s
->name
[0]))
880 (*_bfd_error_handler
)
881 (_("%s: can not represent section `%s' in oasys"),
882 bfd_get_filename (abfd
), s
->name
);
883 bfd_set_error (bfd_error_nonrepresentable_section
);
886 out
.relb
= RELOCATION_TYPE_REL
| s
->target_index
;
887 H_PUT_32 (abfd
, s
->size
, out
.value
);
888 H_PUT_32 (abfd
, s
->vma
, out
.vma
);
890 if (! oasys_write_record (abfd
,
891 oasys_record_is_section_enum
,
892 (oasys_record_union_type
*) & out
,
900 oasys_write_header (bfd
*abfd
)
902 /* Create and write the header. */
903 oasys_header_record_type r
;
904 size_t length
= strlen (abfd
->filename
);
906 if (length
> (size_t) sizeof (r
.module_name
))
907 length
= sizeof (r
.module_name
);
909 (void) memcpy (r
.module_name
, abfd
->filename
, length
);
910 (void) memset (r
.module_name
+ length
, ' ', sizeof (r
.module_name
) - length
);
912 r
.version_number
= OASYS_VERSION_NUMBER
;
913 r
.rev_number
= OASYS_REV_NUMBER
;
915 return oasys_write_record (abfd
, oasys_record_is_header_enum
,
916 (oasys_record_union_type
*) & r
,
917 offsetof (oasys_header_record_type
,
922 oasys_write_end (bfd
*abfd
)
924 oasys_end_record_type end
;
925 unsigned char null
= 0;
927 end
.relb
= RELOCATION_TYPE_ABS
;
928 H_PUT_32 (abfd
, abfd
->start_address
, end
.entry
);
929 H_PUT_16 (abfd
, 0, end
.fill
);
931 if (! oasys_write_record (abfd
,
932 oasys_record_is_end_enum
,
933 (oasys_record_union_type
*) & end
,
937 return bfd_bwrite ((void *) &null
, (bfd_size_type
) 1, abfd
) == 1;
941 comp (const void * ap
, const void * bp
)
943 arelent
*a
= *((arelent
**) ap
);
944 arelent
*b
= *((arelent
**) bp
);
946 return a
->address
- b
->address
;
950 oasys_write_data (bfd
*abfd
)
954 for (s
= abfd
->sections
; s
!= NULL
; s
= s
->next
)
956 if (s
->flags
& SEC_LOAD
)
958 bfd_byte
*raw_data
= oasys_per_section (s
)->data
;
959 oasys_data_record_type processed_data
;
960 bfd_size_type current_byte_index
= 0;
961 unsigned int relocs_to_go
= s
->reloc_count
;
962 arelent
**p
= s
->orelocation
;
964 if (s
->reloc_count
!= 0)
965 /* Sort the reloc records so it's easy to insert the relocs into the
967 qsort (s
->orelocation
, s
->reloc_count
, sizeof (arelent
**), comp
);
969 current_byte_index
= 0;
970 processed_data
.relb
= s
->target_index
| RELOCATION_TYPE_REL
;
972 while (current_byte_index
< s
->size
)
974 /* Scan forwards by eight bytes or however much is left and see if
975 there are any relocations going on. */
976 bfd_byte
*mod
= &processed_data
.data
[0];
977 bfd_byte
*dst
= &processed_data
.data
[1];
982 H_PUT_32 (abfd
, s
->vma
+ current_byte_index
,
983 processed_data
.addr
);
985 /* Don't start a relocation unless you're sure you can finish it
986 within the same data record. The worst case relocation is a
987 4-byte relocatable value which is split across two modification
988 bytes (1 relocation byte + 2 symbol reference bytes + 2 data +
989 1 modification byte + 2 data = 8 bytes total). That's where
990 the magic number 8 comes from. */
991 while (current_byte_index
< s
->size
&& dst
<=
992 & processed_data
.data
[sizeof (processed_data
.data
) - 8])
994 if (relocs_to_go
!= 0)
998 /* There is a relocation, is it for this byte ? */
999 if (r
->address
== current_byte_index
)
1003 /* If this is coming from an unloadable section then copy
1005 if (raw_data
== NULL
)
1008 *dst
++ = *raw_data
++;
1016 current_byte_index
++;
1019 /* Don't write a useless null modification byte. */
1023 if (! (oasys_write_record
1024 (abfd
, oasys_record_is_data_enum
,
1025 ((oasys_record_union_type
*) &processed_data
),
1026 (size_t) (dst
- (bfd_byte
*) &processed_data
))))
1036 oasys_write_object_contents (bfd
*abfd
)
1038 if (! oasys_write_header (abfd
))
1040 if (! oasys_write_syms (abfd
))
1042 if (! oasys_write_sections (abfd
))
1044 if (! oasys_write_data (abfd
))
1046 if (! oasys_write_end (abfd
))
1051 /* Set section contents is complicated with OASYS since the format is
1052 not a byte image, but a record stream. */
1055 oasys_set_section_contents (bfd
*abfd
,
1057 const void * location
,
1059 bfd_size_type count
)
1063 if (oasys_per_section (section
)->data
== NULL
)
1065 oasys_per_section (section
)->data
= bfd_alloc (abfd
, section
->size
);
1066 if (!oasys_per_section (section
)->data
)
1069 (void) memcpy ((void *) (oasys_per_section (section
)->data
+ offset
),
1070 location
, (size_t) count
);
1077 /* Native-level interface to symbols. */
1079 /* We read the symbols into a buffer, which is discarded when this
1080 function exits. We read the strings into a buffer large enough to
1081 hold them all plus all the cached symbol entries. */
1084 oasys_make_empty_symbol (bfd
*abfd
)
1086 bfd_size_type amt
= sizeof (oasys_symbol_type
);
1087 oasys_symbol_type
*new = bfd_zalloc (abfd
, amt
);
1091 new->symbol
.the_bfd
= abfd
;
1092 return &new->symbol
;
1095 /* User should have checked the file flags; perhaps we should return
1096 BFD_NO_MORE_SYMBOLS if there are none? */
1099 oasys_openr_next_archived_file (bfd
*arch
, bfd
*prev
)
1101 oasys_ar_data_type
*ar
= OASYS_AR_DATA (arch
);
1102 oasys_module_info_type
*p
;
1104 /* Take the next one from the arch state, or reset. */
1106 /* Reset the index - the first two entries are bogus. */
1107 ar
->module_index
= 0;
1109 p
= ar
->module
+ ar
->module_index
;
1112 if (ar
->module_index
<= ar
->module_count
)
1114 if (p
->abfd
== NULL
)
1116 p
->abfd
= _bfd_create_empty_archive_element_shell (arch
);
1117 p
->abfd
->origin
= p
->pos
;
1118 p
->abfd
->filename
= p
->name
;
1120 /* Fixup a pointer to this element for the member. */
1121 p
->abfd
->arelt_data
= (void *) p
;
1126 bfd_set_error (bfd_error_no_more_archived_files
);
1131 oasys_find_nearest_line (bfd
*abfd ATTRIBUTE_UNUSED
,
1132 asection
*section ATTRIBUTE_UNUSED
,
1133 asymbol
**symbols ATTRIBUTE_UNUSED
,
1134 bfd_vma offset ATTRIBUTE_UNUSED
,
1135 const char **filename_ptr ATTRIBUTE_UNUSED
,
1136 const char **functionname_ptr ATTRIBUTE_UNUSED
,
1137 unsigned int *line_ptr ATTRIBUTE_UNUSED
)
1143 oasys_find_inliner_info (bfd
*abfd ATTRIBUTE_UNUSED
,
1144 const char **filename_ptr ATTRIBUTE_UNUSED
,
1145 const char **functionname_ptr ATTRIBUTE_UNUSED
,
1146 unsigned int *line_ptr ATTRIBUTE_UNUSED
)
1152 oasys_generic_stat_arch_elt (bfd
*abfd
, struct stat
*buf
)
1154 oasys_module_info_type
*mod
= (oasys_module_info_type
*) abfd
->arelt_data
;
1158 bfd_set_error (bfd_error_invalid_operation
);
1162 buf
->st_size
= mod
->size
;
1163 buf
->st_mode
= 0666;
1168 oasys_sizeof_headers (bfd
*abfd ATTRIBUTE_UNUSED
,
1169 struct bfd_link_info
*info ATTRIBUTE_UNUSED
)
1174 #define oasys_close_and_cleanup _bfd_generic_close_and_cleanup
1175 #define oasys_bfd_free_cached_info _bfd_generic_bfd_free_cached_info
1176 #define oasys_slurp_armap bfd_true
1177 #define oasys_slurp_extended_name_table bfd_true
1178 #define oasys_construct_extended_name_table ((bfd_boolean (*) (bfd *, char **, bfd_size_type *, const char **)) bfd_true)
1179 #define oasys_truncate_arname bfd_dont_truncate_arname
1180 #define oasys_write_armap ((bfd_boolean (*) (bfd *, unsigned int, struct orl *, unsigned int, int)) bfd_true)
1181 #define oasys_read_ar_hdr bfd_nullvoidptr
1182 #define oasys_get_elt_at_index _bfd_generic_get_elt_at_index
1183 #define oasys_update_armap_timestamp bfd_true
1184 #define oasys_bfd_is_local_label_name bfd_generic_is_local_label_name
1185 #define oasys_bfd_is_target_special_symbol ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false)
1186 #define oasys_get_lineno _bfd_nosymbols_get_lineno
1187 #define oasys_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol
1188 #define oasys_read_minisymbols _bfd_generic_read_minisymbols
1189 #define oasys_minisymbol_to_symbol _bfd_generic_minisymbol_to_symbol
1190 #define oasys_bfd_reloc_type_lookup _bfd_norelocs_bfd_reloc_type_lookup
1191 #define oasys_bfd_reloc_name_lookup _bfd_norelocs_bfd_reloc_name_lookup
1192 #define oasys_set_arch_mach bfd_default_set_arch_mach
1193 #define oasys_get_section_contents_in_window _bfd_generic_get_section_contents_in_window
1194 #define oasys_bfd_get_relocated_section_contents bfd_generic_get_relocated_section_contents
1195 #define oasys_bfd_relax_section bfd_generic_relax_section
1196 #define oasys_bfd_gc_sections bfd_generic_gc_sections
1197 #define oasys_bfd_merge_sections bfd_generic_merge_sections
1198 #define oasys_bfd_is_group_section bfd_generic_is_group_section
1199 #define oasys_bfd_discard_group bfd_generic_discard_group
1200 #define oasys_section_already_linked _bfd_generic_section_already_linked
1201 #define oasys_bfd_define_common_symbol bfd_generic_define_common_symbol
1202 #define oasys_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
1203 #define oasys_bfd_link_hash_table_free _bfd_generic_link_hash_table_free
1204 #define oasys_bfd_link_add_symbols _bfd_generic_link_add_symbols
1205 #define oasys_bfd_link_just_syms _bfd_generic_link_just_syms
1206 #define oasys_bfd_final_link _bfd_generic_final_link
1207 #define oasys_bfd_link_split_section _bfd_generic_link_split_section
1209 const bfd_target oasys_vec
=
1211 "oasys", /* Name. */
1212 bfd_target_oasys_flavour
,
1213 BFD_ENDIAN_BIG
, /* Target byte order. */
1214 BFD_ENDIAN_BIG
, /* Target headers byte order. */
1215 (HAS_RELOC
| EXEC_P
| /* Object flags. */
1216 HAS_LINENO
| HAS_DEBUG
|
1217 HAS_SYMS
| HAS_LOCALS
| WP_TEXT
| D_PAGED
),
1218 (SEC_CODE
| SEC_DATA
| SEC_ROM
| SEC_HAS_CONTENTS
1219 | SEC_ALLOC
| SEC_LOAD
| SEC_RELOC
), /* Section flags. */
1220 0, /* Leading underscore. */
1221 ' ', /* AR_pad_char. */
1222 16, /* AR_max_namelen. */
1223 bfd_getb64
, bfd_getb_signed_64
, bfd_putb64
,
1224 bfd_getb32
, bfd_getb_signed_32
, bfd_putb32
,
1225 bfd_getb16
, bfd_getb_signed_16
, bfd_putb16
, /* Data. */
1226 bfd_getb64
, bfd_getb_signed_64
, bfd_putb64
,
1227 bfd_getb32
, bfd_getb_signed_32
, bfd_putb32
,
1228 bfd_getb16
, bfd_getb_signed_16
, bfd_putb16
, /* Headers. */
1231 oasys_object_p
, /* bfd_check_format. */
1235 { /* bfd_set_format. */
1238 _bfd_generic_mkarchive
,
1241 { /* bfd_write_contents. */
1243 oasys_write_object_contents
,
1244 _bfd_write_archive_contents
,
1248 BFD_JUMP_TABLE_GENERIC (oasys
),
1249 BFD_JUMP_TABLE_COPY (_bfd_generic
),
1250 BFD_JUMP_TABLE_CORE (_bfd_nocore
),
1251 BFD_JUMP_TABLE_ARCHIVE (oasys
),
1252 BFD_JUMP_TABLE_SYMBOLS (oasys
),
1253 BFD_JUMP_TABLE_RELOCS (oasys
),
1254 BFD_JUMP_TABLE_WRITE (oasys
),
1255 BFD_JUMP_TABLE_LINK (oasys
),
1256 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic
),