* configure.in: Change AC_PREREQ to 2.13. Remove AM_CYGWIN32.
[deliverable/binutils-gdb.git] / bfd / format.c
CommitLineData
6724ff46 1/* Generic BFD support for file formats.
6efd50e3 2 Copyright (C) 1990, 91, 92, 93, 94, 95, 1999 Free Software Foundation, Inc.
6724ff46
RP
3 Written by Cygnus Support.
4
5This file is part of BFD, the Binary File Descriptor library.
6
7This program is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2 of the License, or
10(at your option) any later version.
11
12This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with this program; if not, write to the Free Software
6efd50e3 19Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
6724ff46 20
c188b0be
DM
21/*
22SECTION
3b31740c 23 File formats
c188b0be
DM
24
25 A format is a BFD concept of high level file contents type. The
26 formats supported by BFD are:
27
28 o <<bfd_object>>
29
30 The BFD may contain data, symbols, relocations and debug info.
31
32 o <<bfd_archive>>
33
34 The BFD contains other BFDs and an optional index.
35
36 o <<bfd_core>>
37
38 The BFD contains the result of an executable core dump.
39
40
6724ff46 41*/
c188b0be 42
6724ff46 43#include "bfd.h"
c188b0be 44#include "sysdep.h"
6724ff46
RP
45#include "libbfd.h"
46
3b31740c 47/* IMPORT from targets.c. */
6efd50e3 48extern const size_t _bfd_target_vector_entries;
6724ff46 49
c188b0be
DM
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>>
71 with one of the following error codes:
72
6efd50e3 73 o <<bfd_error_invalid_operation>> -
c188b0be
DM
74 if <<format>> is not one of <<bfd_object>>, <<bfd_archive>> or
75 <<bfd_core>>.
76
6efd50e3 77 o <<bfd_error_system_call>> -
c188b0be 78 if an error occured during a read - even some file mismatches
6efd50e3 79 can cause bfd_error_system_calls.
c188b0be 80
3b31740c 81 o <<file_not_recognised>> -
c188b0be
DM
82 none of the backends recognised the file format.
83
6efd50e3 84 o <<bfd_error_file_ambiguously_recognized>> -
c188b0be 85 more than one backend recognised the file format.
aabda2da
DM
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);
c188b0be 102
aabda2da
DM
103DESCRIPTION
104 Like <<bfd_check_format>>, except when it returns false with
6efd50e3 105 <<bfd_errno>> set to <<bfd_error_file_ambiguously_recognized>>. In that
aabda2da
DM
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
112 should free it.
c188b0be 113*/
6724ff46
RP
114
115boolean
aabda2da
DM
116bfd_check_format_matches (abfd, format, matching)
117 bfd *abfd;
118 bfd_format format;
119 char ***matching;
6724ff46 120{
6efd50e3
ILT
121 const bfd_target * const *target, *save_targ, *right_targ;
122 char **matching_vector = NULL;
6724ff46
RP
123 int match_count;
124
125 if (!bfd_read_p (abfd) ||
126 ((int)(abfd->format) < (int)bfd_unknown) ||
127 ((int)(abfd->format) >= (int)bfd_type_end)) {
6efd50e3 128 bfd_set_error (bfd_error_invalid_operation);
6724ff46
RP
129 return false;
130 }
131
132 if (abfd->format != bfd_unknown)
133 return (abfd->format == format)? true: false;
134
c188b0be
DM
135
136 /* Since the target type was defaulted, check them
137 all in the hope that one will be uniquely recognized. */
138
139 save_targ = abfd->xvec;
140 match_count = 0;
aabda2da
DM
141 if (matching)
142 {
6efd50e3
ILT
143 matching_vector =
144 (char **) bfd_malloc (sizeof (char *) *
145 (_bfd_target_vector_entries + 1));
146 if (!matching_vector)
147 return false;
aabda2da 148 matching_vector[0] = NULL;
6efd50e3 149 *matching = matching_vector;
aabda2da 150 }
c188b0be
DM
151 right_targ = 0;
152
153
6724ff46
RP
154 /* presume the answer is yes */
155 abfd->format = format;
156
157 /* If the target type was explicitly specified, just check that target. */
158
159 if (!abfd->target_defaulted) {
6efd50e3
ILT
160 if (bfd_seek (abfd, (file_ptr)0, SEEK_SET) != 0) /* rewind! */
161 return false;
6724ff46
RP
162 right_targ = BFD_SEND_FMT (abfd, _bfd_check_format, (abfd));
163 if (right_targ) {
164 abfd->xvec = right_targ; /* Set the target as returned */
aabda2da
DM
165 if (matching)
166 free (matching_vector);
6724ff46
RP
167 return true; /* File position has moved, BTW */
168 }
6efd50e3
ILT
169
170 /* For a long time the code has dropped through to check all
171 targets if the specified target was wrong. I don't know why,
172 and I'm reluctant to change it. However, in the case of an
173 archive, it can cause problems. If the specified target does
174 not permit archives (e.g., the binary target), then we should
175 not allow some other target to recognize it as an archive, but
176 should instead allow the specified target to recognize it as an
177 object. */
178
179 if (format == bfd_archive)
180 {
181 abfd->xvec = save_targ;
182 abfd->format = bfd_unknown;
183 if (matching)
184 free (matching_vector);
185 bfd_set_error (bfd_error_file_not_recognized);
186 return false;
187 }
6724ff46
RP
188 }
189
f4bd7a8f 190 for (target = bfd_target_vector; *target != NULL; target++) {
6efd50e3
ILT
191 extern const bfd_target binary_vec;
192 const bfd_target *temp;
193
194 if (*target == &binary_vec)
195 continue;
6724ff46
RP
196
197 abfd->xvec = *target; /* Change BFD's target temporarily */
6efd50e3
ILT
198 if (bfd_seek (abfd, (file_ptr)0, SEEK_SET) != 0)
199 return false;
200 /* If _bfd_check_format neglects to set bfd_error, assume bfd_error_wrong_format.
c188b0be
DM
201 We didn't used to even pay any attention to bfd_error, so I suspect
202 that some _bfd_check_format might have this problem. */
6efd50e3 203 bfd_set_error (bfd_error_wrong_format);
6724ff46
RP
204 temp = BFD_SEND_FMT (abfd, _bfd_check_format, (abfd));
205 if (temp) { /* This format checks out as ok! */
206 right_targ = temp;
aabda2da
DM
207 if (matching)
208 {
209 matching_vector[match_count] = temp->name;
d6d4e4c3 210 matching_vector[match_count + 1] = NULL;
aabda2da 211 }
d6d4e4c3 212 match_count++;
6724ff46
RP
213 /* If this is the default target, accept it, even if other targets
214 might match. People who want those other targets have to set
215 the GNUTARGET variable. */
f4bd7a8f 216 if (temp == bfd_default_vector[0])
c188b0be 217 {
aabda2da
DM
218 if (matching)
219 {
220 matching_vector[0] = temp->name;
221 matching_vector[1] = NULL;
222 }
d6d4e4c3 223 match_count = 1;
c188b0be
DM
224 break;
225 }
6724ff46
RP
226#ifdef GNU960
227 /* Big- and little-endian b.out archives look the same, but it doesn't
228 * matter: there is no difference in their headers, and member file byte
229 * orders will (I hope) be handled appropriately by bfd. Ditto for big
230 * and little coff archives. And the 4 coff/b.out object formats are
231 * unambiguous. So accept the first match we find.
232 */
233 break;
234#endif
6efd50e3 235 } else if (bfd_get_error () != bfd_error_wrong_format) {
c188b0be
DM
236 abfd->xvec = save_targ;
237 abfd->format = bfd_unknown;
6efd50e3 238 if (matching && bfd_get_error () != bfd_error_file_ambiguously_recognized)
aabda2da 239 free (matching_vector);
c188b0be 240 return false;
6724ff46
RP
241 }
242 }
243
244 if (match_count == 1) {
245 abfd->xvec = right_targ; /* Change BFD's target permanently */
aabda2da
DM
246 if (matching)
247 free (matching_vector);
6724ff46
RP
248 return true; /* File position has moved, BTW */
249 }
250
251 abfd->xvec = save_targ; /* Restore original target type */
252 abfd->format = bfd_unknown; /* Restore original format */
aabda2da
DM
253 if (match_count == 0)
254 {
6efd50e3 255 bfd_set_error (bfd_error_file_not_recognized);
aabda2da
DM
256 if (matching)
257 free (matching_vector);
258 }
259 else
6efd50e3 260 bfd_set_error (bfd_error_file_ambiguously_recognized);
6724ff46
RP
261 return false;
262}
c188b0be 263
c188b0be
DM
264/*
265FUNCTION
266 bfd_set_format
267
268SYNOPSIS
269 boolean bfd_set_format(bfd *abfd, bfd_format format);
270
271DESCRIPTION
272 This function sets the file format of the BFD @var{abfd} to the
273 format @var{format}. If the target set in the BFD does not
274 support the format requested, the format is invalid, or the BFD
275 is not open for writing, then an error occurs.
276
277*/
278
6724ff46 279boolean
aabda2da
DM
280bfd_set_format (abfd, format)
281 bfd *abfd;
282 bfd_format format;
6724ff46
RP
283{
284
285 if (bfd_read_p (abfd) ||
286 ((int)abfd->format < (int)bfd_unknown) ||
287 ((int)abfd->format >= (int)bfd_type_end)) {
6efd50e3 288 bfd_set_error (bfd_error_invalid_operation);
6724ff46
RP
289 return false;
290 }
291
292 if (abfd->format != bfd_unknown)
293 return (abfd->format == format) ? true:false;
294
295 /* presume the answer is yes */
296 abfd->format = format;
297
298 if (!BFD_SEND_FMT (abfd, _bfd_set_format, (abfd))) {
299 abfd->format = bfd_unknown;
300 return false;
301 }
302
303 return true;
304}
305
306
c188b0be
DM
307/*
308FUNCTION
309 bfd_format_string
310
311SYNOPSIS
312 CONST char *bfd_format_string(bfd_format format);
313
314DESCRIPTION
315 Return a pointer to a const string
316 <<invalid>>, <<object>>, <<archive>>, <<core>>, or <<unknown>>,
317 depending upon the value of @var{format}.
318*/
6724ff46
RP
319
320CONST char *
aabda2da
DM
321bfd_format_string (format)
322 bfd_format format;
6724ff46
RP
323{
324 if (((int)format <(int) bfd_unknown)
325 || ((int)format >=(int) bfd_type_end))
326 return "invalid";
327
328 switch (format) {
329 case bfd_object:
330 return "object"; /* linker/assember/compiler output */
331 case bfd_archive:
332 return "archive"; /* object archive file */
333 case bfd_core:
334 return "core"; /* core dump */
335 default:
336 return "unknown";
337 }
338}
This page took 0.261553 seconds and 4 git commands to generate.