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