Back to index

cell-binutils  2.17cvs20070401
i386msdos.c
Go to the documentation of this file.
00001 /* BFD back-end for MS-DOS executables.
00002    Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2001, 2002,
00003    2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
00004    Written by Bryan Ford of the University of Utah.
00005 
00006    Contributed by the Center for Software Science at the
00007    University of Utah (pa-gdb-bugs@cs.utah.edu).
00008 
00009    This file is part of BFD, the Binary File Descriptor library.
00010 
00011    This program is free software; you can redistribute it and/or modify
00012    it under the terms of the GNU General Public License as published by
00013    the Free Software Foundation; either version 2 of the License, or
00014    (at your option) any later version.
00015 
00016    This program is distributed in the hope that it will be useful,
00017    but WITHOUT ANY WARRANTY; without even the implied warranty of
00018    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019    GNU General Public License for more details.
00020 
00021    You should have received a copy of the GNU General Public License
00022    along with this program; if not, write to the Free Software
00023    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
00024 
00025 
00026 #include "bfd.h"
00027 #include "sysdep.h"
00028 #include "libbfd.h"
00029 #include "libaout.h"
00030 
00031 #define EXE_MAGIC    0x5a4d
00032 #define EXE_LOAD_HIGH       0x0000
00033 #define EXE_LOAD_LOW 0xffff
00034 #define EXE_PAGE_SIZE       512
00035 
00036 static int
00037 msdos_sizeof_headers (bfd *abfd ATTRIBUTE_UNUSED,
00038                     struct bfd_link_info *info ATTRIBUTE_UNUSED)
00039 {
00040   return 0;
00041 }
00042 
00043 static bfd_boolean
00044 msdos_write_object_contents (bfd *abfd)
00045 {
00046   static char hdr[EXE_PAGE_SIZE];
00047   file_ptr outfile_size = sizeof(hdr);
00048   bfd_vma high_vma = 0;
00049   asection *sec;
00050 
00051   /* Find the total size of the program on disk and in memory.  */
00052   for (sec = abfd->sections; sec != (asection *) NULL; sec = sec->next)
00053     {
00054       if (sec->size == 0)
00055         continue;
00056       if (bfd_get_section_flags (abfd, sec) & SEC_ALLOC)
00057         {
00058          bfd_vma sec_vma = bfd_get_section_vma (abfd, sec) + sec->size;
00059          if (sec_vma > high_vma)
00060            high_vma = sec_vma;
00061        }
00062       if (bfd_get_section_flags (abfd, sec) & SEC_LOAD)
00063         {
00064          file_ptr sec_end = (sizeof (hdr)
00065                            + bfd_get_section_vma (abfd, sec)
00066                            + sec->size);
00067          if (sec_end > outfile_size)
00068            outfile_size = sec_end;
00069        }
00070     }
00071 
00072   /* Make sure the program isn't too big.  */
00073   if (high_vma > (bfd_vma)0xffff)
00074     {
00075       bfd_set_error(bfd_error_file_too_big);
00076       return FALSE;
00077     }
00078 
00079   /* Constants.  */
00080   H_PUT_16 (abfd, EXE_MAGIC, &hdr[0]);
00081   H_PUT_16 (abfd, EXE_PAGE_SIZE / 16, &hdr[8]);
00082   H_PUT_16 (abfd, EXE_LOAD_LOW, &hdr[12]);
00083   H_PUT_16 (abfd, 0x3e, &hdr[24]);
00084   H_PUT_16 (abfd, 0x0001, &hdr[28]); /* XXX??? */
00085   H_PUT_16 (abfd, 0x30fb, &hdr[30]); /* XXX??? */
00086   H_PUT_16 (abfd, 0x726a, &hdr[32]); /* XXX??? */
00087 
00088   /* Bytes in last page (0 = full page).  */
00089   H_PUT_16 (abfd, outfile_size & (EXE_PAGE_SIZE - 1), &hdr[2]);
00090 
00091   /* Number of pages.  */
00092   H_PUT_16 (abfd, (outfile_size + EXE_PAGE_SIZE - 1) / EXE_PAGE_SIZE, &hdr[4]);
00093 
00094   /* Set the initial stack pointer to the end of the bss.
00095      The program's crt0 code must relocate it to a real stack.  */
00096   H_PUT_16 (abfd, high_vma, &hdr[16]);
00097 
00098   if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
00099       || bfd_bwrite (hdr, (bfd_size_type) sizeof(hdr), abfd) != sizeof(hdr))
00100     return FALSE;
00101 
00102   return TRUE;
00103 }
00104 
00105 static bfd_boolean
00106 msdos_set_section_contents (bfd *abfd,
00107                          sec_ptr section,
00108                          const void *location,
00109                          file_ptr offset,
00110                          bfd_size_type count)
00111 {
00112 
00113   if (count == 0)
00114     return TRUE;
00115 
00116   section->filepos = EXE_PAGE_SIZE + bfd_get_section_vma (abfd, section);
00117 
00118   if (bfd_get_section_flags (abfd, section) & SEC_LOAD)
00119     {
00120       if (bfd_seek (abfd, section->filepos + offset, SEEK_SET) != 0
00121           || bfd_bwrite (location, count, abfd) != count)
00122         return FALSE;
00123     }
00124 
00125   return TRUE;
00126 }
00127 
00128 
00129 
00130 #define msdos_mkobject aout_32_mkobject
00131 #define msdos_make_empty_symbol aout_32_make_empty_symbol
00132 #define msdos_bfd_reloc_type_lookup aout_32_reloc_type_lookup
00133 #define msdos_bfd_reloc_name_lookup aout_32_reloc_name_lookup
00134 
00135 #define       msdos_close_and_cleanup _bfd_generic_close_and_cleanup
00136 #define msdos_bfd_free_cached_info _bfd_generic_bfd_free_cached_info
00137 #define msdos_new_section_hook _bfd_generic_new_section_hook
00138 #define msdos_get_section_contents _bfd_generic_get_section_contents
00139 #define msdos_get_section_contents_in_window \
00140   _bfd_generic_get_section_contents_in_window
00141 #define msdos_bfd_get_relocated_section_contents \
00142   bfd_generic_get_relocated_section_contents
00143 #define msdos_bfd_relax_section bfd_generic_relax_section
00144 #define msdos_bfd_gc_sections bfd_generic_gc_sections
00145 #define msdos_bfd_merge_sections bfd_generic_merge_sections
00146 #define msdos_bfd_is_group_section bfd_generic_is_group_section
00147 #define msdos_bfd_discard_group bfd_generic_discard_group
00148 #define msdos_section_already_linked \
00149   _bfd_generic_section_already_linked
00150 #define msdos_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
00151 #define msdos_bfd_link_hash_table_free _bfd_generic_link_hash_table_free
00152 #define msdos_bfd_link_add_symbols _bfd_generic_link_add_symbols
00153 #define msdos_bfd_link_just_syms _bfd_generic_link_just_syms
00154 #define msdos_bfd_final_link _bfd_generic_final_link
00155 #define msdos_bfd_link_split_section _bfd_generic_link_split_section
00156 #define msdos_set_arch_mach _bfd_generic_set_arch_mach
00157 
00158 #define msdos_get_symtab_upper_bound _bfd_nosymbols_get_symtab_upper_bound
00159 #define msdos_canonicalize_symtab _bfd_nosymbols_canonicalize_symtab
00160 #define msdos_print_symbol _bfd_nosymbols_print_symbol
00161 #define msdos_get_symbol_info _bfd_nosymbols_get_symbol_info
00162 #define msdos_find_nearest_line _bfd_nosymbols_find_nearest_line
00163 #define msdos_find_inliner_info _bfd_nosymbols_find_inliner_info
00164 #define msdos_get_lineno _bfd_nosymbols_get_lineno
00165 #define msdos_bfd_is_target_special_symbol ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false)
00166 #define msdos_bfd_is_local_label_name _bfd_nosymbols_bfd_is_local_label_name
00167 #define msdos_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol
00168 #define msdos_read_minisymbols _bfd_nosymbols_read_minisymbols
00169 #define msdos_minisymbol_to_symbol _bfd_nosymbols_minisymbol_to_symbol
00170 
00171 #define msdos_canonicalize_reloc _bfd_norelocs_canonicalize_reloc
00172 #define msdos_get_reloc_upper_bound _bfd_norelocs_get_reloc_upper_bound
00173 #define msdos_32_bfd_link_split_section  _bfd_generic_link_split_section
00174 
00175 const bfd_target i386msdos_vec =
00176   {
00177     "msdos",                /* name */
00178     bfd_target_msdos_flavour,
00179     BFD_ENDIAN_LITTLE,             /* target byte order */
00180     BFD_ENDIAN_LITTLE,             /* target headers byte order */
00181     (EXEC_P),               /* object flags */
00182     (SEC_CODE | SEC_DATA | SEC_HAS_CONTENTS
00183      | SEC_ALLOC | SEC_LOAD),      /* section flags */
00184     0,                      /* leading underscore */
00185     ' ',                           /* ar_pad_char */
00186     16,                            /* ar_max_namelen */
00187     bfd_getl64, bfd_getl_signed_64, bfd_putl64,
00188     bfd_getl32, bfd_getl_signed_32, bfd_putl32,
00189     bfd_getl16, bfd_getl_signed_16, bfd_putl16,  /* data */
00190     bfd_getl64, bfd_getl_signed_64, bfd_putl64,
00191     bfd_getl32, bfd_getl_signed_32, bfd_putl32,
00192     bfd_getl16, bfd_getl_signed_16, bfd_putl16,  /* hdrs */
00193 
00194     {
00195       _bfd_dummy_target,
00196       _bfd_dummy_target,           /* bfd_check_format */
00197       _bfd_dummy_target,
00198       _bfd_dummy_target,
00199     },
00200     {
00201       bfd_false,
00202       msdos_mkobject,
00203       _bfd_generic_mkarchive,
00204       bfd_false,
00205     },
00206     {                       /* bfd_write_contents */
00207       bfd_false,
00208       msdos_write_object_contents,
00209       _bfd_write_archive_contents,
00210       bfd_false,
00211     },
00212 
00213     BFD_JUMP_TABLE_GENERIC (msdos),
00214     BFD_JUMP_TABLE_COPY (_bfd_generic),
00215     BFD_JUMP_TABLE_CORE (_bfd_nocore),
00216     BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
00217     BFD_JUMP_TABLE_SYMBOLS (msdos),
00218     BFD_JUMP_TABLE_RELOCS (msdos),
00219     BFD_JUMP_TABLE_WRITE (msdos),
00220     BFD_JUMP_TABLE_LINK (msdos),
00221     BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
00222 
00223     NULL,
00224 
00225     (PTR) 0
00226   };
00227 
00228