coff-stgo32.c revision 1.1.1.2.8.1 1 1.1 skrll /* BFD back-end for Intel 386 COFF files (DJGPP variant with a stub).
2 1.1.1.2.8.1 tls Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2005, 2006, 2007, 2009,
3 1.1.1.2.8.1 tls 2011, 2012 Free Software Foundation, Inc.
4 1.1 skrll Written by Robert Hoehne.
5 1.1 skrll
6 1.1 skrll This file is part of BFD, the Binary File Descriptor library.
7 1.1 skrll
8 1.1 skrll This program is free software; you can redistribute it and/or modify
9 1.1 skrll it under the terms of the GNU General Public License as published by
10 1.1 skrll the Free Software Foundation; either version 3 of the License, or
11 1.1 skrll (at your option) any later version.
12 1.1 skrll
13 1.1 skrll This program is distributed in the hope that it will be useful,
14 1.1 skrll but WITHOUT ANY WARRANTY; without even the implied warranty of
15 1.1 skrll MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 1.1 skrll GNU General Public License for more details.
17 1.1 skrll
18 1.1 skrll You should have received a copy of the GNU General Public License
19 1.1 skrll along with this program; if not, write to the Free Software
20 1.1 skrll Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
21 1.1 skrll MA 02110-1301, USA. */
22 1.1 skrll
23 1.1 skrll /* This file handles now also stubbed coff images. The stub is a small
24 1.1 skrll DOS executable program before the coff image to load it in memory
25 1.1 skrll and execute it. This is needed, because DOS cannot run coff files.
26 1.1 skrll
27 1.1 skrll All the functions below are called by the corresponding functions
28 1.1 skrll from coffswap.h.
29 1.1 skrll The only thing what they do is to adjust the information stored in
30 1.1 skrll the COFF file which are offset into the file.
31 1.1 skrll This is needed, because DJGPP uses a very special way to load and run
32 1.1 skrll the coff image. It loads the image in memory and assumes then, that the
33 1.1 skrll image had no stub by using the filepointers as pointers in the coff
34 1.1 skrll image and NOT in the file.
35 1.1 skrll
36 1.1 skrll To be compatible with any existing executables I have fixed this
37 1.1 skrll here and NOT in the DJGPP startup code. */
38 1.1 skrll
39 1.1 skrll #define TARGET_SYM go32stubbedcoff_vec
40 1.1 skrll #define TARGET_NAME "coff-go32-exe"
41 1.1 skrll #define TARGET_UNDERSCORE '_'
42 1.1 skrll #define COFF_GO32_EXE
43 1.1 skrll #define COFF_LONG_SECTION_NAMES
44 1.1 skrll #define COFF_SUPPORT_GNU_LINKONCE
45 1.1 skrll #define COFF_LONG_FILENAMES
46 1.1 skrll
47 1.1 skrll #define COFF_SECTION_ALIGNMENT_ENTRIES \
48 1.1 skrll { COFF_SECTION_NAME_EXACT_MATCH (".data"), \
49 1.1 skrll COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 4 }, \
50 1.1 skrll { COFF_SECTION_NAME_EXACT_MATCH (".text"), \
51 1.1 skrll COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 4 }, \
52 1.1 skrll { COFF_SECTION_NAME_PARTIAL_MATCH (".debug"), \
53 1.1 skrll COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 0 }, \
54 1.1 skrll { COFF_SECTION_NAME_PARTIAL_MATCH (".gnu.linkonce.wi"), \
55 1.1 skrll COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 0 }
56 1.1 skrll
57 1.1.1.2.8.1 tls #include "sysdep.h"
58 1.1 skrll #include "bfd.h"
59 1.1 skrll
60 1.1.1.2.8.1 tls /* All that ..._PRE and ...POST functions are called from the corresponding
61 1.1.1.2.8.1 tls coff_swap... functions. The ...PRE functions are called at the beginning
62 1.1.1.2.8.1 tls of the function and the ...POST functions at the end of the swap routines. */
63 1.1 skrll
64 1.1 skrll static void
65 1.1.1.2.8.1 tls adjust_filehdr_in_post (bfd *, void *, void *);
66 1.1 skrll static void
67 1.1.1.2.8.1 tls adjust_filehdr_out_pre (bfd *, void *, void *);
68 1.1 skrll static void
69 1.1.1.2.8.1 tls adjust_filehdr_out_post (bfd *, void *, void *);
70 1.1 skrll static void
71 1.1.1.2.8.1 tls adjust_scnhdr_in_post (bfd *, void *, void *);
72 1.1 skrll static void
73 1.1.1.2.8.1 tls adjust_scnhdr_out_pre (bfd *, void *, void *);
74 1.1 skrll static void
75 1.1.1.2.8.1 tls adjust_scnhdr_out_post (bfd *, void *, void *);
76 1.1 skrll static void
77 1.1.1.2.8.1 tls adjust_aux_in_post (bfd *, void *, int, int, int, int, void *);
78 1.1 skrll static void
79 1.1.1.2.8.1 tls adjust_aux_out_pre (bfd *, void *, int, int, int, int, void *);
80 1.1 skrll static void
81 1.1.1.2.8.1 tls adjust_aux_out_post (bfd *, void *, int, int, int, int, void *);
82 1.1 skrll static void
83 1.1.1.2.8.1 tls create_go32_stub (bfd *);
84 1.1 skrll
85 1.1 skrll #define COFF_ADJUST_FILEHDR_IN_POST adjust_filehdr_in_post
86 1.1 skrll #define COFF_ADJUST_FILEHDR_OUT_PRE adjust_filehdr_out_pre
87 1.1 skrll #define COFF_ADJUST_FILEHDR_OUT_POST adjust_filehdr_out_post
88 1.1 skrll
89 1.1 skrll #define COFF_ADJUST_SCNHDR_IN_POST adjust_scnhdr_in_post
90 1.1 skrll #define COFF_ADJUST_SCNHDR_OUT_PRE adjust_scnhdr_out_pre
91 1.1 skrll #define COFF_ADJUST_SCNHDR_OUT_POST adjust_scnhdr_out_post
92 1.1 skrll
93 1.1 skrll #define COFF_ADJUST_AUX_IN_POST adjust_aux_in_post
94 1.1 skrll #define COFF_ADJUST_AUX_OUT_PRE adjust_aux_out_pre
95 1.1 skrll #define COFF_ADJUST_AUX_OUT_POST adjust_aux_out_post
96 1.1 skrll
97 1.1.1.2.8.1 tls static const bfd_target *go32_check_format (bfd *);
98 1.1.1.2.8.1 tls
99 1.1.1.2.8.1 tls #define COFF_CHECK_FORMAT go32_check_format
100 1.1.1.2.8.1 tls
101 1.1 skrll static bfd_boolean
102 1.1.1.2.8.1 tls go32_stubbed_coff_bfd_copy_private_bfd_data (bfd *, bfd *);
103 1.1 skrll
104 1.1 skrll #define coff_bfd_copy_private_bfd_data go32_stubbed_coff_bfd_copy_private_bfd_data
105 1.1 skrll
106 1.1 skrll #include "coff-i386.c"
107 1.1 skrll
108 1.1.1.2.8.1 tls /* This macro is used, because I cannot assume the endianness of the
109 1.1 skrll host system. */
110 1.1.1.2.8.1 tls #define _H(index) (H_GET_16 (abfd, (header + index * 2)))
111 1.1 skrll
112 1.1 skrll /* These bytes are a 2048-byte DOS executable, which loads the COFF
113 1.1 skrll image into memory and then runs it. It is called 'stub'. */
114 1.1 skrll
115 1.1.1.2 christos static const unsigned char stub_bytes[GO32_STUBSIZE] =
116 1.1 skrll {
117 1.1 skrll #include "go32stub.h"
118 1.1 skrll };
119 1.1 skrll
120 1.1 skrll /*
121 1.1 skrll I have not commented each swap function below, because the
122 1.1 skrll technique is in any function the same. For the ...in function,
123 1.1.1.2 christos all the pointers are adjusted by adding GO32_STUBSIZE and for the
124 1.1 skrll ...out function, it is subtracted first and after calling the
125 1.1 skrll standard swap function it is reset to the old value. */
126 1.1 skrll
127 1.1 skrll /* This macro is used for adjusting the filepointers, which
128 1.1 skrll is done only, if the pointer is nonzero. */
129 1.1 skrll
130 1.1 skrll #define ADJUST_VAL(val,diff) \
131 1.1 skrll if (val != 0) val += diff
132 1.1 skrll
133 1.1 skrll static void
134 1.1.1.2.8.1 tls adjust_filehdr_in_post (bfd * abfd ATTRIBUTE_UNUSED,
135 1.1.1.2.8.1 tls void * src,
136 1.1.1.2.8.1 tls void * dst)
137 1.1 skrll {
138 1.1 skrll FILHDR *filehdr_src = (FILHDR *) src;
139 1.1 skrll struct internal_filehdr *filehdr_dst = (struct internal_filehdr *) dst;
140 1.1 skrll
141 1.1.1.2 christos ADJUST_VAL (filehdr_dst->f_symptr, GO32_STUBSIZE);
142 1.1 skrll
143 1.1.1.2 christos /* Save now the stub to be used later. Put the stub data to FILEHDR_DST
144 1.1.1.2 christos first as coff_data (abfd) still does not exist. It may not even be ever
145 1.1.1.2 christos created as we are just checking the file format of ABFD. */
146 1.1.1.2 christos memcpy (filehdr_dst->go32stub, filehdr_src->stub, GO32_STUBSIZE);
147 1.1.1.2 christos filehdr_dst->f_flags |= F_GO32STUB;
148 1.1 skrll }
149 1.1 skrll
150 1.1 skrll static void
151 1.1.1.2.8.1 tls adjust_filehdr_out_pre (bfd * abfd, void * in, void * out)
152 1.1 skrll {
153 1.1 skrll struct internal_filehdr *filehdr_in = (struct internal_filehdr *) in;
154 1.1 skrll FILHDR *filehdr_out = (FILHDR *) out;
155 1.1 skrll
156 1.1 skrll /* Generate the stub. */
157 1.1 skrll create_go32_stub (abfd);
158 1.1 skrll
159 1.1 skrll /* Copy the stub to the file header. */
160 1.1.1.2 christos if (coff_data (abfd)->go32stub != NULL)
161 1.1.1.2 christos memcpy (filehdr_out->stub, coff_data (abfd)->go32stub, GO32_STUBSIZE);
162 1.1 skrll else
163 1.1 skrll /* Use the default. */
164 1.1.1.2 christos memcpy (filehdr_out->stub, stub_bytes, GO32_STUBSIZE);
165 1.1 skrll
166 1.1.1.2 christos ADJUST_VAL (filehdr_in->f_symptr, -GO32_STUBSIZE);
167 1.1 skrll }
168 1.1 skrll
169 1.1 skrll static void
170 1.1.1.2.8.1 tls adjust_filehdr_out_post (bfd * abfd ATTRIBUTE_UNUSED,
171 1.1.1.2.8.1 tls void * in,
172 1.1.1.2.8.1 tls void * out ATTRIBUTE_UNUSED)
173 1.1 skrll {
174 1.1 skrll struct internal_filehdr *filehdr_in = (struct internal_filehdr *) in;
175 1.1 skrll /* Undo the above change. */
176 1.1.1.2 christos ADJUST_VAL (filehdr_in->f_symptr, GO32_STUBSIZE);
177 1.1 skrll }
178 1.1 skrll
179 1.1 skrll static void
180 1.1.1.2.8.1 tls adjust_scnhdr_in_post (bfd * abfd ATTRIBUTE_UNUSED,
181 1.1.1.2.8.1 tls void * ext ATTRIBUTE_UNUSED,
182 1.1.1.2.8.1 tls void * in)
183 1.1 skrll {
184 1.1 skrll struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *) in;
185 1.1 skrll
186 1.1.1.2 christos ADJUST_VAL (scnhdr_int->s_scnptr, GO32_STUBSIZE);
187 1.1.1.2 christos ADJUST_VAL (scnhdr_int->s_relptr, GO32_STUBSIZE);
188 1.1.1.2 christos ADJUST_VAL (scnhdr_int->s_lnnoptr, GO32_STUBSIZE);
189 1.1 skrll }
190 1.1 skrll
191 1.1 skrll static void
192 1.1.1.2.8.1 tls adjust_scnhdr_out_pre (bfd * abfd ATTRIBUTE_UNUSED,
193 1.1.1.2.8.1 tls void * in,
194 1.1.1.2.8.1 tls void * out ATTRIBUTE_UNUSED)
195 1.1 skrll {
196 1.1 skrll struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *) in;
197 1.1 skrll
198 1.1.1.2 christos ADJUST_VAL (scnhdr_int->s_scnptr, -GO32_STUBSIZE);
199 1.1.1.2 christos ADJUST_VAL (scnhdr_int->s_relptr, -GO32_STUBSIZE);
200 1.1.1.2 christos ADJUST_VAL (scnhdr_int->s_lnnoptr, -GO32_STUBSIZE);
201 1.1 skrll }
202 1.1 skrll
203 1.1 skrll static void
204 1.1.1.2.8.1 tls adjust_scnhdr_out_post (bfd * abfd ATTRIBUTE_UNUSED,
205 1.1.1.2.8.1 tls void * in,
206 1.1.1.2.8.1 tls void * out ATTRIBUTE_UNUSED)
207 1.1 skrll {
208 1.1 skrll struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *) in;
209 1.1 skrll
210 1.1.1.2 christos ADJUST_VAL (scnhdr_int->s_scnptr, GO32_STUBSIZE);
211 1.1.1.2 christos ADJUST_VAL (scnhdr_int->s_relptr, GO32_STUBSIZE);
212 1.1.1.2 christos ADJUST_VAL (scnhdr_int->s_lnnoptr, GO32_STUBSIZE);
213 1.1 skrll }
214 1.1 skrll
215 1.1 skrll static void
216 1.1.1.2.8.1 tls adjust_aux_in_post (bfd * abfd ATTRIBUTE_UNUSED,
217 1.1.1.2.8.1 tls void * ext1 ATTRIBUTE_UNUSED,
218 1.1.1.2.8.1 tls int type,
219 1.1.1.2.8.1 tls int in_class,
220 1.1.1.2.8.1 tls int indx ATTRIBUTE_UNUSED,
221 1.1.1.2.8.1 tls int numaux ATTRIBUTE_UNUSED,
222 1.1.1.2.8.1 tls void * in1)
223 1.1 skrll {
224 1.1 skrll union internal_auxent *in = (union internal_auxent *) in1;
225 1.1 skrll
226 1.1.1.2 christos if (in_class == C_BLOCK || in_class == C_FCN || ISFCN (type)
227 1.1.1.2 christos || ISTAG (in_class))
228 1.1 skrll {
229 1.1.1.2 christos ADJUST_VAL (in->x_sym.x_fcnary.x_fcn.x_lnnoptr, GO32_STUBSIZE);
230 1.1 skrll }
231 1.1 skrll }
232 1.1 skrll
233 1.1 skrll static void
234 1.1.1.2.8.1 tls adjust_aux_out_pre (bfd *abfd ATTRIBUTE_UNUSED,
235 1.1.1.2.8.1 tls void * inp,
236 1.1.1.2.8.1 tls int type,
237 1.1.1.2.8.1 tls int in_class,
238 1.1.1.2.8.1 tls int indx ATTRIBUTE_UNUSED,
239 1.1.1.2.8.1 tls int numaux ATTRIBUTE_UNUSED,
240 1.1.1.2.8.1 tls void * extp ATTRIBUTE_UNUSED)
241 1.1 skrll {
242 1.1 skrll union internal_auxent *in = (union internal_auxent *) inp;
243 1.1 skrll
244 1.1.1.2 christos if (in_class == C_BLOCK || in_class == C_FCN || ISFCN (type)
245 1.1.1.2 christos || ISTAG (in_class))
246 1.1 skrll {
247 1.1.1.2 christos ADJUST_VAL (in->x_sym.x_fcnary.x_fcn.x_lnnoptr, -GO32_STUBSIZE);
248 1.1 skrll }
249 1.1 skrll }
250 1.1 skrll
251 1.1 skrll static void
252 1.1.1.2.8.1 tls adjust_aux_out_post (bfd *abfd ATTRIBUTE_UNUSED,
253 1.1.1.2.8.1 tls void * inp,
254 1.1.1.2.8.1 tls int type,
255 1.1.1.2.8.1 tls int in_class,
256 1.1.1.2.8.1 tls int indx ATTRIBUTE_UNUSED,
257 1.1.1.2.8.1 tls int numaux ATTRIBUTE_UNUSED,
258 1.1.1.2.8.1 tls void * extp ATTRIBUTE_UNUSED)
259 1.1 skrll {
260 1.1 skrll union internal_auxent *in = (union internal_auxent *) inp;
261 1.1 skrll
262 1.1.1.2 christos if (in_class == C_BLOCK || in_class == C_FCN || ISFCN (type)
263 1.1.1.2 christos || ISTAG (in_class))
264 1.1 skrll {
265 1.1.1.2 christos ADJUST_VAL (in->x_sym.x_fcnary.x_fcn.x_lnnoptr, GO32_STUBSIZE);
266 1.1 skrll }
267 1.1 skrll }
268 1.1 skrll
269 1.1 skrll /* That's the function, which creates the stub. There are
270 1.1 skrll different cases from where the stub is taken.
271 1.1 skrll At first the environment variable $(GO32STUB) is checked and then
272 1.1 skrll $(STUB) if it was not set.
273 1.1 skrll If it exists and points to a valid stub the stub is taken from
274 1.1 skrll that file. This file can be also a whole executable file, because
275 1.1 skrll the stub is computed from the exe information at the start of that
276 1.1 skrll file.
277 1.1 skrll
278 1.1 skrll If there was any error, the standard stub (compiled in this file)
279 1.1 skrll is taken. */
280 1.1 skrll
281 1.1 skrll static void
282 1.1.1.2.8.1 tls create_go32_stub (bfd *abfd)
283 1.1 skrll {
284 1.1 skrll /* Do it only once. */
285 1.1.1.2 christos if (coff_data (abfd)->go32stub == NULL)
286 1.1 skrll {
287 1.1 skrll char *stub;
288 1.1 skrll struct stat st;
289 1.1 skrll int f;
290 1.1 skrll unsigned char header[10];
291 1.1 skrll char magic[8];
292 1.1 skrll unsigned long coff_start;
293 1.1 skrll long exe_start;
294 1.1 skrll
295 1.1 skrll /* Check at first the environment variable $(GO32STUB). */
296 1.1 skrll stub = getenv ("GO32STUB");
297 1.1 skrll /* Now check the environment variable $(STUB). */
298 1.1 skrll if (stub == NULL)
299 1.1 skrll stub = getenv ("STUB");
300 1.1 skrll if (stub == NULL)
301 1.1 skrll goto stub_end;
302 1.1 skrll if (stat (stub, &st) != 0)
303 1.1 skrll goto stub_end;
304 1.1 skrll #ifdef O_BINARY
305 1.1 skrll f = open (stub, O_RDONLY | O_BINARY);
306 1.1 skrll #else
307 1.1 skrll f = open (stub, O_RDONLY);
308 1.1 skrll #endif
309 1.1 skrll if (f < 0)
310 1.1 skrll goto stub_end;
311 1.1 skrll if (read (f, &header, sizeof (header)) < 0)
312 1.1 skrll {
313 1.1 skrll close (f);
314 1.1 skrll goto stub_end;
315 1.1 skrll }
316 1.1 skrll if (_H (0) != 0x5a4d) /* It is not an exe file. */
317 1.1 skrll {
318 1.1 skrll close (f);
319 1.1 skrll goto stub_end;
320 1.1 skrll }
321 1.1 skrll /* Compute the size of the stub (it is every thing up
322 1.1 skrll to the beginning of the coff image). */
323 1.1 skrll coff_start = (long) _H (2) * 512L;
324 1.1 skrll if (_H (1))
325 1.1 skrll coff_start += (long) _H (1) - 512L;
326 1.1 skrll
327 1.1 skrll /* Currently there is only a fixed stub size of 2048 bytes
328 1.1 skrll supported. */
329 1.1 skrll if (coff_start != 2048)
330 1.1 skrll {
331 1.1 skrll close (f);
332 1.1 skrll goto stub_end;
333 1.1 skrll }
334 1.1 skrll exe_start = _H (4) * 16;
335 1.1 skrll if ((long) lseek (f, exe_start, SEEK_SET) != exe_start)
336 1.1 skrll {
337 1.1 skrll close (f);
338 1.1 skrll goto stub_end;
339 1.1 skrll }
340 1.1 skrll if (read (f, &magic, 8) != 8)
341 1.1 skrll {
342 1.1 skrll close (f);
343 1.1 skrll goto stub_end;
344 1.1 skrll }
345 1.1 skrll if (! CONST_STRNEQ (magic, "go32stub"))
346 1.1 skrll {
347 1.1 skrll close (f);
348 1.1 skrll goto stub_end;
349 1.1 skrll }
350 1.1 skrll /* Now we found a correct stub (hopefully). */
351 1.1.1.2 christos coff_data (abfd)->go32stub = bfd_alloc (abfd, (bfd_size_type) coff_start);
352 1.1.1.2 christos if (coff_data (abfd)->go32stub == NULL)
353 1.1 skrll {
354 1.1 skrll close (f);
355 1.1 skrll return;
356 1.1 skrll }
357 1.1 skrll lseek (f, 0L, SEEK_SET);
358 1.1.1.2 christos if ((unsigned long) read (f, coff_data (abfd)->go32stub, coff_start)
359 1.1 skrll != coff_start)
360 1.1 skrll {
361 1.1.1.2 christos bfd_release (abfd, coff_data (abfd)->go32stub);
362 1.1.1.2 christos coff_data (abfd)->go32stub = NULL;
363 1.1 skrll }
364 1.1 skrll close (f);
365 1.1 skrll }
366 1.1 skrll stub_end:
367 1.1 skrll /* There was something wrong above, so use now the standard builtin
368 1.1 skrll stub. */
369 1.1.1.2 christos if (coff_data (abfd)->go32stub == NULL)
370 1.1 skrll {
371 1.1.1.2 christos coff_data (abfd)->go32stub
372 1.1.1.2 christos = bfd_alloc (abfd, (bfd_size_type) GO32_STUBSIZE);
373 1.1.1.2 christos if (coff_data (abfd)->go32stub == NULL)
374 1.1 skrll return;
375 1.1.1.2 christos memcpy (coff_data (abfd)->go32stub, stub_bytes, GO32_STUBSIZE);
376 1.1 skrll }
377 1.1 skrll }
378 1.1 skrll
379 1.1 skrll /* If ibfd was a stubbed coff image, copy the stub from that bfd
380 1.1 skrll to the new obfd. */
381 1.1 skrll
382 1.1 skrll static bfd_boolean
383 1.1.1.2.8.1 tls go32_stubbed_coff_bfd_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
384 1.1 skrll {
385 1.1 skrll /* Check if both are the same targets. */
386 1.1 skrll if (ibfd->xvec != obfd->xvec)
387 1.1 skrll return TRUE;
388 1.1 skrll
389 1.1.1.2 christos /* Check if we have a source stub. */
390 1.1.1.2 christos if (coff_data (ibfd)->go32stub == NULL)
391 1.1 skrll return TRUE;
392 1.1 skrll
393 1.1.1.2 christos /* As adjust_filehdr_out_pre may get called only after this function,
394 1.1.1.2 christos optionally allocate the output stub. */
395 1.1.1.2 christos if (coff_data (obfd)->go32stub == NULL)
396 1.1.1.2 christos coff_data (obfd)->go32stub = bfd_alloc (obfd,
397 1.1.1.2 christos (bfd_size_type) GO32_STUBSIZE);
398 1.1.1.2 christos
399 1.1 skrll /* Now copy the stub. */
400 1.1.1.2 christos if (coff_data (obfd)->go32stub != NULL)
401 1.1.1.2 christos memcpy (coff_data (obfd)->go32stub, coff_data (ibfd)->go32stub,
402 1.1.1.2 christos GO32_STUBSIZE);
403 1.1 skrll
404 1.1 skrll return TRUE;
405 1.1 skrll }
406 1.1.1.2.8.1 tls
407 1.1.1.2.8.1 tls /* coff_object_p only checks 2 bytes F_MAGIC at GO32_STUBSIZE inside the file
408 1.1.1.2.8.1 tls which is too fragile. */
409 1.1.1.2.8.1 tls
410 1.1.1.2.8.1 tls static const bfd_target *
411 1.1.1.2.8.1 tls go32_check_format (bfd *abfd)
412 1.1.1.2.8.1 tls {
413 1.1.1.2.8.1 tls char mz[2];
414 1.1.1.2.8.1 tls
415 1.1.1.2.8.1 tls if (bfd_bread (mz, 2, abfd) != 2 || mz[0] != 'M' || mz[1] != 'Z')
416 1.1.1.2.8.1 tls {
417 1.1.1.2.8.1 tls bfd_set_error (bfd_error_wrong_format);
418 1.1.1.2.8.1 tls return NULL;
419 1.1.1.2.8.1 tls }
420 1.1.1.2.8.1 tls
421 1.1.1.2.8.1 tls if (bfd_seek (abfd, 0, SEEK_SET) != 0)
422 1.1.1.2.8.1 tls return NULL;
423 1.1.1.2.8.1 tls
424 1.1.1.2.8.1 tls return coff_object_p (abfd);
425 1.1.1.2.8.1 tls }
426