1 /* BFD back-end for os9000 i386 binaries. 2 Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1998, 1999, 2001, 2002, 3 2004, 2005 Free Software Foundation, Inc. 4 Written by Cygnus Support. 5 6 This file is part of BFD, the Binary File Descriptor library. 7 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 2 of the License, or 11 (at your option) any later version. 12 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. 17 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, MA 02110-1301, USA. */ 21 22 23 #include "bfd.h" 24 #include "sysdep.h" 25 #include "libbfd.h" 26 #include "bfdlink.h" 27 #include "libaout.h" /* BFD a.out internal data structures */ 28 #include "os9k.h" 29 30 static const bfd_target * os9k_callback 31 PARAMS ((bfd *)); 32 static const bfd_target * os9k_object_p 33 PARAMS ((bfd *)); 34 static int os9k_sizeof_headers 35 PARAMS ((bfd *, bfd_boolean)); 36 bfd_boolean os9k_swap_exec_header_in 37 PARAMS ((bfd *, mh_com *, struct internal_exec *)); 38 39 /* Swaps the information in an executable header taken from a raw byte 40 stream memory image, into the internal exec_header structure. */ 41 bfd_boolean 42 os9k_swap_exec_header_in (abfd, raw_bytes, execp) 43 bfd *abfd; 44 mh_com *raw_bytes; 45 struct internal_exec *execp; 46 { 47 mh_com *bytes = (mh_com *) raw_bytes; 48 unsigned int dload, dmemsize, dmemstart; 49 50 /* Now fill in fields in the execp, from the bytes in the raw data. */ 51 execp->a_info = H_GET_16 (abfd, bytes->m_sync); 52 execp->a_syms = 0; 53 execp->a_entry = H_GET_32 (abfd, bytes->m_exec); 54 execp->a_talign = 2; 55 execp->a_dalign = 2; 56 execp->a_balign = 2; 57 58 dload = H_GET_32 (abfd, bytes->m_idata); 59 execp->a_data = dload + 8; 60 61 if (bfd_seek (abfd, (file_ptr) dload, SEEK_SET) != 0 62 || (bfd_bread (&dmemstart, (bfd_size_type) sizeof (dmemstart), abfd) 63 != sizeof (dmemstart)) 64 || (bfd_bread (&dmemsize, (bfd_size_type) sizeof (dmemsize), abfd) 65 != sizeof (dmemsize))) 66 return FALSE; 67 68 execp->a_tload = 0; 69 execp->a_dload = H_GET_32 (abfd, (unsigned char *) &dmemstart); 70 execp->a_text = dload - execp->a_tload; 71 execp->a_data = H_GET_32 (abfd, (unsigned char *) &dmemsize); 72 execp->a_bss = H_GET_32 (abfd, bytes->m_data) - execp->a_data; 73 74 execp->a_trsize = 0; 75 execp->a_drsize = 0; 76 77 return TRUE; 78 } 79 80 static const bfd_target * 81 os9k_object_p (abfd) 82 bfd *abfd; 83 { 84 struct internal_exec anexec; 85 mh_com exec_bytes; 86 87 if (bfd_bread ((PTR) &exec_bytes, (bfd_size_type) MHCOM_BYTES_SIZE, abfd) 88 != MHCOM_BYTES_SIZE) 89 { 90 if (bfd_get_error () != bfd_error_system_call) 91 bfd_set_error (bfd_error_wrong_format); 92 return 0; 93 } 94 95 anexec.a_info = H_GET_16 (abfd, exec_bytes.m_sync); 96 if (N_BADMAG (anexec)) 97 { 98 bfd_set_error (bfd_error_wrong_format); 99 return 0; 100 } 101 102 if (! os9k_swap_exec_header_in (abfd, &exec_bytes, &anexec)) 103 { 104 if (bfd_get_error () != bfd_error_system_call) 105 bfd_set_error (bfd_error_wrong_format); 106 return NULL; 107 } 108 return aout_32_some_aout_object_p (abfd, &anexec, os9k_callback); 109 } 110 111 112 /* Finish up the opening of a b.out file for reading. Fill in all the 113 fields that are not handled by common code. */ 114 115 static const bfd_target * 116 os9k_callback (abfd) 117 bfd *abfd; 118 { 119 struct internal_exec *execp = exec_hdr (abfd); 120 unsigned long bss_start; 121 122 /* Architecture and machine type. */ 123 bfd_set_arch_mach (abfd, bfd_arch_i386, 0); 124 125 /* The positions of the string table and symbol table. */ 126 obj_str_filepos (abfd) = 0; 127 obj_sym_filepos (abfd) = 0; 128 129 /* The alignments of the sections. */ 130 obj_textsec (abfd)->alignment_power = execp->a_talign; 131 obj_datasec (abfd)->alignment_power = execp->a_dalign; 132 obj_bsssec (abfd)->alignment_power = execp->a_balign; 133 134 /* The starting addresses of the sections. */ 135 obj_textsec (abfd)->vma = execp->a_tload; 136 obj_datasec (abfd)->vma = execp->a_dload; 137 138 /* And reload the sizes, since the aout module zaps them. */ 139 obj_textsec (abfd)->size = execp->a_text; 140 141 bss_start = execp->a_dload + execp->a_data; /* BSS = end of data section. */ 142 obj_bsssec (abfd)->vma = align_power (bss_start, execp->a_balign); 143 144 /* The file positions of the sections. */ 145 obj_textsec (abfd)->filepos = execp->a_entry; 146 obj_datasec (abfd)->filepos = execp->a_dload; 147 148 /* The file positions of the relocation info *** 149 obj_textsec (abfd)->rel_filepos = N_TROFF(*execp); 150 obj_datasec (abfd)->rel_filepos = N_DROFF(*execp); */ 151 152 adata (abfd).page_size = 1; /* Not applicable. */ 153 adata (abfd).segment_size = 1;/* Not applicable. */ 154 adata (abfd).exec_bytes_size = MHCOM_BYTES_SIZE; 155 156 return abfd->xvec; 157 } 158 159 static int 160 os9k_sizeof_headers (ignore_abfd, ignore) 161 bfd *ignore_abfd ATTRIBUTE_UNUSED; 162 bfd_boolean ignore ATTRIBUTE_UNUSED; 163 { 164 return sizeof (struct internal_exec); 165 } 166 167 168 169 #define aout_32_close_and_cleanup aout_32_bfd_free_cached_info 170 171 #define aout_32_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol 172 173 #define aout_32_bfd_reloc_type_lookup _bfd_norelocs_bfd_reloc_type_lookup 174 175 #define aout_32_get_section_contents_in_window \ 176 _bfd_generic_get_section_contents_in_window 177 178 #define os9k_bfd_get_relocated_section_contents \ 179 bfd_generic_get_relocated_section_contents 180 #define os9k_bfd_relax_section bfd_generic_relax_section 181 #define os9k_bfd_gc_sections bfd_generic_gc_sections 182 #define os9k_bfd_merge_sections bfd_generic_merge_sections 183 #define os9k_bfd_is_group_section bfd_generic_is_group_section 184 #define os9k_bfd_discard_group bfd_generic_discard_group 185 #define os9k_section_already_linked \ 186 _bfd_generic_section_already_linked 187 #define os9k_bfd_link_hash_table_create _bfd_generic_link_hash_table_create 188 #define os9k_bfd_link_hash_table_free _bfd_generic_link_hash_table_free 189 #define os9k_bfd_link_add_symbols _bfd_generic_link_add_symbols 190 #define os9k_bfd_link_just_syms _bfd_generic_link_just_syms 191 #define os9k_bfd_final_link _bfd_generic_final_link 192 #define os9k_bfd_link_split_section _bfd_generic_link_split_section 193 194 const bfd_target i386os9k_vec = 195 { 196 "i386os9k", /* name */ 197 bfd_target_os9k_flavour, 198 BFD_ENDIAN_LITTLE, /* data byte order is little */ 199 BFD_ENDIAN_LITTLE, /* hdr byte order is little */ 200 (HAS_RELOC | EXEC_P | WP_TEXT), /* object flags */ 201 (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD), /* section flags */ 202 0, /* symbol leading char */ 203 ' ', /* ar_pad_char */ 204 16, /* ar_max_namelen */ 205 206 bfd_getl64, bfd_getl_signed_64, bfd_putl64, 207 bfd_getl32, bfd_getl_signed_32, bfd_putl32, 208 bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */ 209 bfd_getl64, bfd_getl_signed_64, bfd_putl64, 210 bfd_getl32, bfd_getl_signed_32, bfd_putl32, 211 bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */ 212 {_bfd_dummy_target, os9k_object_p, /* bfd_check_format */ 213 bfd_generic_archive_p, _bfd_dummy_target}, 214 {bfd_false, bfd_false, /* bfd_set_format */ 215 _bfd_generic_mkarchive, bfd_false}, 216 {bfd_false, bfd_false, /* bfd_write_contents */ 217 _bfd_write_archive_contents, bfd_false}, 218 219 BFD_JUMP_TABLE_GENERIC (aout_32), 220 BFD_JUMP_TABLE_COPY (_bfd_generic), 221 BFD_JUMP_TABLE_CORE (_bfd_nocore), 222 BFD_JUMP_TABLE_ARCHIVE (_bfd_archive_bsd), 223 BFD_JUMP_TABLE_SYMBOLS (aout_32), 224 BFD_JUMP_TABLE_RELOCS (aout_32), 225 BFD_JUMP_TABLE_WRITE (aout_32), 226 BFD_JUMP_TABLE_LINK (os9k), 227 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic), 228 229 NULL, 230 231 (PTR) 0, 232 }; 233