daily update
[deliverable/binutils-gdb.git] / bfd / format.c
CommitLineData
252b5132 1/* Generic BFD support for file formats.
7898deda
NC
2 Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1999, 2000, 2001
3 Free Software Foundation, Inc.
252b5132
RH
4 Written by Cygnus Support.
5
6This file is part of BFD, the Binary File Descriptor library.
7
8This program is free software; you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation; either version 2 of the License, or
11(at your option) any later version.
12
13This program is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19along with this program; if not, write to the Free Software
20Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
21
22/*
23SECTION
24 File formats
25
26 A format is a BFD concept of high level file contents type. The
3fde5a36 27 formats supported by BFD are:
252b5132
RH
28
29 o <<bfd_object>>
30
31 The BFD may contain data, symbols, relocations and debug info.
32
33 o <<bfd_archive>>
34
35 The BFD contains other BFDs and an optional index.
36
37 o <<bfd_core>>
38
39 The BFD contains the result of an executable core dump.
40
252b5132
RH
41*/
42
43#include "bfd.h"
44#include "sysdep.h"
45#include "libbfd.h"
46
47/* IMPORT from targets.c. */
48extern const size_t _bfd_target_vector_entries;
49
50/*
51FUNCTION
52 bfd_check_format
53
54SYNOPSIS
55 boolean bfd_check_format(bfd *abfd, bfd_format format);
56
57DESCRIPTION
58 Verify if the file attached to the BFD @var{abfd} is compatible
59 with the format @var{format} (i.e., one of <<bfd_object>>,
60 <<bfd_archive>> or <<bfd_core>>).
61
62 If the BFD has been set to a specific target before the
63 call, only the named target and format combination is
64 checked. If the target has not been set, or has been set to
65 <<default>>, then all the known target backends is
66 interrogated to determine a match. If the default target
67 matches, it is used. If not, exactly one target must recognize
68 the file, or an error results.
69
70 The function returns <<true>> on success, otherwise <<false>>
3fde5a36 71 with one of the following error codes:
252b5132
RH
72
73 o <<bfd_error_invalid_operation>> -
74 if <<format>> is not one of <<bfd_object>>, <<bfd_archive>> or
75 <<bfd_core>>.
76
77 o <<bfd_error_system_call>> -
78 if an error occured during a read - even some file mismatches
79 can cause bfd_error_system_calls.
80
81 o <<file_not_recognised>> -
82 none of the backends recognised the file format.
83
84 o <<bfd_error_file_ambiguously_recognized>> -
85 more than one backend recognised the file format.
86*/
87
88boolean
89bfd_check_format (abfd, format)
90 bfd *abfd;
91 bfd_format format;
92{
93 return bfd_check_format_matches (abfd, format, NULL);
94}
95
96/*
97FUNCTION
98 bfd_check_format_matches
99
100SYNOPSIS
101 boolean bfd_check_format_matches(bfd *abfd, bfd_format format, char ***matching);
102
103DESCRIPTION
104 Like <<bfd_check_format>>, except when it returns false with
105 <<bfd_errno>> set to <<bfd_error_file_ambiguously_recognized>>. In that
106 case, if @var{matching} is not NULL, it will be filled in with
107 a NULL-terminated list of the names of the formats that matched,
108 allocated with <<malloc>>.
109 Then the user may choose a format and try again.
110
111 When done with the list that @var{matching} points to, the caller
3fde5a36 112 should free it.
252b5132
RH
113*/
114
115boolean
116bfd_check_format_matches (abfd, format, matching)
117 bfd *abfd;
118 bfd_format format;
119 char ***matching;
120{
121 extern const bfd_target binary_vec;
3619ad04 122 const bfd_target * const *target, *save_targ, *right_targ, *ar_right_targ;
252b5132
RH
123 char **matching_vector = NULL;
124 int match_count;
3619ad04 125 int ar_match_index;
252b5132 126
3619ad04 127 if (!bfd_read_p (abfd)
cea4409c 128 || (unsigned int) abfd->format >= (unsigned int) bfd_type_end)
1d713d9e
NC
129 {
130 bfd_set_error (bfd_error_invalid_operation);
131 return false;
132 }
252b5132
RH
133
134 if (abfd->format != bfd_unknown)
3619ad04 135 return abfd->format == format;
252b5132 136
3fde5a36 137 /* Since the target type was defaulted, check them
252b5132 138 all in the hope that one will be uniquely recognized. */
252b5132
RH
139 save_targ = abfd->xvec;
140 match_count = 0;
3619ad04 141 ar_match_index = _bfd_target_vector_entries;
3fde5a36 142
252b5132
RH
143 if (matching)
144 {
dc810e39
AM
145 bfd_size_type amt;
146
3619ad04 147 *matching = NULL;
dc810e39
AM
148 amt = sizeof (char *) * 2 * _bfd_target_vector_entries;
149 matching_vector = (char **) bfd_malloc (amt);
252b5132
RH
150 if (!matching_vector)
151 return false;
252b5132 152 }
3fde5a36 153
252b5132 154 right_targ = 0;
3619ad04 155 ar_right_targ = 0;
252b5132 156
1d713d9e 157 /* Presume the answer is yes. */
252b5132
RH
158 abfd->format = format;
159
160 /* If the target type was explicitly specified, just check that target. */
1d713d9e
NC
161 if (!abfd->target_defaulted)
162 {
dc810e39 163 if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0) /* rewind! */
252b5132 164 return false;
3fde5a36 165
1d713d9e 166 right_targ = BFD_SEND_FMT (abfd, _bfd_check_format, (abfd));
3fde5a36 167
1d713d9e 168 if (right_targ)
252b5132 169 {
1d713d9e 170 abfd->xvec = right_targ; /* Set the target as returned. */
3fde5a36 171
1d713d9e
NC
172 if (matching)
173 free (matching_vector);
3fde5a36 174
1d713d9e 175 return true; /* File position has moved, BTW. */
252b5132 176 }
1d713d9e
NC
177
178 /* For a long time the code has dropped through to check all
179 targets if the specified target was wrong. I don't know why,
180 and I'm reluctant to change it. However, in the case of an
181 archive, it can cause problems. If the specified target does
182 not permit archives (e.g., the binary target), then we should
183 not allow some other target to recognize it as an archive, but
184 should instead allow the specified target to recognize it as an
185 object. When I first made this change, it broke the PE target,
186 because the specified pei-i386 target did not recognize the
187 actual pe-i386 archive. Since there may be other problems of
188 this sort, I changed this test to check only for the binary
189 target. */
190 if (format == bfd_archive && save_targ == &binary_vec)
252b5132 191 {
1d713d9e
NC
192 abfd->xvec = save_targ;
193 abfd->format = bfd_unknown;
3fde5a36 194
1d713d9e
NC
195 if (matching)
196 free (matching_vector);
3fde5a36 197
1d713d9e 198 bfd_set_error (bfd_error_file_not_recognized);
3fde5a36 199
1d713d9e
NC
200 return false;
201 }
202 }
203
204 for (target = bfd_target_vector; *target != NULL; target++)
205 {
206 const bfd_target *temp;
3619ad04 207 bfd_error_type err;
3fde5a36 208
1d713d9e
NC
209 if (*target == &binary_vec)
210 continue;
3fde5a36 211
1d713d9e 212 abfd->xvec = *target; /* Change BFD's target temporarily */
3fde5a36 213
dc810e39 214 if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
1d713d9e 215 return false;
3fde5a36 216
1d713d9e
NC
217 /* If _bfd_check_format neglects to set bfd_error, assume
218 bfd_error_wrong_format. We didn't used to even pay any
219 attention to bfd_error, so I suspect that some
220 _bfd_check_format might have this problem. */
221 bfd_set_error (bfd_error_wrong_format);
222
223 temp = BFD_SEND_FMT (abfd, _bfd_check_format, (abfd));
3fde5a36 224
1d713d9e
NC
225 if (temp)
226 { /* This format checks out as ok! */
227 right_targ = temp;
3fde5a36 228
1d713d9e
NC
229 /* If this is the default target, accept it, even if other
230 targets might match. People who want those other targets
231 have to set the GNUTARGET variable. */
232 if (temp == bfd_default_vector[0])
233 {
1d713d9e
NC
234 match_count = 1;
235 break;
252b5132 236 }
3619ad04
AM
237
238 if (matching)
239 matching_vector[match_count] = temp->name;
240
241 match_count++;
242
252b5132 243#ifdef GNU960
1d713d9e
NC
244 /* Big- and little-endian b.out archives look the same, but it
245 doesn't matter: there is no difference in their headers, and
246 member file byte orders will (I hope) be handled appropriately
247 by bfd. Ditto for big and little coff archives. And the 4
248 coff/b.out object formats are unambiguous. So accept the
249 first match we find. */
250 break;
252b5132 251#endif
1d713d9e 252 }
3619ad04
AM
253 else if ((err = bfd_get_error ()) == bfd_error_wrong_object_format
254 || err == bfd_error_file_ambiguously_recognized)
255 {
256 /* An archive with objects of the wrong type, or an
257 ambiguous match. We want this target to match if we get
258 no better matches. */
259 if (ar_right_targ != bfd_default_vector[0])
260 ar_right_targ = *target;
261 if (matching)
262 matching_vector[ar_match_index] = (*target)->name;
263 ar_match_index++;
264 }
265 else if (err != bfd_error_wrong_format)
1d713d9e
NC
266 {
267 abfd->xvec = save_targ;
268 abfd->format = bfd_unknown;
3fde5a36 269
3619ad04 270 if (matching)
1d713d9e 271 free (matching_vector);
3fde5a36 272
1d713d9e
NC
273 return false;
274 }
275 }
3fde5a36 276
3619ad04
AM
277 if (match_count == 0)
278 {
279 /* Try partial matches. */
280 right_targ = ar_right_targ;
281 if (right_targ == bfd_default_vector[0])
282 {
283 match_count = 1;
284 }
285 else
286 {
287 match_count = ar_match_index - _bfd_target_vector_entries;
288 if (matching && match_count > 1)
289 {
290 memcpy (matching_vector,
291 matching_vector + _bfd_target_vector_entries,
292 sizeof (char *) * match_count);
293 }
294 }
295 }
296
1d713d9e
NC
297 if (match_count == 1)
298 {
299 abfd->xvec = right_targ; /* Change BFD's target permanently. */
3fde5a36 300
1d713d9e 301 if (matching)
252b5132 302 free (matching_vector);
3fde5a36 303
1d713d9e 304 return true; /* File position has moved, BTW. */
252b5132 305 }
252b5132 306
1d713d9e
NC
307 abfd->xvec = save_targ; /* Restore original target type. */
308 abfd->format = bfd_unknown; /* Restore original format. */
3fde5a36 309
252b5132
RH
310 if (match_count == 0)
311 {
312 bfd_set_error (bfd_error_file_not_recognized);
3fde5a36 313
252b5132
RH
314 if (matching)
315 free (matching_vector);
316 }
317 else
3619ad04
AM
318 {
319 bfd_set_error (bfd_error_file_ambiguously_recognized);
320
321 if (matching)
322 {
323 *matching = matching_vector;
324 matching_vector[match_count] = NULL;
325 }
326 }
3fde5a36 327
252b5132
RH
328 return false;
329}
330
331/*
332FUNCTION
333 bfd_set_format
334
335SYNOPSIS
336 boolean bfd_set_format(bfd *abfd, bfd_format format);
337
338DESCRIPTION
339 This function sets the file format of the BFD @var{abfd} to the
340 format @var{format}. If the target set in the BFD does not
341 support the format requested, the format is invalid, or the BFD
342 is not open for writing, then an error occurs.
252b5132
RH
343*/
344
345boolean
346bfd_set_format (abfd, format)
347 bfd *abfd;
348 bfd_format format;
349{
3619ad04 350 if (bfd_read_p (abfd)
cea4409c 351 || (unsigned int) abfd->format >= (unsigned int) bfd_type_end)
1d713d9e
NC
352 {
353 bfd_set_error (bfd_error_invalid_operation);
354 return false;
355 }
252b5132
RH
356
357 if (abfd->format != bfd_unknown)
1d713d9e 358 return (abfd->format == format) ? true : false;
252b5132 359
1d713d9e 360 /* Presume the answer is yes. */
252b5132
RH
361 abfd->format = format;
362
1d713d9e
NC
363 if (!BFD_SEND_FMT (abfd, _bfd_set_format, (abfd)))
364 {
365 abfd->format = bfd_unknown;
366 return false;
367 }
252b5132
RH
368
369 return true;
370}
371
252b5132
RH
372/*
373FUNCTION
374 bfd_format_string
375
376SYNOPSIS
3619ad04 377 const char *bfd_format_string(bfd_format format);
252b5132
RH
378
379DESCRIPTION
380 Return a pointer to a const string
381 <<invalid>>, <<object>>, <<archive>>, <<core>>, or <<unknown>>,
382 depending upon the value of @var{format}.
383*/
384
3619ad04 385const char *
252b5132
RH
386bfd_format_string (format)
387 bfd_format format;
388{
3fde5a36
KH
389 if (((int)format <(int) bfd_unknown)
390 || ((int)format >=(int) bfd_type_end))
252b5132 391 return "invalid";
3fde5a36 392
1d713d9e
NC
393 switch (format)
394 {
395 case bfd_object:
396 return "object"; /* Linker/assember/compiler output. */
3fde5a36 397 case bfd_archive:
1d713d9e 398 return "archive"; /* Object archive file. */
3fde5a36 399 case bfd_core:
1d713d9e 400 return "core"; /* Core dump. */
3fde5a36 401 default:
1d713d9e
NC
402 return "unknown";
403 }
252b5132 404}
This page took 0.134499 seconds and 4 git commands to generate.