format.c revision 78828
1/* Generic BFD support for file formats.
2   Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1999, 2000, 2001
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;
123  char **matching_vector = NULL;
124  int match_count;
125
126  if (!bfd_read_p (abfd) ||
127      ((int)(abfd->format) < (int)bfd_unknown) ||
128      ((int)(abfd->format) >= (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 (abfd->format == format)? true: false;
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
142  if (matching)
143    {
144      matching_vector =
145	(char **) bfd_malloc (sizeof (char *) *
146			      (_bfd_target_vector_entries + 1));
147      if (!matching_vector)
148	return false;
149      matching_vector[0] = NULL;
150      *matching = matching_vector;
151    }
152
153  right_targ = 0;
154
155  /* Presume the answer is yes.  */
156  abfd->format = format;
157
158  /* If the target type was explicitly specified, just check that target.  */
159  if (!abfd->target_defaulted)
160    {
161      if (bfd_seek (abfd, (file_ptr)0, SEEK_SET) != 0)	/* rewind! */
162	return false;
163
164      right_targ = BFD_SEND_FMT (abfd, _bfd_check_format, (abfd));
165
166      if (right_targ)
167	{
168	  abfd->xvec = right_targ;	/* Set the target as returned.  */
169
170	  if (matching)
171	    free (matching_vector);
172
173	  return true;			/* File position has moved, BTW.  */
174	}
175
176      /* For a long time the code has dropped through to check all
177	 targets if the specified target was wrong.  I don't know why,
178	 and I'm reluctant to change it.  However, in the case of an
179	 archive, it can cause problems.  If the specified target does
180	 not permit archives (e.g., the binary target), then we should
181	 not allow some other target to recognize it as an archive, but
182	 should instead allow the specified target to recognize it as an
183	 object.  When I first made this change, it broke the PE target,
184	 because the specified pei-i386 target did not recognize the
185	 actual pe-i386 archive.  Since there may be other problems of
186	 this sort, I changed this test to check only for the binary
187	 target.  */
188      if (format == bfd_archive && save_targ == &binary_vec)
189	{
190	  abfd->xvec = save_targ;
191	  abfd->format = bfd_unknown;
192
193	  if (matching)
194	    free (matching_vector);
195
196	  bfd_set_error (bfd_error_file_not_recognized);
197
198	  return false;
199	}
200    }
201
202  for (target = bfd_target_vector; *target != NULL; target++)
203    {
204      const bfd_target *temp;
205
206      if (*target == &binary_vec)
207	continue;
208
209      abfd->xvec = *target;	/* Change BFD's target temporarily */
210
211      if (bfd_seek (abfd, (file_ptr)0, SEEK_SET) != 0)
212	return false;
213
214      /* If _bfd_check_format neglects to set bfd_error, assume
215	 bfd_error_wrong_format.  We didn't used to even pay any
216	 attention to bfd_error, so I suspect that some
217	 _bfd_check_format might have this problem.  */
218      bfd_set_error (bfd_error_wrong_format);
219
220      temp = BFD_SEND_FMT (abfd, _bfd_check_format, (abfd));
221
222      if (temp)
223	{		/* This format checks out as ok!  */
224	  right_targ = temp;
225
226	  if (matching)
227	    {
228	      matching_vector[match_count] = temp->name;
229	      matching_vector[match_count + 1] = NULL;
230	    }
231
232	  match_count++;
233
234	  /* If this is the default target, accept it, even if other
235	     targets might match.  People who want those other targets
236	     have to set the GNUTARGET variable.  */
237	  if (temp == bfd_default_vector[0])
238	    {
239	      if (matching)
240		{
241		  matching_vector[0] = temp->name;
242		  matching_vector[1] = NULL;
243		}
244	      match_count = 1;
245	      break;
246	    }
247#ifdef GNU960
248	  /* Big- and little-endian b.out archives look the same, but it
249	     doesn't matter: there is no difference in their headers, and
250	     member file byte orders will (I hope) be handled appropriately
251	     by bfd.  Ditto for big and little coff archives.  And the 4
252	     coff/b.out object formats are unambiguous.  So accept the
253	     first match we find.  */
254	  break;
255#endif
256	}
257      else if (bfd_get_error () != bfd_error_wrong_format)
258	{
259	  abfd->xvec = save_targ;
260	  abfd->format = bfd_unknown;
261
262	  if (matching && bfd_get_error ()
263	      != bfd_error_file_ambiguously_recognized)
264	    free (matching_vector);
265
266	  return false;
267	}
268    }
269
270  if (match_count == 1)
271    {
272      abfd->xvec = right_targ;		/* Change BFD's target permanently.  */
273
274      if (matching)
275	free (matching_vector);
276
277      return true;			/* File position has moved, BTW.  */
278    }
279
280  abfd->xvec = save_targ;		/* Restore original target type.  */
281  abfd->format = bfd_unknown;		/* Restore original format.  */
282
283  if (match_count == 0)
284    {
285      bfd_set_error (bfd_error_file_not_recognized);
286
287      if (matching)
288	free (matching_vector);
289    }
290  else
291    bfd_set_error (bfd_error_file_ambiguously_recognized);
292
293  return false;
294}
295
296/*
297FUNCTION
298	bfd_set_format
299
300SYNOPSIS
301	boolean bfd_set_format(bfd *abfd, bfd_format format);
302
303DESCRIPTION
304	This function sets the file format of the BFD @var{abfd} to the
305	format @var{format}. If the target set in the BFD does not
306	support the format requested, the format is invalid, or the BFD
307	is not open for writing, then an error occurs.
308*/
309
310boolean
311bfd_set_format (abfd, format)
312     bfd *abfd;
313     bfd_format format;
314{
315  if (bfd_read_p (abfd) ||
316      ((int)abfd->format < (int)bfd_unknown) ||
317      ((int)abfd->format >= (int)bfd_type_end))
318    {
319      bfd_set_error (bfd_error_invalid_operation);
320      return false;
321    }
322
323  if (abfd->format != bfd_unknown)
324    return (abfd->format == format) ? true : false;
325
326  /* Presume the answer is yes.  */
327  abfd->format = format;
328
329  if (!BFD_SEND_FMT (abfd, _bfd_set_format, (abfd)))
330    {
331      abfd->format = bfd_unknown;
332      return false;
333    }
334
335  return true;
336}
337
338/*
339FUNCTION
340	bfd_format_string
341
342SYNOPSIS
343	CONST char *bfd_format_string(bfd_format format);
344
345DESCRIPTION
346	Return a pointer to a const string
347	<<invalid>>, <<object>>, <<archive>>, <<core>>, or <<unknown>>,
348	depending upon the value of @var{format}.
349*/
350
351CONST char *
352bfd_format_string (format)
353     bfd_format format;
354{
355  if (((int)format <(int) bfd_unknown)
356      || ((int)format >=(int) bfd_type_end))
357    return "invalid";
358
359  switch (format)
360    {
361    case bfd_object:
362      return "object";		/* Linker/assember/compiler output.  */
363    case bfd_archive:
364      return "archive";		/* Object archive file.  */
365    case bfd_core:
366      return "core";		/* Core dump.  */
367    default:
368      return "unknown";
369    }
370}
371