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