Fix compilation of the BFD sub-directory with a gcc v8 compiler by adding extra casts.
[deliverable/binutils-gdb.git] / bfd / i386msdos.c
CommitLineData
252b5132 1/* BFD back-end for MS-DOS executables.
219d1afa 2 Copyright (C) 1990-2018 Free Software Foundation, Inc.
252b5132
RH
3 Written by Bryan Ford of the University of Utah.
4
5 Contributed by the Center for Software Science at the
6 University of Utah (pa-gdb-bugs@cs.utah.edu).
7
8 This file is part of BFD, the Binary File Descriptor library.
9
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
cd123cb7 12 the Free Software Foundation; either version 3 of the License, or
252b5132
RH
13 (at your option) any later version.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
cd123cb7
NC
22 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
23 MA 02110-1301, USA. */
252b5132
RH
24
25
252b5132 26#include "sysdep.h"
3db64b00 27#include "bfd.h"
252b5132
RH
28#include "libbfd.h"
29#include "libaout.h"
830db048 30#include "coff/msdos.h"
252b5132 31
252b5132
RH
32#define EXE_LOAD_HIGH 0x0000
33#define EXE_LOAD_LOW 0xffff
34#define EXE_PAGE_SIZE 512
35
830db048
ZF
36static bfd_boolean
37msdos_mkobject (bfd *abfd)
38{
39 bfd_default_set_arch_mach (abfd, bfd_arch_i386, bfd_mach_i386_i8086);
40
41 return aout_32_mkobject (abfd);
42}
43
44static const bfd_target *
45msdos_object_p (bfd *abfd)
46{
47 struct external_DOS_hdr hdr;
48 bfd_byte buffer[2];
49 asection *section;
50 unsigned int size;
51
52 if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
53 || bfd_bread (&hdr, (bfd_size_type) sizeof (hdr), abfd) < DOS_HDR_SIZE)
54 {
55 if (bfd_get_error () != bfd_error_system_call)
56 bfd_set_error (bfd_error_wrong_format);
57 return NULL;
58 }
59
60 if (H_GET_16 (abfd, hdr.e_magic) != IMAGE_DOS_SIGNATURE)
61 {
62 bfd_set_error (bfd_error_wrong_format);
63 return NULL;
64 }
65
66 /* Check that this isn't actually a PE, NE, or LE file. If it is, the
67 e_lfanew field will be valid and point to a header beginning with one of
68 the relevant signatures. If not, e_lfanew might point to anything, so
69 don't bail if we can't read there. */
70 if (H_GET_16 (abfd, hdr.e_cparhdr) < 4
71 || bfd_seek (abfd, (file_ptr) H_GET_32 (abfd, hdr.e_lfanew), SEEK_SET) != 0
72 || bfd_bread (buffer, (bfd_size_type) 2, abfd) != 2)
73 {
74 if (bfd_get_error () == bfd_error_system_call)
75 return NULL;
76 }
77 else
78 {
79 if (H_GET_16 (abfd, buffer) == IMAGE_NT_SIGNATURE
80 || H_GET_16 (abfd, buffer) == IMAGE_OS2_SIGNATURE
81 || H_GET_16 (abfd, buffer) == IMAGE_OS2_SIGNATURE_LE
82 || H_GET_16 (abfd, buffer) == IMAGE_OS2_SIGNATURE_LX)
83 {
84 bfd_set_error (bfd_error_wrong_format);
85 return NULL;
86 }
87 }
88
89 if (!msdos_mkobject (abfd))
90 return NULL;
91
92 abfd->flags = EXEC_P;
93 abfd->start_address = H_GET_16 (abfd, hdr.e_ip);
94
95 section = bfd_make_section (abfd, ".text");
96 if (section == NULL)
97 return NULL;
98
99 section->flags = (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS);
100 section->filepos = H_GET_16 (abfd, hdr.e_cparhdr) * 16;
101 size = (H_GET_16 (abfd, hdr.e_cp) - 1) * EXE_PAGE_SIZE - section->filepos;
102 size += H_GET_16 (abfd, hdr.e_cblp);
103
104 /* Check that the size is valid. */
105 if (bfd_seek (abfd, (file_ptr) (section->filepos + size), SEEK_SET) != 0)
106 {
107 if (bfd_get_error () != bfd_error_system_call)
108 bfd_set_error (bfd_error_wrong_format);
109 return NULL;
110 }
111
112 bfd_set_section_size (abfd, section, size);
113 section->alignment_power = 4;
114
115 return abfd->xvec;
116}
117
252b5132 118static int
a6b96beb
AM
119msdos_sizeof_headers (bfd *abfd ATTRIBUTE_UNUSED,
120 struct bfd_link_info *info ATTRIBUTE_UNUSED)
252b5132
RH
121{
122 return 0;
123}
124
b34976b6 125static bfd_boolean
a6b96beb 126msdos_write_object_contents (bfd *abfd)
252b5132
RH
127{
128 static char hdr[EXE_PAGE_SIZE];
129 file_ptr outfile_size = sizeof(hdr);
130 bfd_vma high_vma = 0;
131 asection *sec;
132
133 /* Find the total size of the program on disk and in memory. */
134 for (sec = abfd->sections; sec != (asection *) NULL; sec = sec->next)
135 {
eea6121a 136 if (sec->size == 0)
07d6d2b8 137 continue;
252b5132 138 if (bfd_get_section_flags (abfd, sec) & SEC_ALLOC)
07d6d2b8 139 {
eea6121a 140 bfd_vma sec_vma = bfd_get_section_vma (abfd, sec) + sec->size;
252b5132
RH
141 if (sec_vma > high_vma)
142 high_vma = sec_vma;
143 }
144 if (bfd_get_section_flags (abfd, sec) & SEC_LOAD)
07d6d2b8 145 {
911d08a7
AM
146 file_ptr sec_end = (sizeof (hdr)
147 + bfd_get_section_vma (abfd, sec)
eea6121a 148 + sec->size);
252b5132
RH
149 if (sec_end > outfile_size)
150 outfile_size = sec_end;
151 }
152 }
153
154 /* Make sure the program isn't too big. */
155 if (high_vma > (bfd_vma)0xffff)
156 {
157 bfd_set_error(bfd_error_file_too_big);
b34976b6 158 return FALSE;
252b5132
RH
159 }
160
e4b17274 161 /* Constants. */
830db048 162 H_PUT_16 (abfd, IMAGE_DOS_SIGNATURE, &hdr[0]);
dc810e39
AM
163 H_PUT_16 (abfd, EXE_PAGE_SIZE / 16, &hdr[8]);
164 H_PUT_16 (abfd, EXE_LOAD_LOW, &hdr[12]);
165 H_PUT_16 (abfd, 0x3e, &hdr[24]);
166 H_PUT_16 (abfd, 0x0001, &hdr[28]); /* XXX??? */
167 H_PUT_16 (abfd, 0x30fb, &hdr[30]); /* XXX??? */
168 H_PUT_16 (abfd, 0x726a, &hdr[32]); /* XXX??? */
252b5132 169
e4b17274 170 /* Bytes in last page (0 = full page). */
dc810e39 171 H_PUT_16 (abfd, outfile_size & (EXE_PAGE_SIZE - 1), &hdr[2]);
252b5132 172
e4b17274 173 /* Number of pages. */
dc810e39 174 H_PUT_16 (abfd, (outfile_size + EXE_PAGE_SIZE - 1) / EXE_PAGE_SIZE, &hdr[4]);
252b5132
RH
175
176 /* Set the initial stack pointer to the end of the bss.
177 The program's crt0 code must relocate it to a real stack. */
dc810e39 178 H_PUT_16 (abfd, high_vma, &hdr[16]);
252b5132
RH
179
180 if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
dc810e39 181 || bfd_bwrite (hdr, (bfd_size_type) sizeof(hdr), abfd) != sizeof(hdr))
b34976b6 182 return FALSE;
252b5132 183
b34976b6 184 return TRUE;
252b5132
RH
185}
186
b34976b6 187static bfd_boolean
a6b96beb
AM
188msdos_set_section_contents (bfd *abfd,
189 sec_ptr section,
190 const void *location,
191 file_ptr offset,
192 bfd_size_type count)
252b5132
RH
193{
194
195 if (count == 0)
b34976b6 196 return TRUE;
252b5132
RH
197
198 section->filepos = EXE_PAGE_SIZE + bfd_get_section_vma (abfd, section);
199
200 if (bfd_get_section_flags (abfd, section) & SEC_LOAD)
201 {
dc810e39 202 if (bfd_seek (abfd, section->filepos + offset, SEEK_SET) != 0
07d6d2b8
AM
203 || bfd_bwrite (location, count, abfd) != count)
204 return FALSE;
252b5132
RH
205 }
206
b34976b6 207 return TRUE;
252b5132
RH
208}
209
210
211
252b5132
RH
212#define msdos_make_empty_symbol aout_32_make_empty_symbol
213#define msdos_bfd_reloc_type_lookup aout_32_reloc_type_lookup
157090f7 214#define msdos_bfd_reloc_name_lookup aout_32_reloc_name_lookup
252b5132
RH
215
216#define msdos_close_and_cleanup _bfd_generic_close_and_cleanup
217#define msdos_bfd_free_cached_info _bfd_generic_bfd_free_cached_info
218#define msdos_new_section_hook _bfd_generic_new_section_hook
219#define msdos_get_section_contents _bfd_generic_get_section_contents
220#define msdos_get_section_contents_in_window \
221 _bfd_generic_get_section_contents_in_window
222#define msdos_bfd_get_relocated_section_contents \
223 bfd_generic_get_relocated_section_contents
224#define msdos_bfd_relax_section bfd_generic_relax_section
225#define msdos_bfd_gc_sections bfd_generic_gc_sections
ae17ab41 226#define msdos_bfd_lookup_section_flags bfd_generic_lookup_section_flags
8550eb6e 227#define msdos_bfd_merge_sections bfd_generic_merge_sections
72adc230 228#define msdos_bfd_is_group_section bfd_generic_is_group_section
e61463e1 229#define msdos_bfd_discard_group bfd_generic_discard_group
082b7297
L
230#define msdos_section_already_linked \
231 _bfd_generic_section_already_linked
3023e3f6 232#define msdos_bfd_define_common_symbol bfd_generic_define_common_symbol
7dba9362 233#define msdos_bfd_define_start_stop bfd_generic_define_start_stop
252b5132
RH
234#define msdos_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
235#define msdos_bfd_link_add_symbols _bfd_generic_link_add_symbols
2d653fc7 236#define msdos_bfd_link_just_syms _bfd_generic_link_just_syms
1338dd10
PB
237#define msdos_bfd_copy_link_hash_symbol_type \
238 _bfd_generic_copy_link_hash_symbol_type
252b5132
RH
239#define msdos_bfd_final_link _bfd_generic_final_link
240#define msdos_bfd_link_split_section _bfd_generic_link_split_section
241#define msdos_set_arch_mach _bfd_generic_set_arch_mach
4f3b23b3 242#define msdos_bfd_link_check_relocs _bfd_generic_link_check_relocs
252b5132
RH
243
244#define msdos_get_symtab_upper_bound _bfd_nosymbols_get_symtab_upper_bound
6cee3f79 245#define msdos_canonicalize_symtab _bfd_nosymbols_canonicalize_symtab
252b5132
RH
246#define msdos_print_symbol _bfd_nosymbols_print_symbol
247#define msdos_get_symbol_info _bfd_nosymbols_get_symbol_info
60bb06bc
L
248#define msdos_get_symbol_version_string \
249 _bfd_nosymbols_get_symbol_version_string
252b5132 250#define msdos_find_nearest_line _bfd_nosymbols_find_nearest_line
9c461f7d 251#define msdos_find_line _bfd_nosymbols_find_line
4ab527b0 252#define msdos_find_inliner_info _bfd_nosymbols_find_inliner_info
252b5132 253#define msdos_get_lineno _bfd_nosymbols_get_lineno
12ef3f5a 254#define msdos_bfd_is_target_special_symbol ((bfd_boolean (*) (bfd *, asymbol *)) (bfd_boolean (*)) bfd_false)
252b5132
RH
255#define msdos_bfd_is_local_label_name _bfd_nosymbols_bfd_is_local_label_name
256#define msdos_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol
257#define msdos_read_minisymbols _bfd_nosymbols_read_minisymbols
258#define msdos_minisymbol_to_symbol _bfd_nosymbols_minisymbol_to_symbol
259
260#define msdos_canonicalize_reloc _bfd_norelocs_canonicalize_reloc
23186865 261#define msdos_set_reloc _bfd_norelocs_set_reloc
252b5132
RH
262#define msdos_get_reloc_upper_bound _bfd_norelocs_get_reloc_upper_bound
263#define msdos_32_bfd_link_split_section _bfd_generic_link_split_section
264
6d00b590 265const bfd_target i386_msdos_vec =
252b5132 266 {
e4b17274
NC
267 "msdos", /* name */
268 bfd_target_msdos_flavour,
269 BFD_ENDIAN_LITTLE, /* target byte order */
270 BFD_ENDIAN_LITTLE, /* target headers byte order */
271 (EXEC_P), /* object flags */
272 (SEC_CODE | SEC_DATA | SEC_HAS_CONTENTS
273 | SEC_ALLOC | SEC_LOAD), /* section flags */
274 0, /* leading underscore */
275 ' ', /* ar_pad_char */
276 16, /* ar_max_namelen */
0aabe54e 277 0, /* match priority. */
e4b17274
NC
278 bfd_getl64, bfd_getl_signed_64, bfd_putl64,
279 bfd_getl32, bfd_getl_signed_32, bfd_putl32,
280 bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* data */
281 bfd_getl64, bfd_getl_signed_64, bfd_putl64,
282 bfd_getl32, bfd_getl_signed_32, bfd_putl32,
283 bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* hdrs */
284
285 {
286 _bfd_dummy_target,
830db048 287 msdos_object_p, /* bfd_check_format */
e4b17274
NC
288 _bfd_dummy_target,
289 _bfd_dummy_target,
290 },
291 {
292 bfd_false,
293 msdos_mkobject,
294 _bfd_generic_mkarchive,
295 bfd_false,
296 },
297 { /* bfd_write_contents */
298 bfd_false,
299 msdos_write_object_contents,
300 _bfd_write_archive_contents,
301 bfd_false,
302 },
303
304 BFD_JUMP_TABLE_GENERIC (msdos),
305 BFD_JUMP_TABLE_COPY (_bfd_generic),
306 BFD_JUMP_TABLE_CORE (_bfd_nocore),
307 BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
308 BFD_JUMP_TABLE_SYMBOLS (msdos),
309 BFD_JUMP_TABLE_RELOCS (msdos),
310 BFD_JUMP_TABLE_WRITE (msdos),
311 BFD_JUMP_TABLE_LINK (msdos),
312 BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
313
314 NULL,
dc810e39 315
2c3fc389 316 NULL
e4b17274 317 };
252b5132
RH
318
319
This page took 0.997948 seconds and 4 git commands to generate.