1 |
/* BFD back-end for VERSAdos-E objects. |
/* BFD back-end for VERSAdos-E objects. |
2 |
Copyright 1995, 1996, 1998, 1999, 2000, 2001, 2002 |
Copyright 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 |
3 |
Free Software Foundation, Inc. |
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 |
|
|
23 |
|
|
24 |
/* |
/* |
25 |
SUBSECTION |
SUBSECTION |
26 |
VERSAdos-E relocateable object file format |
VERSAdos-E relocatable object file format |
27 |
|
|
28 |
DESCRIPTION |
DESCRIPTION |
29 |
|
|
30 |
This module supports reading of VERSAdos relocateable |
This module supports reading of VERSAdos relocatable |
31 |
object files. |
object files. |
32 |
|
|
33 |
A VERSAdos file looks like contains |
A VERSAdos file looks like contains |
34 |
|
|
35 |
o Indentification Record |
o Identification Record |
36 |
o External Symbol Definition Record |
o External Symbol Definition Record |
37 |
o Object Text Recrod |
o Object Text Record |
38 |
o End Record |
o End Record |
39 |
|
|
40 |
*/ |
*/ |
44 |
#include "libbfd.h" |
#include "libbfd.h" |
45 |
#include "libiberty.h" |
#include "libiberty.h" |
46 |
|
|
47 |
static boolean versados_mkobject PARAMS ((bfd *)); |
static bfd_boolean versados_mkobject PARAMS ((bfd *)); |
48 |
static boolean versados_scan PARAMS ((bfd *)); |
static bfd_boolean versados_scan PARAMS ((bfd *)); |
49 |
static const bfd_target *versados_object_p PARAMS ((bfd *)); |
static const bfd_target *versados_object_p PARAMS ((bfd *)); |
50 |
static asymbol *versados_new_symbol PARAMS ((bfd *, int, const char *, bfd_vma, asection *)); |
static asymbol *versados_new_symbol |
51 |
|
PARAMS ((bfd *, int, const char *, bfd_vma, asection *)); |
52 |
static char *new_symbol_string PARAMS ((bfd *, const char *)); |
static char *new_symbol_string PARAMS ((bfd *, const char *)); |
53 |
static const bfd_target *versados_object_p PARAMS ((bfd *)); |
static const bfd_target *versados_object_p PARAMS ((bfd *)); |
54 |
static boolean versados_pass_2 PARAMS ((bfd *)); |
static bfd_boolean versados_pass_2 PARAMS ((bfd *)); |
55 |
static boolean versados_get_section_contents |
static bfd_boolean versados_get_section_contents |
56 |
PARAMS ((bfd *, asection *, void *, file_ptr, bfd_size_type)); |
PARAMS ((bfd *, asection *, void *, file_ptr, bfd_size_type)); |
57 |
static boolean versados_set_section_contents |
static bfd_boolean versados_set_section_contents |
58 |
PARAMS ((bfd *, sec_ptr, void *, file_ptr, bfd_size_type)); |
PARAMS ((bfd *, sec_ptr, const void *, file_ptr, bfd_size_type)); |
59 |
static int versados_sizeof_headers PARAMS ((bfd *, boolean)); |
static int versados_sizeof_headers PARAMS ((bfd *, bfd_boolean)); |
60 |
static long int versados_get_symtab_upper_bound PARAMS ((bfd *)); |
static long int versados_get_symtab_upper_bound PARAMS ((bfd *)); |
61 |
static long int versados_get_symtab PARAMS ((bfd *, asymbol **)); |
static long int versados_canonicalize_symtab PARAMS ((bfd *, asymbol **)); |
62 |
static void versados_get_symbol_info |
static void versados_get_symbol_info |
63 |
PARAMS ((bfd *, asymbol *, symbol_info *)); |
PARAMS ((bfd *, asymbol *, symbol_info *)); |
64 |
static void versados_print_symbol |
static void versados_print_symbol |
173 |
|
|
174 |
/* Set up the tdata information. */ |
/* Set up the tdata information. */ |
175 |
|
|
176 |
static boolean |
static bfd_boolean |
177 |
versados_mkobject (abfd) |
versados_mkobject (abfd) |
178 |
bfd *abfd; |
bfd *abfd; |
179 |
{ |
{ |
182 |
bfd_size_type amt = sizeof (tdata_type); |
bfd_size_type amt = sizeof (tdata_type); |
183 |
tdata_type *tdata = (tdata_type *) bfd_alloc (abfd, amt); |
tdata_type *tdata = (tdata_type *) bfd_alloc (abfd, amt); |
184 |
if (tdata == NULL) |
if (tdata == NULL) |
185 |
return false; |
return FALSE; |
186 |
abfd->tdata.versados_data = tdata; |
abfd->tdata.versados_data = tdata; |
187 |
tdata->symbols = NULL; |
tdata->symbols = NULL; |
188 |
VDATA (abfd)->alert = 0x12345678; |
VDATA (abfd)->alert = 0x12345678; |
189 |
} |
} |
190 |
|
|
191 |
bfd_default_set_arch_mach (abfd, bfd_arch_m68k, 0); |
bfd_default_set_arch_mach (abfd, bfd_arch_m68k, 0); |
192 |
return true; |
return TRUE; |
193 |
} |
} |
194 |
|
|
195 |
/* Report a problem in an S record file. FIXME: This probably should |
/* Report a problem in an S record file. FIXME: This probably should |
320 |
case ESD_STD_REL_SEC: |
case ESD_STD_REL_SEC: |
321 |
case ESD_SHRT_REL_SEC: |
case ESD_SHRT_REL_SEC: |
322 |
{ |
{ |
323 |
sec->_raw_size = get_4 (&ptr); |
sec->size = get_4 (&ptr); |
324 |
sec->flags |= SEC_ALLOC; |
sec->flags |= SEC_ALLOC; |
325 |
} |
} |
326 |
break; |
break; |
358 |
|
|
359 |
reloc_howto_type versados_howto_table[] = |
reloc_howto_type versados_howto_table[] = |
360 |
{ |
{ |
361 |
HOWTO (R_RELWORD, 0, 1, 16, false, |
HOWTO (R_RELWORD, 0, 1, 16, FALSE, |
362 |
0, complain_overflow_dont, 0, |
0, complain_overflow_dont, 0, |
363 |
"+v16", true, 0x0000ffff, 0x0000ffff, false), |
"+v16", TRUE, 0x0000ffff, 0x0000ffff, FALSE), |
364 |
HOWTO (R_RELLONG, 0, 2, 32, false, |
HOWTO (R_RELLONG, 0, 2, 32, FALSE, |
365 |
0, complain_overflow_dont, 0, |
0, complain_overflow_dont, 0, |
366 |
"+v32", true, 0xffffffff, 0xffffffff, false), |
"+v32", TRUE, 0xffffffff, 0xffffffff, FALSE), |
367 |
|
|
368 |
HOWTO (R_RELWORD_NEG, 0, -1, 16, false, |
HOWTO (R_RELWORD_NEG, 0, -1, 16, FALSE, |
369 |
0, complain_overflow_dont, 0, |
0, complain_overflow_dont, 0, |
370 |
"-v16", true, 0x0000ffff, 0x0000ffff, false), |
"-v16", TRUE, 0x0000ffff, 0x0000ffff, FALSE), |
371 |
HOWTO (R_RELLONG_NEG, 0, -2, 32, false, |
HOWTO (R_RELLONG_NEG, 0, -2, 32, FALSE, |
372 |
0, complain_overflow_dont, 0, |
0, complain_overflow_dont, 0, |
373 |
"-v32", true, 0xffffffff, 0xffffffff, false), |
"-v32", TRUE, 0xffffffff, 0xffffffff, FALSE), |
374 |
}; |
}; |
375 |
|
|
376 |
static int |
static int |
457 |
EDATA (abfd, otr->esdid - 1).section->relocation + rn; |
EDATA (abfd, otr->esdid - 1).section->relocation + rn; |
458 |
n->address = dst_idx; |
n->address = dst_idx; |
459 |
|
|
460 |
n->sym_ptr_ptr = (asymbol **) esdid; |
n->sym_ptr_ptr = (asymbol **) (size_t) esdid; |
461 |
n->addend = 0; |
n->addend = 0; |
462 |
n->howto = versados_howto_table + ((j & 1) * 2) + (sizeinwords - 1); |
n->howto = versados_howto_table + ((j & 1) * 2) + (sizeinwords - 1); |
463 |
} |
} |
470 |
else |
else |
471 |
{ |
{ |
472 |
need_contents = 1; |
need_contents = 1; |
473 |
if (dst_idx < esdid->section->_raw_size) |
if (dst_idx < esdid->section->size) |
474 |
if (pass == 2) |
if (pass == 2) |
475 |
{ |
{ |
476 |
/* absolute code, comes in 16 bit lumps */ |
/* absolute code, comes in 16 bit lumps */ |
485 |
|
|
486 |
if (!contents && need_contents) |
if (!contents && need_contents) |
487 |
{ |
{ |
488 |
bfd_size_type size = esdid->section->_raw_size; |
bfd_size_type size = esdid->section->size; |
489 |
esdid->contents = (unsigned char *) bfd_alloc (abfd, size); |
esdid->contents = (unsigned char *) bfd_alloc (abfd, size); |
490 |
} |
} |
491 |
} |
} |
492 |
|
|
493 |
static boolean |
static bfd_boolean |
494 |
versados_scan (abfd) |
versados_scan (abfd) |
495 |
bfd *abfd; |
bfd *abfd; |
496 |
{ |
{ |
511 |
{ |
{ |
512 |
union ext_any any; |
union ext_any any; |
513 |
if (!get_record (abfd, &any)) |
if (!get_record (abfd, &any)) |
514 |
return true; |
return TRUE; |
515 |
switch (any.header.type) |
switch (any.header.type) |
516 |
{ |
{ |
517 |
case VHEADER: |
case VHEADER: |
573 |
|
|
574 |
if ((VDATA (abfd)->symbols == NULL && abfd->symcount > 0) |
if ((VDATA (abfd)->symbols == NULL && abfd->symcount > 0) |
575 |
|| (VDATA (abfd)->strings == NULL && VDATA (abfd)->stringlen > 0)) |
|| (VDATA (abfd)->strings == NULL && VDATA (abfd)->stringlen > 0)) |
576 |
return false; |
return FALSE; |
577 |
|
|
578 |
/* Actually fill in the section symbols, |
/* Actually fill in the section symbols, |
579 |
we stick them at the end of the table */ |
we stick them at the end of the table */ |
613 |
{ |
{ |
614 |
struct ext_vheader ext; |
struct ext_vheader ext; |
615 |
unsigned char len; |
unsigned char len; |
616 |
|
tdata_type *tdata_save; |
617 |
|
|
618 |
if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0) |
if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0) |
619 |
return NULL; |
return NULL; |
644 |
|
|
645 |
/* OK, looks like a record, build the tdata and read in. */ |
/* OK, looks like a record, build the tdata and read in. */ |
646 |
|
|
647 |
if (!versados_mkobject (abfd) |
tdata_save = abfd->tdata.versados_data; |
648 |
|| !versados_scan (abfd)) |
if (!versados_mkobject (abfd) || !versados_scan (abfd)) |
649 |
return NULL; |
{ |
650 |
|
abfd->tdata.versados_data = tdata_save; |
651 |
|
return NULL; |
652 |
|
} |
653 |
|
|
654 |
return abfd->xvec; |
return abfd->xvec; |
655 |
} |
} |
656 |
|
|
657 |
static boolean |
static bfd_boolean |
658 |
versados_pass_2 (abfd) |
versados_pass_2 (abfd) |
659 |
bfd *abfd; |
bfd *abfd; |
660 |
{ |
{ |
688 |
} |
} |
689 |
} |
} |
690 |
|
|
691 |
static boolean |
static bfd_boolean |
692 |
versados_get_section_contents (abfd, section, location, offset, count) |
versados_get_section_contents (abfd, section, location, offset, count) |
693 |
bfd *abfd; |
bfd *abfd; |
694 |
asection *section; |
asection *section; |
697 |
bfd_size_type count; |
bfd_size_type count; |
698 |
{ |
{ |
699 |
if (!versados_pass_2 (abfd)) |
if (!versados_pass_2 (abfd)) |
700 |
return false; |
return FALSE; |
701 |
|
|
702 |
memcpy (location, |
memcpy (location, |
703 |
EDATA (abfd, section->target_index).contents + offset, |
EDATA (abfd, section->target_index).contents + offset, |
704 |
(size_t) count); |
(size_t) count); |
705 |
|
|
706 |
return true; |
return TRUE; |
707 |
} |
} |
708 |
|
|
709 |
#define versados_get_section_contents_in_window \ |
#define versados_get_section_contents_in_window \ |
710 |
_bfd_generic_get_section_contents_in_window |
_bfd_generic_get_section_contents_in_window |
711 |
|
|
712 |
static boolean |
static bfd_boolean |
713 |
versados_set_section_contents (abfd, section, location, offset, bytes_to_do) |
versados_set_section_contents (abfd, section, location, offset, bytes_to_do) |
714 |
bfd *abfd ATTRIBUTE_UNUSED; |
bfd *abfd ATTRIBUTE_UNUSED; |
715 |
sec_ptr section ATTRIBUTE_UNUSED; |
sec_ptr section ATTRIBUTE_UNUSED; |
716 |
PTR location ATTRIBUTE_UNUSED; |
const PTR location ATTRIBUTE_UNUSED; |
717 |
file_ptr offset ATTRIBUTE_UNUSED; |
file_ptr offset ATTRIBUTE_UNUSED; |
718 |
bfd_size_type bytes_to_do ATTRIBUTE_UNUSED; |
bfd_size_type bytes_to_do ATTRIBUTE_UNUSED; |
719 |
{ |
{ |
720 |
return false; |
return FALSE; |
721 |
} |
} |
722 |
|
|
723 |
static int |
static int |
724 |
versados_sizeof_headers (abfd, exec) |
versados_sizeof_headers (abfd, exec) |
725 |
bfd *abfd ATTRIBUTE_UNUSED; |
bfd *abfd ATTRIBUTE_UNUSED; |
726 |
boolean exec ATTRIBUTE_UNUSED; |
bfd_boolean exec ATTRIBUTE_UNUSED; |
727 |
{ |
{ |
728 |
return 0; |
return 0; |
729 |
} |
} |
740 |
/* Return the symbol table. */ |
/* Return the symbol table. */ |
741 |
|
|
742 |
static long |
static long |
743 |
versados_get_symtab (abfd, alocation) |
versados_canonicalize_symtab (abfd, alocation) |
744 |
bfd *abfd; |
bfd *abfd; |
745 |
asymbol **alocation; |
asymbol **alocation; |
746 |
{ |
{ |
819 |
/* translate from indexes to symptr ptrs */ |
/* translate from indexes to symptr ptrs */ |
820 |
for (count = 0; count < section->reloc_count; count++) |
for (count = 0; count < section->reloc_count; count++) |
821 |
{ |
{ |
822 |
int esdid = (int) src[count].sym_ptr_ptr; |
int esdid = (int) (size_t) src[count].sym_ptr_ptr; |
823 |
|
|
824 |
if (esdid == 0) |
if (esdid == 0) |
825 |
{ |
{ |
855 |
#define versados_bfd_free_cached_info _bfd_generic_bfd_free_cached_info |
#define versados_bfd_free_cached_info _bfd_generic_bfd_free_cached_info |
856 |
#define versados_new_section_hook _bfd_generic_new_section_hook |
#define versados_new_section_hook _bfd_generic_new_section_hook |
857 |
|
|
858 |
|
#define versados_bfd_is_target_special_symbol \ |
859 |
|
((bfd_boolean (*) (bfd *, asymbol *)) bfd_false) |
860 |
#define versados_bfd_is_local_label_name bfd_generic_is_local_label_name |
#define versados_bfd_is_local_label_name bfd_generic_is_local_label_name |
861 |
#define versados_get_lineno _bfd_nosymbols_get_lineno |
#define versados_get_lineno _bfd_nosymbols_get_lineno |
862 |
#define versados_find_nearest_line _bfd_nosymbols_find_nearest_line |
#define versados_find_nearest_line _bfd_nosymbols_find_nearest_line |
874 |
#define versados_bfd_relax_section bfd_generic_relax_section |
#define versados_bfd_relax_section bfd_generic_relax_section |
875 |
#define versados_bfd_gc_sections bfd_generic_gc_sections |
#define versados_bfd_gc_sections bfd_generic_gc_sections |
876 |
#define versados_bfd_merge_sections bfd_generic_merge_sections |
#define versados_bfd_merge_sections bfd_generic_merge_sections |
877 |
|
#define versados_bfd_is_group_section bfd_generic_is_group_section |
878 |
#define versados_bfd_discard_group bfd_generic_discard_group |
#define versados_bfd_discard_group bfd_generic_discard_group |
879 |
|
#define versados_section_already_linked \ |
880 |
|
_bfd_generic_section_already_linked |
881 |
#define versados_bfd_link_hash_table_create _bfd_generic_link_hash_table_create |
#define versados_bfd_link_hash_table_create _bfd_generic_link_hash_table_create |
882 |
#define versados_bfd_link_hash_table_free _bfd_generic_link_hash_table_free |
#define versados_bfd_link_hash_table_free _bfd_generic_link_hash_table_free |
883 |
#define versados_bfd_link_add_symbols _bfd_generic_link_add_symbols |
#define versados_bfd_link_add_symbols _bfd_generic_link_add_symbols |