format.c revision 77298
1/* Generic BFD support for file formats.
2   Copyright (C) 1990, 91, 92, 93, 94, 95, 1999 Free Software Foundation, Inc.
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
19Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
20
21/*
22SECTION
23	File formats
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*/
41
42#include "bfd.h"
43#include "sysdep.h"
44#include "libbfd.h"
45
46/* IMPORT from targets.c.  */
47extern const size_t _bfd_target_vector_entries;
48
49/*
50FUNCTION
51	bfd_check_format
52
53SYNOPSIS
54	boolean bfd_check_format(bfd *abfd, bfd_format format);
55
56DESCRIPTION
57	Verify if the file attached to the BFD @var{abfd} is compatible
58	with the format @var{format} (i.e., one of <<bfd_object>>,
59	<<bfd_archive>> or <<bfd_core>>).
60
61	If the BFD has been set to a specific target before the
62	call, only the named target and format combination is
63	checked. If the target has not been set, or has been set to
64	<<default>>, then all the known target backends is
65	interrogated to determine a match.  If the default target
66	matches, it is used.  If not, exactly one target must recognize
67	the file, or an error results.
68
69	The function returns <<true>> on success, otherwise <<false>>
70	with one of the following error codes:
71
72	o <<bfd_error_invalid_operation>> -
73	if <<format>> is not one of <<bfd_object>>, <<bfd_archive>> or
74	<<bfd_core>>.
75
76	o <<bfd_error_system_call>> -
77	if an error occured during a read - even some file mismatches
78	can cause bfd_error_system_calls.
79
80	o <<file_not_recognised>> -
81	none of the backends recognised the file format.
82
83	o <<bfd_error_file_ambiguously_recognized>> -
84	more than one backend recognised the file format.
85*/
86
87boolean
88bfd_check_format (abfd, format)
89     bfd *abfd;
90     bfd_format format;
91{
92  return bfd_check_format_matches (abfd, format, NULL);
93}
94
95/*
96FUNCTION
97	bfd_check_format_matches
98
99SYNOPSIS
100	boolean bfd_check_format_matches(bfd *abfd, bfd_format format, char ***matching);
101
102DESCRIPTION
103	Like <<bfd_check_format>>, except when it returns false with
104	<<bfd_errno>> set to <<bfd_error_file_ambiguously_recognized>>.  In that
105	case, if @var{matching} is not NULL, it will be filled in with
106	a NULL-terminated list of the names of the formats that matched,
107	allocated with <<malloc>>.
108	Then the user may choose a format and try again.
109
110	When done with the list that @var{matching} points to, the caller
111	should free it.
112*/
113
114boolean
115bfd_check_format_matches (abfd, format, matching)
116     bfd *abfd;
117     bfd_format format;
118     char ***matching;
119{
120  extern const bfd_target binary_vec;
121  const bfd_target * const *target, *save_targ, *right_targ;
122  char **matching_vector = NULL;
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))
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)? true: false;
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
141  if (matching)
142    {
143      matching_vector =
144	(char **) bfd_malloc (sizeof (char *) *
145			      (_bfd_target_vector_entries + 1));
146      if (!matching_vector)
147	return false;
148      matching_vector[0] = NULL;
149      *matching = matching_vector;
150    }
151
152  right_targ = 0;
153
154  /* Presume the answer is yes.  */
155  abfd->format = format;
156
157  /* If the target type was explicitly specified, just check that target.  */
158  if (!abfd->target_defaulted)
159    {
160      if (bfd_seek (abfd, (file_ptr)0, SEEK_SET) != 0)	/* rewind! */
161	return false;
162
163      right_targ = BFD_SEND_FMT (abfd, _bfd_check_format, (abfd));
164
165      if (right_targ)
166	{
167	  abfd->xvec = right_targ;	/* Set the target as returned.  */
168
169	  if (matching)
170	    free (matching_vector);
171
172	  return true;			/* File position has moved, BTW.  */
173	}
174
175      /* For a long time the code has dropped through to check all
176	 targets if the specified target was wrong.  I don't know why,
177	 and I'm reluctant to change it.  However, in the case of an
178	 archive, it can cause problems.  If the specified target does
179	 not permit archives (e.g., the binary target), then we should
180	 not allow some other target to recognize it as an archive, but
181	 should instead allow the specified target to recognize it as an
182	 object.  When I first made this change, it broke the PE target,
183	 because the specified pei-i386 target did not recognize the
184	 actual pe-i386 archive.  Since there may be other problems of
185	 this sort, I changed this test to check only for the binary
186	 target.  */
187      if (format == bfd_archive && save_targ == &binary_vec)
188	{
189	  abfd->xvec = save_targ;
190	  abfd->format = bfd_unknown;
191
192	  if (matching)
193	    free (matching_vector);
194
195	  bfd_set_error (bfd_error_file_not_recognized);
196
197	  return false;
198	}
199    }
200
201  for (target = bfd_target_vector; *target != NULL; target++)
202    {
203      const bfd_target *temp;
204
205      if (*target == &binary_vec)
206	continue;
207
208      abfd->xvec = *target;	/* Change BFD's target temporarily */
209
210      if (bfd_seek (abfd, (file_ptr)0, SEEK_SET) != 0)
211	return false;
212
213      /* If _bfd_check_format neglects to set bfd_error, assume
214	 bfd_error_wrong_format.  We didn't used to even pay any
215	 attention to bfd_error, so I suspect that some
216	 _bfd_check_format might have this problem.  */
217      bfd_set_error (bfd_error_wrong_format);
218
219      temp = BFD_SEND_FMT (abfd, _bfd_check_format, (abfd));
220
221      if (temp)
222	{		/* This format checks out as ok!  */
223	  right_targ = temp;
224
225	  if (matching)
226	    {
227	      matching_vector[match_count] = temp->name;
228	      matching_vector[match_count + 1] = NULL;
229	    }
230
231	  match_count++;
232
233	  /* If this is the default target, accept it, even if other
234	     targets might match.  People who want those other targets
235	     have to set the GNUTARGET variable.  */
236	  if (temp == bfd_default_vector[0])
237	    {
238	      if (matching)
239		{
240		  matching_vector[0] = temp->name;
241		  matching_vector[1] = NULL;
242		}
243	      match_count = 1;
244	      break;
245	    }
246#ifdef GNU960
247	  /* Big- and little-endian b.out archives look the same, but it
248	     doesn't matter: there is no difference in their headers, and
249	     member file byte orders will (I hope) be handled appropriately
250	     by bfd.  Ditto for big and little coff archives.  And the 4
251	     coff/b.out object formats are unambiguous.  So accept the
252	     first match we find.  */
253	  break;
254#endif
255	}
256      else if (bfd_get_error () != bfd_error_wrong_format)
257	{
258	  abfd->xvec = save_targ;
259	  abfd->format = bfd_unknown;
260
261	  if (matching && bfd_get_error ()
262	      != bfd_error_file_ambiguously_recognized)
263	    free (matching_vector);
264
265	  return false;
266	}
267    }
268
269  if (match_count == 1)
270    {
271      abfd->xvec = right_targ;		/* Change BFD's target permanently.  */
272
273      if (matching)
274	free (matching_vector);
275
276      return true;			/* File position has moved, BTW.  */
277    }
278
279  abfd->xvec = save_targ;		/* Restore original target type.  */
280  abfd->format = bfd_unknown;		/* Restore original format.  */
281
282  if (match_count == 0)
283    {
284      bfd_set_error (bfd_error_file_not_recognized);
285
286      if (matching)
287	free (matching_vector);
288    }
289  else
290    bfd_set_error (bfd_error_file_ambiguously_recognized);
291
292  return false;
293}
294
295/*
296FUNCTION
297	bfd_set_format
298
299SYNOPSIS
300	boolean bfd_set_format(bfd *abfd, bfd_format format);
301
302DESCRIPTION
303	This function sets the file format of the BFD @var{abfd} to the
304	format @var{format}. If the target set in the BFD does not
305	support the format requested, the format is invalid, or the BFD
306	is not open for writing, then an error occurs.
307*/
308
309boolean
310bfd_set_format (abfd, format)
311     bfd *abfd;
312     bfd_format format;
313{
314  if (bfd_read_p (abfd) ||
315      ((int)abfd->format < (int)bfd_unknown) ||
316      ((int)abfd->format >= (int)bfd_type_end))
317    {
318      bfd_set_error (bfd_error_invalid_operation);
319      return false;
320    }
321
322  if (abfd->format != bfd_unknown)
323    return (abfd->format == format) ? true : false;
324
325  /* Presume the answer is yes.  */
326  abfd->format = format;
327
328  if (!BFD_SEND_FMT (abfd, _bfd_set_format, (abfd)))
329    {
330      abfd->format = bfd_unknown;
331      return false;
332    }
333
334  return true;
335}
336
337/*
338FUNCTION
339	bfd_format_string
340
341SYNOPSIS
342	CONST char *bfd_format_string(bfd_format format);
343
344DESCRIPTION
345	Return a pointer to a const string
346	<<invalid>>, <<object>>, <<archive>>, <<core>>, or <<unknown>>,
347	depending upon the value of @var{format}.
348*/
349
350CONST char *
351bfd_format_string (format)
352     bfd_format format;
353{
354  if (((int)format <(int) bfd_unknown)
355      || ((int)format >=(int) bfd_type_end))
356    return "invalid";
357
358  switch (format)
359    {
360    case bfd_object:
361      return "object";		/* Linker/assember/compiler output.  */
362    case bfd_archive:
363      return "archive";		/* Object archive file.  */
364    case bfd_core:
365      return "core";		/* Core dump.  */
366    default:
367      return "unknown";
368    }
369}
370