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