1 |
/* BFD back-end for oasys objects. |
/* BFD back-end for oasys objects. |
2 |
Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2001, 2002 |
Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2001, |
3 |
Free Software Foundation, Inc. |
2002, 2003, 2004, 2005 Free Software Foundation, Inc. |
4 |
Written by Steve Chamberlain of Cygnus Support, <sac@cygnus.com>. |
Written by Steve Chamberlain of Cygnus Support, <sac@cygnus.com>. |
5 |
|
|
6 |
This file is part of BFD, the Binary File Descriptor library. |
This file is part of BFD, the Binary File Descriptor library. |
27 |
#include "oasys.h" |
#include "oasys.h" |
28 |
#include "liboasys.h" |
#include "liboasys.h" |
29 |
|
|
30 |
static boolean oasys_slurp_section_data PARAMS ((bfd * const)); |
static bfd_boolean oasys_slurp_section_data |
31 |
static boolean oasys_read_record PARAMS ((bfd *, oasys_record_union_type *)); |
PARAMS ((bfd * const)); |
32 |
static boolean oasys_write_sections PARAMS ((bfd *)); |
static bfd_boolean oasys_read_record |
33 |
static boolean oasys_write_record |
PARAMS ((bfd *, oasys_record_union_type *)); |
34 |
|
static bfd_boolean oasys_write_sections |
35 |
|
PARAMS ((bfd *)); |
36 |
|
static bfd_boolean oasys_write_record |
37 |
PARAMS ((bfd *, oasys_record_enum_type, oasys_record_union_type *, size_t)); |
PARAMS ((bfd *, oasys_record_enum_type, oasys_record_union_type *, size_t)); |
38 |
static boolean oasys_write_syms PARAMS ((bfd *)); |
static bfd_boolean oasys_write_syms |
39 |
static boolean oasys_write_header PARAMS ((bfd *)); |
PARAMS ((bfd *)); |
40 |
static boolean oasys_write_end PARAMS ((bfd *)); |
static bfd_boolean oasys_write_header |
41 |
static boolean oasys_write_data PARAMS ((bfd *)); |
PARAMS ((bfd *)); |
42 |
static size_t oasys_string_length PARAMS ((oasys_record_union_type *)); |
static bfd_boolean oasys_write_end |
43 |
static boolean oasys_slurp_symbol_table PARAMS ((bfd *const)); |
PARAMS ((bfd *)); |
44 |
static long int oasys_get_symtab_upper_bound PARAMS ((bfd *const)); |
static bfd_boolean oasys_write_data |
45 |
static const bfd_target *oasys_archive_p PARAMS ((bfd *)); |
PARAMS ((bfd *)); |
46 |
static boolean oasys_mkobject PARAMS ((bfd *)); |
static size_t oasys_string_length |
47 |
static const bfd_target *oasys_object_p PARAMS ((bfd *)); |
PARAMS ((oasys_record_union_type *)); |
48 |
static void oasys_get_symbol_info PARAMS ((bfd *, asymbol *, symbol_info *)); |
static bfd_boolean oasys_slurp_symbol_table |
49 |
|
PARAMS ((bfd *const)); |
50 |
|
static long int oasys_get_symtab_upper_bound |
51 |
|
PARAMS ((bfd *const)); |
52 |
|
static const bfd_target *oasys_archive_p |
53 |
|
PARAMS ((bfd *)); |
54 |
|
static bfd_boolean oasys_mkobject |
55 |
|
PARAMS ((bfd *)); |
56 |
|
static const bfd_target *oasys_object_p |
57 |
|
PARAMS ((bfd *)); |
58 |
|
static void oasys_get_symbol_info |
59 |
|
PARAMS ((bfd *, asymbol *, symbol_info *)); |
60 |
static void oasys_print_symbol |
static void oasys_print_symbol |
61 |
PARAMS ((bfd *, void *, asymbol *, bfd_print_symbol_type)); |
PARAMS ((bfd *, void *, asymbol *, bfd_print_symbol_type)); |
62 |
static boolean oasys_new_section_hook PARAMS ((bfd *, asection *)); |
static bfd_boolean oasys_new_section_hook |
63 |
static long int oasys_get_reloc_upper_bound PARAMS ((bfd *, sec_ptr)); |
PARAMS ((bfd *, asection *)); |
64 |
static boolean oasys_get_section_contents |
static long int oasys_get_reloc_upper_bound |
65 |
|
PARAMS ((bfd *, sec_ptr)); |
66 |
|
static bfd_boolean oasys_get_section_contents |
67 |
PARAMS ((bfd *, sec_ptr, void *, file_ptr, bfd_size_type)); |
PARAMS ((bfd *, sec_ptr, void *, file_ptr, bfd_size_type)); |
68 |
static int comp PARAMS ((const void *, const void *)); |
static int comp |
69 |
static boolean oasys_write_object_contents PARAMS ((bfd *)); |
PARAMS ((const void *, const void *)); |
70 |
static boolean oasys_set_section_contents |
static bfd_boolean oasys_write_object_contents |
71 |
PARAMS ((bfd *, sec_ptr, void *, file_ptr, bfd_size_type)); |
PARAMS ((bfd *)); |
72 |
static asymbol *oasys_make_empty_symbol PARAMS ((bfd *)); |
static bfd_boolean oasys_set_section_contents |
73 |
static bfd *oasys_openr_next_archived_file PARAMS ((bfd *, bfd *)); |
PARAMS ((bfd *, sec_ptr, const void *, file_ptr, bfd_size_type)); |
74 |
static boolean oasys_find_nearest_line |
static asymbol *oasys_make_empty_symbol |
75 |
|
PARAMS ((bfd *)); |
76 |
|
static bfd *oasys_openr_next_archived_file |
77 |
|
PARAMS ((bfd *, bfd *)); |
78 |
|
static bfd_boolean oasys_find_nearest_line |
79 |
PARAMS ((bfd *, asection *, asymbol **, bfd_vma, |
PARAMS ((bfd *, asection *, asymbol **, bfd_vma, |
80 |
const char **, const char **, unsigned int *)); |
const char **, const char **, unsigned int *)); |
81 |
static int oasys_generic_stat_arch_elt PARAMS ((bfd *, struct stat *)); |
static int oasys_generic_stat_arch_elt |
82 |
static int oasys_sizeof_headers PARAMS ((bfd *, boolean)); |
PARAMS ((bfd *, struct stat *)); |
83 |
|
static int oasys_sizeof_headers |
84 |
|
PARAMS ((bfd *, bfd_boolean)); |
85 |
|
|
86 |
long oasys_get_symtab PARAMS ((bfd *, asymbol **)); |
long oasys_canonicalize_symtab |
87 |
|
PARAMS ((bfd *, asymbol **)); |
88 |
long oasys_canonicalize_reloc |
long oasys_canonicalize_reloc |
89 |
PARAMS ((bfd *, sec_ptr, arelent **, asymbol **)); |
PARAMS ((bfd *, sec_ptr, arelent **, asymbol **)); |
90 |
|
|
91 |
/* Read in all the section data and relocation stuff too. */ |
/* Read in all the section data and relocation stuff too. */ |
92 |
|
|
93 |
static boolean |
static bfd_boolean |
94 |
oasys_read_record (abfd, record) |
oasys_read_record (abfd, record) |
95 |
bfd *abfd; |
bfd *abfd; |
96 |
oasys_record_union_type *record; |
oasys_record_union_type *record; |
97 |
{ |
{ |
98 |
bfd_size_type amt = sizeof (record->header); |
bfd_size_type amt = sizeof (record->header); |
99 |
if (bfd_bread ((PTR) record, amt, abfd) != amt) |
if (bfd_bread ((PTR) record, amt, abfd) != amt) |
100 |
return false; |
return FALSE; |
101 |
|
|
102 |
amt = record->header.length - sizeof (record->header); |
amt = record->header.length - sizeof (record->header); |
103 |
if ((long) amt <= 0) |
if ((long) amt <= 0) |
104 |
return true; |
return TRUE; |
105 |
if (bfd_bread ((PTR) ((char *) record + sizeof (record->header)), amt, abfd) |
if (bfd_bread ((PTR) ((char *) record + sizeof (record->header)), amt, abfd) |
106 |
!= amt) |
!= amt) |
107 |
return false; |
return FALSE; |
108 |
return true; |
return TRUE; |
109 |
} |
} |
110 |
|
|
111 |
static size_t |
static size_t |
132 |
|
|
133 |
*/ |
*/ |
134 |
|
|
135 |
static boolean |
static bfd_boolean |
136 |
oasys_slurp_symbol_table (abfd) |
oasys_slurp_symbol_table (abfd) |
137 |
bfd *const abfd; |
bfd *const abfd; |
138 |
{ |
{ |
139 |
oasys_record_union_type record; |
oasys_record_union_type record; |
140 |
oasys_data_type *data = OASYS_DATA (abfd); |
oasys_data_type *data = OASYS_DATA (abfd); |
141 |
boolean loop = true; |
bfd_boolean loop = TRUE; |
142 |
asymbol *dest_defined; |
asymbol *dest_defined; |
143 |
asymbol *dest; |
asymbol *dest; |
144 |
char *string_ptr; |
char *string_ptr; |
146 |
|
|
147 |
if (data->symbols != (asymbol *) NULL) |
if (data->symbols != (asymbol *) NULL) |
148 |
{ |
{ |
149 |
return true; |
return TRUE; |
150 |
} |
} |
151 |
/* Buy enough memory for all the symbols and all the names */ |
/* Buy enough memory for all the symbols and all the names */ |
152 |
amt = abfd->symcount; |
amt = abfd->symcount; |
161 |
data->strings = bfd_alloc (abfd, amt); |
data->strings = bfd_alloc (abfd, amt); |
162 |
|
|
163 |
if (!data->symbols || !data->strings) |
if (!data->symbols || !data->strings) |
164 |
return false; |
return FALSE; |
165 |
|
|
166 |
dest_defined = data->symbols + abfd->symcount - 1; |
dest_defined = data->symbols + abfd->symcount - 1; |
167 |
|
|
168 |
string_ptr = data->strings; |
string_ptr = data->strings; |
169 |
if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0) |
if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0) |
170 |
return false; |
return FALSE; |
171 |
while (loop) |
while (loop) |
172 |
{ |
{ |
173 |
|
|
174 |
if (! oasys_read_record (abfd, &record)) |
if (! oasys_read_record (abfd, &record)) |
175 |
return false; |
return FALSE; |
176 |
switch (record.header.type) |
switch (record.header.type) |
177 |
{ |
{ |
178 |
case oasys_record_is_header_enum: |
case oasys_record_is_header_enum: |
252 |
} |
} |
253 |
break; |
break; |
254 |
default: |
default: |
255 |
loop = false; |
loop = FALSE; |
256 |
} |
} |
257 |
} |
} |
258 |
return true; |
return TRUE; |
259 |
} |
} |
260 |
|
|
261 |
static long |
static long |
271 |
extern const bfd_target oasys_vec; |
extern const bfd_target oasys_vec; |
272 |
|
|
273 |
long |
long |
274 |
oasys_get_symtab (abfd, location) |
oasys_canonicalize_symtab (abfd, location) |
275 |
bfd *abfd; |
bfd *abfd; |
276 |
asymbol **location; |
asymbol **location; |
277 |
{ |
{ |
324 |
|
|
325 |
/* |
/* |
326 |
There isn't a magic number in an Oasys archive, so the best we |
There isn't a magic number in an Oasys archive, so the best we |
327 |
can do to verify reasnableness is to make sure that the values in |
can do to verify reasonableness is to make sure that the values in |
328 |
the header are too weird |
the header are too weird |
329 |
*/ |
*/ |
330 |
|
|
428 |
return abfd->xvec; |
return abfd->xvec; |
429 |
} |
} |
430 |
|
|
431 |
static boolean |
static bfd_boolean |
432 |
oasys_mkobject (abfd) |
oasys_mkobject (abfd) |
433 |
bfd *abfd; |
bfd *abfd; |
434 |
{ |
{ |
444 |
{ |
{ |
445 |
oasys_data_type *oasys; |
oasys_data_type *oasys; |
446 |
oasys_data_type *save = OASYS_DATA (abfd); |
oasys_data_type *save = OASYS_DATA (abfd); |
447 |
boolean loop = true; |
bfd_boolean loop = TRUE; |
448 |
boolean had_usefull = false; |
bfd_boolean had_usefull = FALSE; |
449 |
|
|
450 |
abfd->tdata.oasys_obj_data = 0; |
abfd->tdata.oasys_obj_data = 0; |
451 |
oasys_mkobject (abfd); |
oasys_mkobject (abfd); |
472 |
switch ((oasys_record_enum_type) (record.header.type)) |
switch ((oasys_record_enum_type) (record.header.type)) |
473 |
{ |
{ |
474 |
case oasys_record_is_header_enum: |
case oasys_record_is_header_enum: |
475 |
had_usefull = true; |
had_usefull = TRUE; |
476 |
break; |
break; |
477 |
case oasys_record_is_symbol_enum: |
case oasys_record_is_symbol_enum: |
478 |
case oasys_record_is_local_enum: |
case oasys_record_is_local_enum: |
479 |
/* Count symbols and remember their size for a future malloc */ |
/* Count symbols and remember their size for a future malloc */ |
480 |
abfd->symcount++; |
abfd->symcount++; |
481 |
oasys->symbol_string_length += 1 + oasys_string_length (&record); |
oasys->symbol_string_length += 1 + oasys_string_length (&record); |
482 |
had_usefull = true; |
had_usefull = TRUE; |
483 |
break; |
break; |
484 |
case oasys_record_is_section_enum: |
case oasys_record_is_section_enum: |
485 |
{ |
{ |
507 |
BFD_FAIL (); |
BFD_FAIL (); |
508 |
} |
} |
509 |
|
|
510 |
s->_raw_size = H_GET_32 (abfd, record.section.value); |
s->size = H_GET_32 (abfd, record.section.value); |
511 |
s->vma = H_GET_32 (abfd, record.section.vma); |
s->vma = H_GET_32 (abfd, record.section.vma); |
512 |
s->flags = 0; |
s->flags = 0; |
513 |
had_usefull = true; |
had_usefull = TRUE; |
514 |
} |
} |
515 |
break; |
break; |
516 |
case oasys_record_is_data_enum: |
case oasys_record_is_data_enum: |
521 |
case oasys_record_is_end_enum: |
case oasys_record_is_end_enum: |
522 |
if (! had_usefull) |
if (! had_usefull) |
523 |
goto fail; |
goto fail; |
524 |
loop = false; |
loop = FALSE; |
525 |
break; |
break; |
526 |
default: |
default: |
527 |
goto fail; |
goto fail; |
601 |
static reloc_howto_type howto_table[] = |
static reloc_howto_type howto_table[] = |
602 |
{ |
{ |
603 |
|
|
604 |
HOWTO (0, 0, 1, 16, false, 0, complain_overflow_bitfield, 0, "abs16", true, 0x0000ffff, 0x0000ffff, false), |
HOWTO (0, 0, 1, 16, FALSE, 0, complain_overflow_bitfield, 0, "abs16", TRUE, 0x0000ffff, 0x0000ffff, FALSE), |
605 |
HOWTO (0, 0, 2, 32, false, 0, complain_overflow_bitfield, 0, "abs32", true, 0xffffffff, 0xffffffff, false), |
HOWTO (0, 0, 2, 32, FALSE, 0, complain_overflow_bitfield, 0, "abs32", TRUE, 0xffffffff, 0xffffffff, FALSE), |
606 |
HOWTO (0, 0, 1, 16, true, 0, complain_overflow_signed, 0, "pcrel16", true, 0x0000ffff, 0x0000ffff, false), |
HOWTO (0, 0, 1, 16, TRUE, 0, complain_overflow_signed, 0, "pcrel16", TRUE, 0x0000ffff, 0x0000ffff, FALSE), |
607 |
HOWTO (0, 0, 2, 32, true, 0, complain_overflow_signed, 0, "pcrel32", true, 0xffffffff, 0xffffffff, false) |
HOWTO (0, 0, 2, 32, TRUE, 0, complain_overflow_signed, 0, "pcrel32", TRUE, 0xffffffff, 0xffffffff, FALSE) |
608 |
}; |
}; |
609 |
|
|
610 |
/* Read in all the section data and relocation stuff too */ |
/* Read in all the section data and relocation stuff too */ |
611 |
static boolean |
static bfd_boolean |
612 |
oasys_slurp_section_data (abfd) |
oasys_slurp_section_data (abfd) |
613 |
bfd *const abfd; |
bfd *const abfd; |
614 |
{ |
{ |
615 |
oasys_record_union_type record; |
oasys_record_union_type record; |
616 |
oasys_data_type *data = OASYS_DATA (abfd); |
oasys_data_type *data = OASYS_DATA (abfd); |
617 |
boolean loop = true; |
bfd_boolean loop = TRUE; |
618 |
oasys_per_section_type *per; |
oasys_per_section_type *per; |
619 |
asection *s; |
asection *s; |
620 |
bfd_size_type amt; |
bfd_size_type amt; |
624 |
{ |
{ |
625 |
per = oasys_per_section (s); |
per = oasys_per_section (s); |
626 |
if (per->initialized) |
if (per->initialized) |
627 |
return true; |
return TRUE; |
628 |
} |
} |
629 |
|
|
630 |
if (data->first_data_record == 0) |
if (data->first_data_record == 0) |
631 |
return true; |
return TRUE; |
632 |
|
|
633 |
if (bfd_seek (abfd, data->first_data_record, SEEK_SET) != 0) |
if (bfd_seek (abfd, data->first_data_record, SEEK_SET) != 0) |
634 |
return false; |
return FALSE; |
635 |
while (loop) |
while (loop) |
636 |
{ |
{ |
637 |
if (! oasys_read_record (abfd, &record)) |
if (! oasys_read_record (abfd, &record)) |
638 |
return false; |
return FALSE; |
639 |
switch (record.header.type) |
switch (record.header.type) |
640 |
{ |
{ |
641 |
case oasys_record_is_header_enum: |
case oasys_record_is_header_enum: |
657 |
|
|
658 |
if (! per->initialized) |
if (! per->initialized) |
659 |
{ |
{ |
660 |
per->data = (bfd_byte *) bfd_zalloc (abfd, section->_raw_size); |
per->data = (bfd_byte *) bfd_zalloc (abfd, section->size); |
661 |
if (!per->data) |
if (!per->data) |
662 |
return false; |
return FALSE; |
663 |
per->reloc_tail_ptr |
per->reloc_tail_ptr |
664 |
= (oasys_reloc_type **) §ion->relocation; |
= (oasys_reloc_type **) §ion->relocation; |
665 |
per->had_vma = false; |
per->had_vma = FALSE; |
666 |
per->initialized = true; |
per->initialized = TRUE; |
667 |
section->reloc_count = 0; |
section->reloc_count = 0; |
668 |
section->flags = SEC_ALLOC; |
section->flags = SEC_ALLOC; |
669 |
} |
} |
673 |
{ |
{ |
674 |
/* Take the first vma we see as the base */ |
/* Take the first vma we see as the base */ |
675 |
section->vma = dst_offset; |
section->vma = dst_offset; |
676 |
per->had_vma = true; |
per->had_vma = TRUE; |
677 |
} |
} |
678 |
|
|
679 |
dst_offset -= section->vma; |
dst_offset -= section->vma; |
728 |
r = (oasys_reloc_type *) bfd_alloc (abfd, |
r = (oasys_reloc_type *) bfd_alloc (abfd, |
729 |
amt); |
amt); |
730 |
if (!r) |
if (!r) |
731 |
return false; |
return FALSE; |
732 |
*(per->reloc_tail_ptr) = r; |
*(per->reloc_tail_ptr) = r; |
733 |
per->reloc_tail_ptr = &r->next; |
per->reloc_tail_ptr = &r->next; |
734 |
r->next = (oasys_reloc_type *) NULL; |
r->next = (oasys_reloc_type *) NULL; |
738 |
r->symbol = 0; |
r->symbol = 0; |
739 |
/* Work out the howto */ |
/* Work out the howto */ |
740 |
abort (); |
abort (); |
|
#if 0 |
|
|
r->relent.section = |
|
|
data->sections[reloc & |
|
|
RELOCATION_SECT_BITS]; |
|
|
|
|
|
r->relent.addend = - |
|
|
r->relent.section->vma; |
|
|
#endif |
|
741 |
r->relent.address = dst_ptr - dst_base_ptr; |
r->relent.address = dst_ptr - dst_base_ptr; |
742 |
r->relent.howto = &howto_table[reloc >> 6]; |
r->relent.howto = &howto_table[reloc >> 6]; |
743 |
r->relent.sym_ptr_ptr = (asymbol **) NULL; |
r->relent.sym_ptr_ptr = (asymbol **) NULL; |
762 |
r = (oasys_reloc_type *) bfd_alloc (abfd, |
r = (oasys_reloc_type *) bfd_alloc (abfd, |
763 |
amt); |
amt); |
764 |
if (!r) |
if (!r) |
765 |
return false; |
return FALSE; |
766 |
*(per->reloc_tail_ptr) = r; |
*(per->reloc_tail_ptr) = r; |
767 |
per->reloc_tail_ptr = &r->next; |
per->reloc_tail_ptr = &r->next; |
768 |
r->next = (oasys_reloc_type *) NULL; |
r->next = (oasys_reloc_type *) NULL; |
773 |
/* Work out the howto */ |
/* Work out the howto */ |
774 |
abort (); |
abort (); |
775 |
|
|
|
#if 0 |
|
|
r->relent.section = (asection |
|
|
*) NULL; |
|
|
#endif |
|
776 |
r->relent.addend = 0; |
r->relent.addend = 0; |
777 |
r->relent.address = dst_ptr - dst_base_ptr; |
r->relent.address = dst_ptr - dst_base_ptr; |
778 |
r->relent.howto = &howto_table[reloc >> 6]; |
r->relent.howto = &howto_table[reloc >> 6]; |
804 |
case oasys_record_is_section_enum: |
case oasys_record_is_section_enum: |
805 |
break; |
break; |
806 |
default: |
default: |
807 |
loop = false; |
loop = FALSE; |
808 |
} |
} |
809 |
} |
} |
810 |
|
|
811 |
return true; |
return TRUE; |
812 |
|
|
813 |
} |
} |
814 |
|
|
815 |
static boolean |
static bfd_boolean |
816 |
oasys_new_section_hook (abfd, newsect) |
oasys_new_section_hook (abfd, newsect) |
817 |
bfd *abfd; |
bfd *abfd; |
818 |
asection *newsect; |
asection *newsect; |
820 |
newsect->used_by_bfd = (PTR) |
newsect->used_by_bfd = (PTR) |
821 |
bfd_alloc (abfd, (bfd_size_type) sizeof (oasys_per_section_type)); |
bfd_alloc (abfd, (bfd_size_type) sizeof (oasys_per_section_type)); |
822 |
if (!newsect->used_by_bfd) |
if (!newsect->used_by_bfd) |
823 |
return false; |
return FALSE; |
824 |
oasys_per_section (newsect)->data = (bfd_byte *) NULL; |
oasys_per_section (newsect)->data = (bfd_byte *) NULL; |
825 |
oasys_per_section (newsect)->section = newsect; |
oasys_per_section (newsect)->section = newsect; |
826 |
oasys_per_section (newsect)->offset = 0; |
oasys_per_section (newsect)->offset = 0; |
827 |
oasys_per_section (newsect)->initialized = false; |
oasys_per_section (newsect)->initialized = FALSE; |
828 |
newsect->alignment_power = 1; |
newsect->alignment_power = 1; |
829 |
/* Turn the section string into an index */ |
/* Turn the section string into an index */ |
830 |
|
|
831 |
sscanf (newsect->name, "%u", &newsect->target_index); |
sscanf (newsect->name, "%u", &newsect->target_index); |
832 |
|
|
833 |
return true; |
return TRUE; |
834 |
} |
} |
835 |
|
|
836 |
|
|
844 |
return (asect->reloc_count + 1) * sizeof (arelent *); |
return (asect->reloc_count + 1) * sizeof (arelent *); |
845 |
} |
} |
846 |
|
|
847 |
static boolean |
static bfd_boolean |
848 |
oasys_get_section_contents (abfd, section, location, offset, count) |
oasys_get_section_contents (abfd, section, location, offset, count) |
849 |
bfd *abfd; |
bfd *abfd; |
850 |
sec_ptr section; |
sec_ptr section; |
852 |
file_ptr offset; |
file_ptr offset; |
853 |
bfd_size_type count; |
bfd_size_type count; |
854 |
{ |
{ |
855 |
oasys_per_section_type *p = (oasys_per_section_type *) section->used_by_bfd; |
oasys_per_section_type *p = oasys_per_section (section); |
856 |
oasys_slurp_section_data (abfd); |
oasys_slurp_section_data (abfd); |
857 |
if (! p->initialized) |
if (! p->initialized) |
858 |
{ |
{ |
862 |
{ |
{ |
863 |
(void) memcpy (location, (PTR) (p->data + offset), (size_t) count); |
(void) memcpy (location, (PTR) (p->data + offset), (size_t) count); |
864 |
} |
} |
865 |
return true; |
return TRUE; |
866 |
} |
} |
867 |
|
|
868 |
|
|
879 |
{ |
{ |
880 |
abort (); |
abort (); |
881 |
|
|
|
#if 0 |
|
|
if (src->relent.section == (asection *) NULL) |
|
|
{ |
|
|
src->relent.sym_ptr_ptr = symbols + src->symbol; |
|
|
} |
|
|
#endif |
|
|
|
|
882 |
*relptr++ = &src->relent; |
*relptr++ = &src->relent; |
883 |
src = src->next; |
src = src->next; |
884 |
reloc_count++; |
reloc_count++; |
894 |
|
|
895 |
|
|
896 |
/* Calculate the checksum and write one record */ |
/* Calculate the checksum and write one record */ |
897 |
static boolean |
static bfd_boolean |
898 |
oasys_write_record (abfd, type, record, size) |
oasys_write_record (abfd, type, record, size) |
899 |
bfd *abfd; |
bfd *abfd; |
900 |
oasys_record_enum_type type; |
oasys_record_enum_type type; |
917 |
} |
} |
918 |
record->header.check_sum = 0xff & (-checksum); |
record->header.check_sum = 0xff & (-checksum); |
919 |
if (bfd_bwrite ((PTR) record, (bfd_size_type) size, abfd) != size) |
if (bfd_bwrite ((PTR) record, (bfd_size_type) size, abfd) != size) |
920 |
return false; |
return FALSE; |
921 |
return true; |
return TRUE; |
922 |
} |
} |
923 |
|
|
924 |
|
|
925 |
/* Write out all the symbols */ |
/* Write out all the symbols */ |
926 |
static boolean |
static bfd_boolean |
927 |
oasys_write_syms (abfd) |
oasys_write_syms (abfd) |
928 |
bfd *abfd; |
bfd *abfd; |
929 |
{ |
{ |
999 |
(oasys_record_union_type *) & symbol, |
(oasys_record_union_type *) & symbol, |
1000 |
offsetof (oasys_symbol_record_type, |
offsetof (oasys_symbol_record_type, |
1001 |
name[0]) + l)) |
name[0]) + l)) |
1002 |
return false; |
return FALSE; |
1003 |
} |
} |
1004 |
else |
else |
1005 |
{ |
{ |
1008 |
(oasys_record_union_type *) & symbol, |
(oasys_record_union_type *) & symbol, |
1009 |
offsetof (oasys_symbol_record_type, |
offsetof (oasys_symbol_record_type, |
1010 |
name[0]) + l)) |
name[0]) + l)) |
1011 |
return false; |
return FALSE; |
1012 |
} |
} |
1013 |
g->value = index - 1; |
g->value = index - 1; |
1014 |
} |
} |
1015 |
|
|
1016 |
return true; |
return TRUE; |
1017 |
} |
} |
1018 |
|
|
1019 |
|
|
1020 |
/* Write a section header for each section */ |
/* Write a section header for each section */ |
1021 |
static boolean |
static bfd_boolean |
1022 |
oasys_write_sections (abfd) |
oasys_write_sections (abfd) |
1023 |
bfd *abfd; |
bfd *abfd; |
1024 |
{ |
{ |
1033 |
(_("%s: can not represent section `%s' in oasys"), |
(_("%s: can not represent section `%s' in oasys"), |
1034 |
bfd_get_filename (abfd), s->name); |
bfd_get_filename (abfd), s->name); |
1035 |
bfd_set_error (bfd_error_nonrepresentable_section); |
bfd_set_error (bfd_error_nonrepresentable_section); |
1036 |
return false; |
return FALSE; |
1037 |
} |
} |
1038 |
out.relb = RELOCATION_TYPE_REL | s->target_index; |
out.relb = RELOCATION_TYPE_REL | s->target_index; |
1039 |
H_PUT_32 (abfd, s->_cooked_size, out.value); |
H_PUT_32 (abfd, s->size, out.value); |
1040 |
H_PUT_32 (abfd, s->vma, out.vma); |
H_PUT_32 (abfd, s->vma, out.vma); |
1041 |
|
|
1042 |
if (! oasys_write_record (abfd, |
if (! oasys_write_record (abfd, |
1043 |
oasys_record_is_section_enum, |
oasys_record_is_section_enum, |
1044 |
(oasys_record_union_type *) & out, |
(oasys_record_union_type *) & out, |
1045 |
sizeof (out))) |
sizeof (out))) |
1046 |
return false; |
return FALSE; |
1047 |
} |
} |
1048 |
return true; |
return TRUE; |
1049 |
} |
} |
1050 |
|
|
1051 |
static boolean |
static bfd_boolean |
1052 |
oasys_write_header (abfd) |
oasys_write_header (abfd) |
1053 |
bfd *abfd; |
bfd *abfd; |
1054 |
{ |
{ |
1074 |
(oasys_record_union_type *) & r, |
(oasys_record_union_type *) & r, |
1075 |
offsetof (oasys_header_record_type, |
offsetof (oasys_header_record_type, |
1076 |
description[0]))) |
description[0]))) |
1077 |
return false; |
return FALSE; |
1078 |
|
|
1079 |
return true; |
return TRUE; |
1080 |
} |
} |
1081 |
|
|
1082 |
static boolean |
static bfd_boolean |
1083 |
oasys_write_end (abfd) |
oasys_write_end (abfd) |
1084 |
bfd *abfd; |
bfd *abfd; |
1085 |
{ |
{ |
1093 |
oasys_record_is_end_enum, |
oasys_record_is_end_enum, |
1094 |
(oasys_record_union_type *) & end, |
(oasys_record_union_type *) & end, |
1095 |
sizeof (end))) |
sizeof (end))) |
1096 |
return false; |
return FALSE; |
1097 |
if (bfd_bwrite ((PTR) &null, (bfd_size_type) 1, abfd) != 1) |
if (bfd_bwrite ((PTR) &null, (bfd_size_type) 1, abfd) != 1) |
1098 |
return false; |
return FALSE; |
1099 |
return true; |
return TRUE; |
1100 |
} |
} |
1101 |
|
|
1102 |
static int |
static int |
1113 |
Writing data.. |
Writing data.. |
1114 |
|
|
1115 |
*/ |
*/ |
1116 |
static boolean |
static bfd_boolean |
1117 |
oasys_write_data (abfd) |
oasys_write_data (abfd) |
1118 |
bfd *abfd; |
bfd *abfd; |
1119 |
{ |
{ |
1140 |
current_byte_index = 0; |
current_byte_index = 0; |
1141 |
processed_data.relb = s->target_index | RELOCATION_TYPE_REL; |
processed_data.relb = s->target_index | RELOCATION_TYPE_REL; |
1142 |
|
|
1143 |
while (current_byte_index < s->_cooked_size) |
while (current_byte_index < s->size) |
1144 |
{ |
{ |
1145 |
/* Scan forwards by eight bytes or however much is left and see if |
/* Scan forwards by eight bytes or however much is left and see if |
1146 |
there are any relocations going on */ |
there are any relocations going on */ |
1161 |
1 modification byte + 2 data = 8 bytes total). That's where |
1 modification byte + 2 data = 8 bytes total). That's where |
1162 |
the magic number 8 comes from. |
the magic number 8 comes from. |
1163 |
*/ |
*/ |
1164 |
while (current_byte_index < s->_raw_size && dst <= |
while (current_byte_index < s->size && dst <= |
1165 |
&processed_data.data[sizeof (processed_data.data) - 8]) |
&processed_data.data[sizeof (processed_data.data) - 8]) |
1166 |
{ |
{ |
1167 |
|
|
1209 |
} |
} |
1210 |
|
|
1211 |
/* Is this a section relative relocation, or a symbol |
/* Is this a section relative relocation, or a symbol |
1212 |
relative relocation ? */ |
relative relocation ? */ |
1213 |
abort (); |
abort (); |
1214 |
|
|
|
#if 0 |
|
|
if (r->section != (asection *) NULL) |
|
|
{ |
|
|
/* The relent has a section attached, so it must be section |
|
|
relative */ |
|
|
rel_byte |= RELOCATION_TYPE_REL; |
|
|
rel_byte |= r->section->output_section->target_index; |
|
|
*dst++ = rel_byte; |
|
|
} |
|
|
else |
|
|
#endif |
|
1215 |
{ |
{ |
1216 |
asymbol *sym = *(r->sym_ptr_ptr); |
asymbol *sym = *(r->sym_ptr_ptr); |
1217 |
|
|
1279 |
(abfd, oasys_record_is_data_enum, |
(abfd, oasys_record_is_data_enum, |
1280 |
((oasys_record_union_type *) &processed_data), |
((oasys_record_union_type *) &processed_data), |
1281 |
(size_t) (dst - (bfd_byte *) &processed_data)))) |
(size_t) (dst - (bfd_byte *) &processed_data)))) |
1282 |
return false; |
return FALSE; |
1283 |
} |
} |
1284 |
} |
} |
1285 |
} |
} |
1286 |
|
|
1287 |
return true; |
return TRUE; |
1288 |
} |
} |
1289 |
|
|
1290 |
static boolean |
static bfd_boolean |
1291 |
oasys_write_object_contents (abfd) |
oasys_write_object_contents (abfd) |
1292 |
bfd *abfd; |
bfd *abfd; |
1293 |
{ |
{ |
1294 |
if (! oasys_write_header (abfd)) |
if (! oasys_write_header (abfd)) |
1295 |
return false; |
return FALSE; |
1296 |
if (! oasys_write_syms (abfd)) |
if (! oasys_write_syms (abfd)) |
1297 |
return false; |
return FALSE; |
1298 |
if (! oasys_write_sections (abfd)) |
if (! oasys_write_sections (abfd)) |
1299 |
return false; |
return FALSE; |
1300 |
if (! oasys_write_data (abfd)) |
if (! oasys_write_data (abfd)) |
1301 |
return false; |
return FALSE; |
1302 |
if (! oasys_write_end (abfd)) |
if (! oasys_write_end (abfd)) |
1303 |
return false; |
return FALSE; |
1304 |
return true; |
return TRUE; |
1305 |
} |
} |
1306 |
|
|
1307 |
|
|
1312 |
/* set section contents is complicated with OASYS since the format is |
/* set section contents is complicated with OASYS since the format is |
1313 |
* not a byte image, but a record stream. |
* not a byte image, but a record stream. |
1314 |
*/ |
*/ |
1315 |
static boolean |
static bfd_boolean |
1316 |
oasys_set_section_contents (abfd, section, location, offset, count) |
oasys_set_section_contents (abfd, section, location, offset, count) |
1317 |
bfd *abfd; |
bfd *abfd; |
1318 |
sec_ptr section; |
sec_ptr section; |
1319 |
PTR location; |
const PTR location; |
1320 |
file_ptr offset; |
file_ptr offset; |
1321 |
bfd_size_type count; |
bfd_size_type count; |
1322 |
{ |
{ |
1325 |
if (oasys_per_section (section)->data == (bfd_byte *) NULL) |
if (oasys_per_section (section)->data == (bfd_byte *) NULL) |
1326 |
{ |
{ |
1327 |
oasys_per_section (section)->data = |
oasys_per_section (section)->data = |
1328 |
(bfd_byte *) (bfd_alloc (abfd, section->_cooked_size)); |
(bfd_byte *) (bfd_alloc (abfd, section->size)); |
1329 |
if (!oasys_per_section (section)->data) |
if (!oasys_per_section (section)->data) |
1330 |
return false; |
return FALSE; |
1331 |
} |
} |
1332 |
(void) memcpy ((PTR) (oasys_per_section (section)->data + offset), |
(void) memcpy ((PTR) (oasys_per_section (section)->data + offset), |
1333 |
location, |
location, |
1334 |
(size_t) count); |
(size_t) count); |
1335 |
} |
} |
1336 |
return true; |
return TRUE; |
1337 |
} |
} |
1338 |
|
|
1339 |
|
|
1399 |
} |
} |
1400 |
} |
} |
1401 |
|
|
1402 |
static boolean |
static bfd_boolean |
1403 |
oasys_find_nearest_line (abfd, section, symbols, offset, |
oasys_find_nearest_line (abfd, section, symbols, offset, |
1404 |
filename_ptr, functionname_ptr, line_ptr) |
filename_ptr, functionname_ptr, line_ptr) |
1405 |
bfd *abfd ATTRIBUTE_UNUSED; |
bfd *abfd ATTRIBUTE_UNUSED; |
1410 |
const char **functionname_ptr ATTRIBUTE_UNUSED; |
const char **functionname_ptr ATTRIBUTE_UNUSED; |
1411 |
unsigned int *line_ptr ATTRIBUTE_UNUSED; |
unsigned int *line_ptr ATTRIBUTE_UNUSED; |
1412 |
{ |
{ |
1413 |
return false; |
return FALSE; |
1414 |
|
|
1415 |
} |
} |
1416 |
|
|
1436 |
static int |
static int |
1437 |
oasys_sizeof_headers (abfd, exec) |
oasys_sizeof_headers (abfd, exec) |
1438 |
bfd *abfd ATTRIBUTE_UNUSED; |
bfd *abfd ATTRIBUTE_UNUSED; |
1439 |
boolean exec ATTRIBUTE_UNUSED; |
bfd_boolean exec ATTRIBUTE_UNUSED; |
1440 |
{ |
{ |
1441 |
return 0; |
return 0; |
1442 |
} |
} |
1447 |
#define oasys_slurp_armap bfd_true |
#define oasys_slurp_armap bfd_true |
1448 |
#define oasys_slurp_extended_name_table bfd_true |
#define oasys_slurp_extended_name_table bfd_true |
1449 |
#define oasys_construct_extended_name_table \ |
#define oasys_construct_extended_name_table \ |
1450 |
((boolean (*) PARAMS ((bfd *, char **, bfd_size_type *, const char **))) \ |
((bfd_boolean (*) PARAMS ((bfd *, char **, bfd_size_type *, const char **))) \ |
1451 |
bfd_true) |
bfd_true) |
1452 |
#define oasys_truncate_arname bfd_dont_truncate_arname |
#define oasys_truncate_arname bfd_dont_truncate_arname |
1453 |
#define oasys_write_armap \ |
#define oasys_write_armap \ |
1454 |
((boolean (*) \ |
((bfd_boolean (*) \ |
1455 |
PARAMS ((bfd *, unsigned int, struct orl *, unsigned int, int))) \ |
PARAMS ((bfd *, unsigned int, struct orl *, unsigned int, int))) \ |
1456 |
bfd_true) |
bfd_true) |
1457 |
#define oasys_read_ar_hdr bfd_nullvoidptr |
#define oasys_read_ar_hdr bfd_nullvoidptr |
1459 |
#define oasys_update_armap_timestamp bfd_true |
#define oasys_update_armap_timestamp bfd_true |
1460 |
|
|
1461 |
#define oasys_bfd_is_local_label_name bfd_generic_is_local_label_name |
#define oasys_bfd_is_local_label_name bfd_generic_is_local_label_name |
1462 |
|
#define oasys_bfd_is_target_special_symbol ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false) |
1463 |
#define oasys_get_lineno _bfd_nosymbols_get_lineno |
#define oasys_get_lineno _bfd_nosymbols_get_lineno |
1464 |
#define oasys_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol |
#define oasys_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol |
1465 |
#define oasys_read_minisymbols _bfd_generic_read_minisymbols |
#define oasys_read_minisymbols _bfd_generic_read_minisymbols |
1477 |
#define oasys_bfd_relax_section bfd_generic_relax_section |
#define oasys_bfd_relax_section bfd_generic_relax_section |
1478 |
#define oasys_bfd_gc_sections bfd_generic_gc_sections |
#define oasys_bfd_gc_sections bfd_generic_gc_sections |
1479 |
#define oasys_bfd_merge_sections bfd_generic_merge_sections |
#define oasys_bfd_merge_sections bfd_generic_merge_sections |
1480 |
|
#define oasys_bfd_is_group_section bfd_generic_is_group_section |
1481 |
#define oasys_bfd_discard_group bfd_generic_discard_group |
#define oasys_bfd_discard_group bfd_generic_discard_group |
1482 |
|
#define oasys_section_already_linked \ |
1483 |
|
_bfd_generic_section_already_linked |
1484 |
#define oasys_bfd_link_hash_table_create _bfd_generic_link_hash_table_create |
#define oasys_bfd_link_hash_table_create _bfd_generic_link_hash_table_create |
1485 |
#define oasys_bfd_link_hash_table_free _bfd_generic_link_hash_table_free |
#define oasys_bfd_link_hash_table_free _bfd_generic_link_hash_table_free |
1486 |
#define oasys_bfd_link_add_symbols _bfd_generic_link_add_symbols |
#define oasys_bfd_link_add_symbols _bfd_generic_link_add_symbols |