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