format.c revision 107492
1/* Generic BFD support for file formats.
2   Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1999, 2000, 2001, 2002
3   Free Software Foundation, Inc.
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
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*/
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>>
71	with one of the following error codes:
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
112	should free it.
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;
122  const bfd_target * const *target, *save_targ, *right_targ, *ar_right_targ;
123  char **matching_vector = NULL;
124  int match_count;
125  int ar_match_index;
126
127  if (!bfd_read_p (abfd)
128      || (unsigned int) abfd->format >= (unsigned int) bfd_type_end)
129    {
130      bfd_set_error (bfd_error_invalid_operation);
131      return false;
132    }
133
134  if (abfd->format != bfd_unknown)
135    return (boolean) (abfd->format == format);
136
137  /* Since the target type was defaulted, check them
138     all in the hope that one will be uniquely recognized.  */
139  save_targ = abfd->xvec;
140  match_count = 0;
141  ar_match_index = _bfd_target_vector_entries;
142
143  if (matching)
144    {
145      bfd_size_type amt;
146
147      *matching = NULL;
148      amt = sizeof (char *) * 2 * _bfd_target_vector_entries;
149      matching_vector = (char **) bfd_malloc (amt);
150      if (!matching_vector)
151	return false;
152    }
153
154  right_targ = 0;
155  ar_right_targ = 0;
156
157  /* Presume the answer is yes.  */
158  abfd->format = format;
159
160  /* If the target type was explicitly specified, just check that target.  */
161  if (!abfd->target_defaulted)
162    {
163      if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)	/* rewind! */
164	return false;
165
166      right_targ = BFD_SEND_FMT (abfd, _bfd_check_format, (abfd));
167
168      if (right_targ)
169	{
170	  abfd->xvec = right_targ;	/* Set the target as returned.  */
171
172	  if (matching)
173	    free (matching_vector);
174
175	  return true;			/* File position has moved, BTW.  */
176	}
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)
191	{
192	  abfd->xvec = save_targ;
193	  abfd->format = bfd_unknown;
194
195	  if (matching)
196	    free (matching_vector);
197
198	  bfd_set_error (bfd_error_file_not_recognized);
199
200	  return false;
201	}
202    }
203
204  for (target = bfd_target_vector; *target != NULL; target++)
205    {
206      const bfd_target *temp;
207      bfd_error_type err;
208
209      if (*target == &binary_vec)
210	continue;
211
212      abfd->xvec = *target;	/* Change BFD's target temporarily */
213
214      if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
215	return false;
216
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));
224
225      if (temp)
226	{		/* This format checks out as ok!  */
227	  right_targ = temp;
228
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	    {
234	      match_count = 1;
235	      break;
236	    }
237
238	  if (matching)
239	    matching_vector[match_count] = temp->name;
240
241	  match_count++;
242
243#ifdef GNU960
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;
251#endif
252	}
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)
266	{
267	  abfd->xvec = save_targ;
268	  abfd->format = bfd_unknown;
269
270	  if (matching)
271	    free (matching_vector);
272
273	  return false;
274	}
275    }
276
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
297  if (match_count == 1)
298    {
299      abfd->xvec = right_targ;		/* Change BFD's target permanently.  */
300
301      if (matching)
302	free (matching_vector);
303
304      return true;			/* File position has moved, BTW.  */
305    }
306
307  abfd->xvec = save_targ;		/* Restore original target type.  */
308  abfd->format = bfd_unknown;		/* Restore original format.  */
309
310  if (match_count == 0)
311    {
312      bfd_set_error (bfd_error_file_not_recognized);
313
314      if (matching)
315	free (matching_vector);
316    }
317  else
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    }
327
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.
343*/
344
345boolean
346bfd_set_format (abfd, format)
347     bfd *abfd;
348     bfd_format format;
349{
350  if (bfd_read_p (abfd)
351      || (unsigned int) abfd->format >= (unsigned int) bfd_type_end)
352    {
353      bfd_set_error (bfd_error_invalid_operation);
354      return false;
355    }
356
357  if (abfd->format != bfd_unknown)
358    return (boolean) (abfd->format == format);
359
360  /* Presume the answer is yes.  */
361  abfd->format = format;
362
363  if (!BFD_SEND_FMT (abfd, _bfd_set_format, (abfd)))
364    {
365      abfd->format = bfd_unknown;
366      return false;
367    }
368
369  return true;
370}
371
372/*
373FUNCTION
374	bfd_format_string
375
376SYNOPSIS
377	const char *bfd_format_string(bfd_format format);
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
385const char *
386bfd_format_string (format)
387     bfd_format format;
388{
389  if (((int)format <(int) bfd_unknown)
390      || ((int)format >=(int) bfd_type_end))
391    return "invalid";
392
393  switch (format)
394    {
395    case bfd_object:
396      return "object";		/* Linker/assember/compiler output.  */
397    case bfd_archive:
398      return "archive";		/* Object archive file.  */
399    case bfd_core:
400      return "core";		/* Core dump.  */
401    default:
402      return "unknown";
403    }
404}
405