12159047fSniklas /* BFD back-end for MS-DOS executables.
2*007c2a45Smiod Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2001, 2002,
3*007c2a45Smiod 2003 Free Software Foundation, Inc.
42159047fSniklas Written by Bryan Ford of the University of Utah.
52159047fSniklas
62159047fSniklas Contributed by the Center for Software Science at the
72159047fSniklas University of Utah (pa-gdb-bugs@cs.utah.edu).
82159047fSniklas
92159047fSniklas This file is part of BFD, the Binary File Descriptor library.
102159047fSniklas
112159047fSniklas This program is free software; you can redistribute it and/or modify
122159047fSniklas it under the terms of the GNU General Public License as published by
132159047fSniklas the Free Software Foundation; either version 2 of the License, or
142159047fSniklas (at your option) any later version.
152159047fSniklas
162159047fSniklas This program is distributed in the hope that it will be useful,
172159047fSniklas but WITHOUT ANY WARRANTY; without even the implied warranty of
182159047fSniklas MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
192159047fSniklas GNU General Public License for more details.
202159047fSniklas
212159047fSniklas You should have received a copy of the GNU General Public License
222159047fSniklas along with this program; if not, write to the Free Software
232159047fSniklas Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
242159047fSniklas
252159047fSniklas
262159047fSniklas #include "bfd.h"
272159047fSniklas #include "sysdep.h"
282159047fSniklas #include "libbfd.h"
292159047fSniklas #include "libaout.h"
302159047fSniklas
312159047fSniklas #if 0
322159047fSniklas struct exe_header
332159047fSniklas {
342159047fSniklas unsigned short magic;
352159047fSniklas unsigned short bytes_in_last_page;
362159047fSniklas unsigned short npages; /* number of 512-byte "pages" including this header */
372159047fSniklas unsigned short nrelocs;
382159047fSniklas unsigned short header_paras; /* number of 16-byte paragraphs in header */
392159047fSniklas unsigned short reserved;
402159047fSniklas unsigned short load_switch;
412159047fSniklas unsigned short ss_ofs;
422159047fSniklas unsigned short sp;
432159047fSniklas unsigned short checksum;
442159047fSniklas unsigned short ip;
452159047fSniklas unsigned short cs_ofs;
462159047fSniklas unsigned short reloc_ofs;
472159047fSniklas unsigned short reserved2;
482159047fSniklas unsigned short something1;
492159047fSniklas unsigned short something2;
502159047fSniklas unsigned short something3;
512159047fSniklas };
522159047fSniklas #endif
532159047fSniklas
542159047fSniklas #define EXE_MAGIC 0x5a4d
552159047fSniklas #define EXE_LOAD_HIGH 0x0000
562159047fSniklas #define EXE_LOAD_LOW 0xffff
572159047fSniklas #define EXE_PAGE_SIZE 512
582159047fSniklas
59c074d1c9Sdrahn static int msdos_sizeof_headers
60c074d1c9Sdrahn PARAMS ((bfd *, bfd_boolean));
61c074d1c9Sdrahn static bfd_boolean msdos_write_object_contents
62c074d1c9Sdrahn PARAMS ((bfd *));
63c074d1c9Sdrahn static bfd_boolean msdos_set_section_contents
64*007c2a45Smiod PARAMS ((bfd *, sec_ptr, const PTR, file_ptr, bfd_size_type));
652159047fSniklas
662159047fSniklas static int
msdos_sizeof_headers(abfd,exec)672159047fSniklas msdos_sizeof_headers (abfd, exec)
68b305b0f1Sespie bfd *abfd ATTRIBUTE_UNUSED;
69c074d1c9Sdrahn bfd_boolean exec ATTRIBUTE_UNUSED;
702159047fSniklas {
712159047fSniklas return 0;
722159047fSniklas }
732159047fSniklas
74c074d1c9Sdrahn static bfd_boolean
msdos_write_object_contents(abfd)752159047fSniklas msdos_write_object_contents (abfd)
762159047fSniklas bfd *abfd;
772159047fSniklas {
782159047fSniklas static char hdr[EXE_PAGE_SIZE];
792159047fSniklas file_ptr outfile_size = sizeof(hdr);
802159047fSniklas bfd_vma high_vma = 0;
812159047fSniklas asection *sec;
822159047fSniklas
832159047fSniklas /* Find the total size of the program on disk and in memory. */
842159047fSniklas for (sec = abfd->sections; sec != (asection *) NULL; sec = sec->next)
852159047fSniklas {
86c88b1d6cSniklas if (bfd_get_section_size_before_reloc (sec) == 0)
87c88b1d6cSniklas continue;
882159047fSniklas if (bfd_get_section_flags (abfd, sec) & SEC_ALLOC)
892159047fSniklas {
902159047fSniklas bfd_vma sec_vma = bfd_get_section_vma (abfd, sec)
912159047fSniklas + bfd_get_section_size_before_reloc (sec);
922159047fSniklas if (sec_vma > high_vma)
932159047fSniklas high_vma = sec_vma;
942159047fSniklas }
952159047fSniklas if (bfd_get_section_flags (abfd, sec) & SEC_LOAD)
962159047fSniklas {
972159047fSniklas file_ptr sec_end = sizeof(hdr)
982159047fSniklas + bfd_get_section_vma (abfd, sec)
992159047fSniklas + bfd_get_section_size_before_reloc (sec);
1002159047fSniklas if (sec_end > outfile_size)
1012159047fSniklas outfile_size = sec_end;
1022159047fSniklas }
1032159047fSniklas }
1042159047fSniklas
1052159047fSniklas /* Make sure the program isn't too big. */
1062159047fSniklas if (high_vma > (bfd_vma)0xffff)
1072159047fSniklas {
1082159047fSniklas bfd_set_error(bfd_error_file_too_big);
109c074d1c9Sdrahn return FALSE;
1102159047fSniklas }
1112159047fSniklas
112c074d1c9Sdrahn /* Constants. */
113c074d1c9Sdrahn H_PUT_16 (abfd, EXE_MAGIC, &hdr[0]);
114c074d1c9Sdrahn H_PUT_16 (abfd, EXE_PAGE_SIZE / 16, &hdr[8]);
115c074d1c9Sdrahn H_PUT_16 (abfd, EXE_LOAD_LOW, &hdr[12]);
116c074d1c9Sdrahn H_PUT_16 (abfd, 0x3e, &hdr[24]);
117c074d1c9Sdrahn H_PUT_16 (abfd, 0x0001, &hdr[28]); /* XXX??? */
118c074d1c9Sdrahn H_PUT_16 (abfd, 0x30fb, &hdr[30]); /* XXX??? */
119c074d1c9Sdrahn H_PUT_16 (abfd, 0x726a, &hdr[32]); /* XXX??? */
1202159047fSniklas
121c074d1c9Sdrahn /* Bytes in last page (0 = full page). */
122c074d1c9Sdrahn H_PUT_16 (abfd, outfile_size & (EXE_PAGE_SIZE - 1), &hdr[2]);
1232159047fSniklas
124c074d1c9Sdrahn /* Number of pages. */
125c074d1c9Sdrahn H_PUT_16 (abfd, (outfile_size + EXE_PAGE_SIZE - 1) / EXE_PAGE_SIZE, &hdr[4]);
1262159047fSniklas
1272159047fSniklas /* Set the initial stack pointer to the end of the bss.
1282159047fSniklas The program's crt0 code must relocate it to a real stack. */
129c074d1c9Sdrahn H_PUT_16 (abfd, high_vma, &hdr[16]);
1302159047fSniklas
1312159047fSniklas if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
132c074d1c9Sdrahn || bfd_bwrite (hdr, (bfd_size_type) sizeof(hdr), abfd) != sizeof(hdr))
133c074d1c9Sdrahn return FALSE;
1342159047fSniklas
135c074d1c9Sdrahn return TRUE;
1362159047fSniklas }
1372159047fSniklas
138c074d1c9Sdrahn static bfd_boolean
msdos_set_section_contents(abfd,section,location,offset,count)1392159047fSniklas msdos_set_section_contents (abfd, section, location, offset, count)
1402159047fSniklas bfd *abfd;
1412159047fSniklas sec_ptr section;
142*007c2a45Smiod const PTR location;
1432159047fSniklas file_ptr offset;
1442159047fSniklas bfd_size_type count;
1452159047fSniklas {
1462159047fSniklas
1472159047fSniklas if (count == 0)
148c074d1c9Sdrahn return TRUE;
1492159047fSniklas
1502159047fSniklas section->filepos = EXE_PAGE_SIZE + bfd_get_section_vma (abfd, section);
1512159047fSniklas
1522159047fSniklas if (bfd_get_section_flags (abfd, section) & SEC_LOAD)
1532159047fSniklas {
154c074d1c9Sdrahn if (bfd_seek (abfd, section->filepos + offset, SEEK_SET) != 0
155c074d1c9Sdrahn || bfd_bwrite (location, count, abfd) != count)
156c074d1c9Sdrahn return FALSE;
1572159047fSniklas }
1582159047fSniklas
159c074d1c9Sdrahn return TRUE;
1602159047fSniklas }
1612159047fSniklas
1622159047fSniklas
1632159047fSniklas
1642159047fSniklas #define msdos_mkobject aout_32_mkobject
1652159047fSniklas #define msdos_make_empty_symbol aout_32_make_empty_symbol
1662159047fSniklas #define msdos_bfd_reloc_type_lookup aout_32_reloc_type_lookup
1672159047fSniklas
1682159047fSniklas #define msdos_close_and_cleanup _bfd_generic_close_and_cleanup
1692159047fSniklas #define msdos_bfd_free_cached_info _bfd_generic_bfd_free_cached_info
1702159047fSniklas #define msdos_new_section_hook _bfd_generic_new_section_hook
1712159047fSniklas #define msdos_get_section_contents _bfd_generic_get_section_contents
1722159047fSniklas #define msdos_get_section_contents_in_window \
1732159047fSniklas _bfd_generic_get_section_contents_in_window
1742159047fSniklas #define msdos_bfd_get_relocated_section_contents \
1752159047fSniklas bfd_generic_get_relocated_section_contents
1762159047fSniklas #define msdos_bfd_relax_section bfd_generic_relax_section
177b305b0f1Sespie #define msdos_bfd_gc_sections bfd_generic_gc_sections
178c074d1c9Sdrahn #define msdos_bfd_merge_sections bfd_generic_merge_sections
179c074d1c9Sdrahn #define msdos_bfd_discard_group bfd_generic_discard_group
1802159047fSniklas #define msdos_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
181c074d1c9Sdrahn #define msdos_bfd_link_hash_table_free _bfd_generic_link_hash_table_free
1822159047fSniklas #define msdos_bfd_link_add_symbols _bfd_generic_link_add_symbols
183c074d1c9Sdrahn #define msdos_bfd_link_just_syms _bfd_generic_link_just_syms
1842159047fSniklas #define msdos_bfd_final_link _bfd_generic_final_link
1852159047fSniklas #define msdos_bfd_link_split_section _bfd_generic_link_split_section
1862159047fSniklas #define msdos_set_arch_mach _bfd_generic_set_arch_mach
1872159047fSniklas
1882159047fSniklas #define msdos_get_symtab_upper_bound _bfd_nosymbols_get_symtab_upper_bound
189*007c2a45Smiod #define msdos_canonicalize_symtab _bfd_nosymbols_canonicalize_symtab
1902159047fSniklas #define msdos_print_symbol _bfd_nosymbols_print_symbol
1912159047fSniklas #define msdos_get_symbol_info _bfd_nosymbols_get_symbol_info
1922159047fSniklas #define msdos_find_nearest_line _bfd_nosymbols_find_nearest_line
1932159047fSniklas #define msdos_get_lineno _bfd_nosymbols_get_lineno
194b305b0f1Sespie #define msdos_bfd_is_local_label_name _bfd_nosymbols_bfd_is_local_label_name
1952159047fSniklas #define msdos_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol
1962159047fSniklas #define msdos_read_minisymbols _bfd_nosymbols_read_minisymbols
1972159047fSniklas #define msdos_minisymbol_to_symbol _bfd_nosymbols_minisymbol_to_symbol
1982159047fSniklas
1992159047fSniklas #define msdos_canonicalize_reloc _bfd_norelocs_canonicalize_reloc
2002159047fSniklas #define msdos_get_reloc_upper_bound _bfd_norelocs_get_reloc_upper_bound
2012159047fSniklas #define msdos_32_bfd_link_split_section _bfd_generic_link_split_section
2022159047fSniklas
2032159047fSniklas const bfd_target i386msdos_vec =
2042159047fSniklas {
2052159047fSniklas "msdos", /* name */
2062159047fSniklas bfd_target_msdos_flavour,
207c88b1d6cSniklas BFD_ENDIAN_LITTLE, /* target byte order */
208c88b1d6cSniklas BFD_ENDIAN_LITTLE, /* target headers byte order */
2092159047fSniklas (EXEC_P), /* object flags */
2102159047fSniklas (SEC_CODE | SEC_DATA | SEC_HAS_CONTENTS
2112159047fSniklas | SEC_ALLOC | SEC_LOAD), /* section flags */
2122159047fSniklas 0, /* leading underscore */
2132159047fSniklas ' ', /* ar_pad_char */
2142159047fSniklas 16, /* ar_max_namelen */
2152159047fSniklas bfd_getl64, bfd_getl_signed_64, bfd_putl64,
2162159047fSniklas bfd_getl32, bfd_getl_signed_32, bfd_putl32,
2172159047fSniklas bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
2182159047fSniklas bfd_getl64, bfd_getl_signed_64, bfd_putl64,
2192159047fSniklas bfd_getl32, bfd_getl_signed_32, bfd_putl32,
2202159047fSniklas bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */
2212159047fSniklas
2222159047fSniklas {
2232159047fSniklas _bfd_dummy_target,
2242159047fSniklas _bfd_dummy_target, /* bfd_check_format */
2252159047fSniklas _bfd_dummy_target,
2262159047fSniklas _bfd_dummy_target,
2272159047fSniklas },
2282159047fSniklas {
2292159047fSniklas bfd_false,
2302159047fSniklas msdos_mkobject,
2312159047fSniklas _bfd_generic_mkarchive,
2322159047fSniklas bfd_false,
2332159047fSniklas },
2342159047fSniklas { /* bfd_write_contents */
2352159047fSniklas bfd_false,
2362159047fSniklas msdos_write_object_contents,
2372159047fSniklas _bfd_write_archive_contents,
2382159047fSniklas bfd_false,
2392159047fSniklas },
2402159047fSniklas
2412159047fSniklas BFD_JUMP_TABLE_GENERIC (msdos),
2422159047fSniklas BFD_JUMP_TABLE_COPY (_bfd_generic),
2432159047fSniklas BFD_JUMP_TABLE_CORE (_bfd_nocore),
2442159047fSniklas BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
2452159047fSniklas BFD_JUMP_TABLE_SYMBOLS (msdos),
2462159047fSniklas BFD_JUMP_TABLE_RELOCS (msdos),
2472159047fSniklas BFD_JUMP_TABLE_WRITE (msdos),
2482159047fSniklas BFD_JUMP_TABLE_LINK (msdos),
2492159047fSniklas BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
2502159047fSniklas
251b305b0f1Sespie NULL,
252b305b0f1Sespie
2532159047fSniklas (PTR) 0
2542159047fSniklas };
2552159047fSniklas
2562159047fSniklas
257