xref: /netbsd-src/external/gpl3/binutils/dist/bfd/format.c (revision cb63e24e8d6aae7ddac1859a9015f48b1d8bd90e)
1 /* Generic BFD support for file formats.
2    Copyright (C) 1990-2024 Free Software Foundation, Inc.
3    Written by Cygnus Support.
4 
5    This file is part of BFD, the Binary File Descriptor library.
6 
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3 of the License, or
10    (at your option) any later version.
11 
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16 
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
20    MA 02110-1301, USA.  */
21 
22 
23 /*
24 SECTION
25 	File formats
26 
27 	A format is a BFD concept of high level file contents type. The
28 	formats supported by BFD are:
29 
30 	o <<bfd_object>>
31 
32 	The BFD may contain data, symbols, relocations and debug info.
33 
34 	o <<bfd_archive>>
35 
36 	The BFD contains other BFDs and an optional index.
37 
38 	o <<bfd_core>>
39 
40 	The BFD contains the result of an executable core dump.
41 
42 SUBSECTION
43 	File format functions
44 */
45 
46 #include "sysdep.h"
47 #include "bfd.h"
48 #include "libbfd.h"
49 
50 /* IMPORT from targets.c.  */
51 extern const size_t _bfd_target_vector_entries;
52 
53 /*
54 FUNCTION
55 	bfd_check_format
56 
57 SYNOPSIS
58 	bool bfd_check_format (bfd *abfd, bfd_format format);
59 
60 DESCRIPTION
61 	Verify if the file attached to the BFD @var{abfd} is compatible
62 	with the format @var{format} (i.e., one of <<bfd_object>>,
63 	<<bfd_archive>> or <<bfd_core>>).
64 
65 	If the BFD has been set to a specific target before the
66 	call, only the named target and format combination is
67 	checked. If the target has not been set, or has been set to
68 	<<default>>, then all the known target backends is
69 	interrogated to determine a match.  If the default target
70 	matches, it is used.  If not, exactly one target must recognize
71 	the file, or an error results.
72 
73 	The function returns <<TRUE>> on success, otherwise <<FALSE>>
74 	with one of the following error codes:
75 
76 	o <<bfd_error_invalid_operation>> -
77 	if <<format>> is not one of <<bfd_object>>, <<bfd_archive>> or
78 	<<bfd_core>>.
79 
80 	o <<bfd_error_system_call>> -
81 	if an error occured during a read - even some file mismatches
82 	can cause bfd_error_system_calls.
83 
84 	o <<file_not_recognised>> -
85 	none of the backends recognised the file format.
86 
87 	o <<bfd_error_file_ambiguously_recognized>> -
88 	more than one backend recognised the file format.
89 */
90 
91 bool
bfd_check_format(bfd * abfd,bfd_format format)92 bfd_check_format (bfd *abfd, bfd_format format)
93 {
94   return bfd_check_format_matches (abfd, format, NULL);
95 }
96 
97 struct bfd_preserve
98 {
99   void *marker;
100   void *tdata;
101   flagword flags;
102   const struct bfd_iovec *iovec;
103   void *iostream;
104   const struct bfd_arch_info *arch_info;
105   const struct bfd_build_id *build_id;
106   bfd_cleanup cleanup;
107   struct bfd_section *sections;
108   struct bfd_section *section_last;
109   unsigned int section_count;
110   unsigned int section_id;
111   unsigned int symcount;
112   bool read_only;
113   bfd_vma start_address;
114   struct bfd_hash_table section_htab;
115 };
116 
117 /* When testing an object for compatibility with a particular target
118    back-end, the back-end object_p function needs to set up certain
119    fields in the bfd on successfully recognizing the object.  This
120    typically happens in a piecemeal fashion, with failures possible at
121    many points.  On failure, the bfd is supposed to be restored to its
122    initial state, which is virtually impossible.  However, restoring a
123    subset of the bfd state works in practice.  This function stores
124    the subset.  */
125 
126 static bool
bfd_preserve_save(bfd * abfd,struct bfd_preserve * preserve,bfd_cleanup cleanup)127 bfd_preserve_save (bfd *abfd, struct bfd_preserve *preserve,
128 		   bfd_cleanup cleanup)
129 {
130   preserve->tdata = abfd->tdata.any;
131   preserve->arch_info = abfd->arch_info;
132   preserve->flags = abfd->flags;
133   preserve->iovec = abfd->iovec;
134   preserve->iostream = abfd->iostream;
135   preserve->sections = abfd->sections;
136   preserve->section_last = abfd->section_last;
137   preserve->section_count = abfd->section_count;
138   preserve->section_id = _bfd_section_id;
139   preserve->symcount = abfd->symcount;
140   preserve->read_only = abfd->read_only;
141   preserve->start_address = abfd->start_address;
142   preserve->section_htab = abfd->section_htab;
143   preserve->marker = bfd_alloc (abfd, 1);
144   preserve->build_id = abfd->build_id;
145   preserve->cleanup = cleanup;
146   if (preserve->marker == NULL)
147     return false;
148 
149   return bfd_hash_table_init (&abfd->section_htab, bfd_section_hash_newfunc,
150 			      sizeof (struct section_hash_entry));
151 }
152 
153 /* A back-end object_p function may flip a bfd from file backed to
154    in-memory, eg. pe_ILF_object_p.  In that case to restore the
155    original IO state we need to reopen the file.  Conversely, if we
156    are restoring a previously matched pe ILF format and have been
157    checking further target matches using file IO then we need to close
158    the file and detach the bfd from the cache lru list.  */
159 
160 static void
io_reinit(bfd * abfd,struct bfd_preserve * preserve)161 io_reinit (bfd *abfd, struct bfd_preserve *preserve)
162 {
163   if (abfd->iovec != preserve->iovec)
164     {
165       /* Handle file backed to in-memory transition.  bfd_cache_close
166 	 won't do anything unless abfd->iovec is the cache_iovec.
167 	 Don't be tempted to call iovec->bclose here.  We don't want
168 	 to call memory_bclose, which would free the bim.  The bim
169 	 must be kept if bfd_check_format_matches is going to decide
170 	 later that the PE format needing it is in fact the correct
171 	 target match.  */
172       bfd_cache_close (abfd);
173       abfd->iovec = preserve->iovec;
174       abfd->iostream = preserve->iostream;
175 
176       /* Handle in-memory to file backed transition.  */
177       if ((abfd->flags & BFD_CLOSED_BY_CACHE) != 0
178 	  && (abfd->flags & BFD_IN_MEMORY) != 0
179 	  && (preserve->flags & BFD_CLOSED_BY_CACHE) == 0
180 	  && (preserve->flags & BFD_IN_MEMORY) == 0)
181 	bfd_open_file (abfd);
182     }
183   abfd->flags = preserve->flags;
184 }
185 
186 /* Clear out a subset of BFD state.  */
187 
188 static void
bfd_reinit(bfd * abfd,unsigned int section_id,struct bfd_preserve * preserve,bfd_cleanup cleanup)189 bfd_reinit (bfd *abfd, unsigned int section_id,
190 	    struct bfd_preserve *preserve, bfd_cleanup cleanup)
191 {
192   _bfd_section_id = section_id;
193   if (cleanup)
194     cleanup (abfd);
195   abfd->tdata.any = NULL;
196   abfd->arch_info = &bfd_default_arch_struct;
197   io_reinit (abfd, preserve);
198   abfd->symcount = 0;
199   abfd->read_only = 0;
200   abfd->start_address = 0;
201   abfd->build_id = NULL;
202   bfd_section_list_clear (abfd);
203 }
204 
205 /* Restores bfd state saved by bfd_preserve_save.  */
206 
207 static bfd_cleanup
bfd_preserve_restore(bfd * abfd,struct bfd_preserve * preserve)208 bfd_preserve_restore (bfd *abfd, struct bfd_preserve *preserve)
209 {
210   bfd_hash_table_free (&abfd->section_htab);
211 
212   abfd->tdata.any = preserve->tdata;
213   abfd->arch_info = preserve->arch_info;
214   io_reinit (abfd, preserve);
215   abfd->section_htab = preserve->section_htab;
216   abfd->sections = preserve->sections;
217   abfd->section_last = preserve->section_last;
218   abfd->section_count = preserve->section_count;
219   _bfd_section_id = preserve->section_id;
220   abfd->symcount = preserve->symcount;
221   abfd->read_only = preserve->read_only;
222   abfd->start_address = preserve->start_address;
223   abfd->build_id = preserve->build_id;
224 
225   /* bfd_release frees all memory more recently bfd_alloc'd than
226      its arg, as well as its arg.  */
227   bfd_release (abfd, preserve->marker);
228   preserve->marker = NULL;
229   return preserve->cleanup;
230 }
231 
232 /* Called when the bfd state saved by bfd_preserve_save is no longer
233    needed.  */
234 
235 static void
bfd_preserve_finish(bfd * abfd ATTRIBUTE_UNUSED,struct bfd_preserve * preserve)236 bfd_preserve_finish (bfd *abfd ATTRIBUTE_UNUSED, struct bfd_preserve *preserve)
237 {
238   if (preserve->cleanup)
239     {
240       /* Run the cleanup, assuming that all it will need is the
241 	 tdata at the time the cleanup was returned.  */
242       void *tdata = abfd->tdata.any;
243       abfd->tdata.any = preserve->tdata;
244       preserve->cleanup (abfd);
245       abfd->tdata.any = tdata;
246     }
247   /* It would be nice to be able to free more memory here, eg. old
248      tdata, but that's not possible since these blocks are sitting
249      inside bfd_alloc'd memory.  The section hash is on a separate
250      objalloc.  */
251   bfd_hash_table_free (&preserve->section_htab);
252   preserve->marker = NULL;
253 }
254 
255 static void
print_warnmsg(struct per_xvec_message ** list)256 print_warnmsg (struct per_xvec_message **list)
257 {
258   fflush (stdout);
259   fprintf (stderr, "%s: ", _bfd_get_error_program_name ());
260 
261   for (struct per_xvec_message *warn = *list; warn; warn = warn->next)
262     {
263       fputs (warn->message, stderr);
264       fputc ('\n', stderr);
265     }
266   fflush (stderr);
267 }
268 
269 static void
clear_warnmsg(struct per_xvec_message ** list)270 clear_warnmsg (struct per_xvec_message **list)
271 {
272   struct per_xvec_message *warn = *list;
273   while (warn)
274     {
275       struct per_xvec_message *next = warn->next;
276       free (warn);
277       warn = next;
278     }
279   *list = NULL;
280 }
281 
282 static void
null_error_handler(const char * fmt ATTRIBUTE_UNUSED,va_list ap ATTRIBUTE_UNUSED)283 null_error_handler (const char *fmt ATTRIBUTE_UNUSED,
284 		    va_list ap ATTRIBUTE_UNUSED)
285 {
286 }
287 
288 /*
289 FUNCTION
290 	bfd_check_format_matches
291 
292 SYNOPSIS
293 	bool bfd_check_format_matches
294 	  (bfd *abfd, bfd_format format, char ***matching);
295 
296 DESCRIPTION
297 	Like <<bfd_check_format>>, except when it returns FALSE with
298 	<<bfd_errno>> set to <<bfd_error_file_ambiguously_recognized>>.  In that
299 	case, if @var{matching} is not NULL, it will be filled in with
300 	a NULL-terminated list of the names of the formats that matched,
301 	allocated with <<malloc>>.
302 	Then the user may choose a format and try again.
303 
304 	When done with the list that @var{matching} points to, the caller
305 	should free it.
306 */
307 
308 bool
bfd_check_format_matches(bfd * abfd,bfd_format format,char *** matching)309 bfd_check_format_matches (bfd *abfd, bfd_format format, char ***matching)
310 {
311   extern const bfd_target binary_vec;
312 #if BFD_SUPPORTS_PLUGINS
313   extern const bfd_target plugin_vec;
314 #endif
315   const bfd_target * const *target;
316   const bfd_target **matching_vector = NULL;
317   const bfd_target *save_targ, *right_targ, *ar_right_targ, *match_targ;
318   int match_count, best_count, best_match;
319   int ar_match_index;
320   unsigned int initial_section_id = _bfd_section_id;
321   struct bfd_preserve preserve, preserve_match;
322   bfd_cleanup cleanup = NULL;
323   bfd_error_handler_type orig_error_handler;
324   static int in_check_format;
325 
326   if (matching != NULL)
327     *matching = NULL;
328 
329   if (!bfd_read_p (abfd)
330       || (unsigned int) abfd->format >= (unsigned int) bfd_type_end)
331     {
332       bfd_set_error (bfd_error_invalid_operation);
333       return false;
334     }
335 
336   if (abfd->format != bfd_unknown)
337     return abfd->format == format;
338 
339   if (matching != NULL || *bfd_associated_vector != NULL)
340     {
341       size_t amt;
342 
343       amt = sizeof (*matching_vector) * 2 * _bfd_target_vector_entries;
344       matching_vector = (const bfd_target **) bfd_malloc (amt);
345       if (!matching_vector)
346 	return false;
347     }
348 
349   /* Presume the answer is yes.  */
350   abfd->format = format;
351   save_targ = abfd->xvec;
352 
353   /* Don't report errors on recursive calls checking the first element
354      of an archive.  */
355   if (in_check_format)
356     orig_error_handler = bfd_set_error_handler (null_error_handler);
357   else
358     orig_error_handler = _bfd_set_error_handler_caching (abfd);
359   ++in_check_format;
360 
361   preserve_match.marker = NULL;
362   if (!bfd_preserve_save (abfd, &preserve, NULL))
363     goto err_ret;
364 
365   /* If the target type was explicitly specified, just check that target.  */
366   if (!abfd->target_defaulted)
367     {
368       if (bfd_seek (abfd, 0, SEEK_SET) != 0)	/* rewind! */
369 	goto err_ret;
370 
371       cleanup = BFD_SEND_FMT (abfd, _bfd_check_format, (abfd));
372 
373       if (cleanup)
374 	goto ok_ret;
375 
376       /* For a long time the code has dropped through to check all
377 	 targets if the specified target was wrong.  I don't know why,
378 	 and I'm reluctant to change it.  However, in the case of an
379 	 archive, it can cause problems.  If the specified target does
380 	 not permit archives (e.g., the binary target), then we should
381 	 not allow some other target to recognize it as an archive, but
382 	 should instead allow the specified target to recognize it as an
383 	 object.  When I first made this change, it broke the PE target,
384 	 because the specified pei-i386 target did not recognize the
385 	 actual pe-i386 archive.  Since there may be other problems of
386 	 this sort, I changed this test to check only for the binary
387 	 target.  */
388       if (format == bfd_archive && save_targ == &binary_vec)
389 	goto err_unrecog;
390     }
391 
392   /* Since the target type was defaulted, check them all in the hope
393      that one will be uniquely recognized.  */
394   right_targ = NULL;
395   ar_right_targ = NULL;
396   match_targ = NULL;
397   best_match = 256;
398   best_count = 0;
399   match_count = 0;
400   ar_match_index = _bfd_target_vector_entries;
401 
402   for (target = bfd_target_vector; *target != NULL; target++)
403     {
404       void **high_water;
405 
406       /* The binary target matches anything, so don't return it when
407 	 searching.  Don't match the plugin target if we have another
408 	 alternative since we want to properly set the input format
409 	 before allowing a plugin to claim the file.  Also, don't
410 	 check the default target twice.  */
411       if (*target == &binary_vec
412 #if BFD_SUPPORTS_PLUGINS
413 	  || (match_count != 0 && *target == &plugin_vec)
414 #endif
415 	  || (!abfd->target_defaulted && *target == save_targ))
416 	continue;
417 
418       /* If we already tried a match, the bfd is modified and may
419 	 have sections attached, which will confuse the next
420 	 _bfd_check_format call.  */
421       bfd_reinit (abfd, initial_section_id, &preserve, cleanup);
422       /* Free bfd_alloc memory too.  If we have matched and preserved
423 	 a target then the high water mark is that much higher.  */
424       if (preserve_match.marker)
425 	high_water = &preserve_match.marker;
426       else
427 	high_water = &preserve.marker;
428       bfd_release (abfd, *high_water);
429       *high_water = bfd_alloc (abfd, 1);
430 
431       /* Change BFD's target temporarily.  */
432       abfd->xvec = *target;
433 
434       if (bfd_seek (abfd, 0, SEEK_SET) != 0)
435 	goto err_ret;
436 
437       cleanup = BFD_SEND_FMT (abfd, _bfd_check_format, (abfd));
438       if (cleanup)
439 	{
440 	  int match_priority = abfd->xvec->match_priority;
441 #if BFD_SUPPORTS_PLUGINS
442 	  /* If this object can be handled by a plugin, give that the
443 	     lowest priority; objects both handled by a plugin and
444 	     with an underlying object format will be claimed
445 	     separately by the plugin.  */
446 	  if (*target == &plugin_vec)
447 	    match_priority = (*target)->match_priority;
448 #endif
449 
450 	  if (abfd->format != bfd_archive
451 	      || (bfd_has_map (abfd)
452 		  && bfd_get_error () != bfd_error_wrong_object_format))
453 	    {
454 	      /* If this is the default target, accept it, even if
455 		 other targets might match.  People who want those
456 		 other targets have to set the GNUTARGET variable.  */
457 	      if (abfd->xvec == bfd_default_vector[0])
458 		goto ok_ret;
459 
460 	      if (matching_vector)
461 		matching_vector[match_count] = abfd->xvec;
462 	      match_count++;
463 
464 	      if (match_priority < best_match)
465 		{
466 		  best_match = match_priority;
467 		  best_count = 0;
468 		}
469 	      if (match_priority <= best_match)
470 		{
471 		  /* This format checks out as ok!  */
472 		  right_targ = abfd->xvec;
473 		  best_count++;
474 		}
475 	    }
476 	  else
477 	    {
478 	      /* An archive with no armap or objects of the wrong
479 		 type.  We want this target to match if we get no
480 		 better matches.  */
481 	      if (ar_right_targ != bfd_default_vector[0])
482 		ar_right_targ = *target;
483 	      if (matching_vector)
484 		matching_vector[ar_match_index] = *target;
485 	      ar_match_index++;
486 	    }
487 
488 	  if (preserve_match.marker == NULL)
489 	    {
490 	      match_targ = abfd->xvec;
491 	      if (!bfd_preserve_save (abfd, &preserve_match, cleanup))
492 		goto err_ret;
493 	      cleanup = NULL;
494 	    }
495 	}
496     }
497 
498   if (best_count == 1)
499     match_count = 1;
500 
501   if (match_count == 0)
502     {
503       /* Try partial matches.  */
504       right_targ = ar_right_targ;
505 
506       if (right_targ == bfd_default_vector[0])
507 	{
508 	  match_count = 1;
509 	}
510       else
511 	{
512 	  match_count = ar_match_index - _bfd_target_vector_entries;
513 
514 	  if (matching_vector && match_count > 1)
515 	    memcpy (matching_vector,
516 		    matching_vector + _bfd_target_vector_entries,
517 		    sizeof (*matching_vector) * match_count);
518 	}
519     }
520 
521   /* We have more than one equally good match.  If any of the best
522      matches is a target in config.bfd targ_defvec or targ_selvecs,
523      choose it.  */
524   if (match_count > 1)
525     {
526       const bfd_target * const *assoc = bfd_associated_vector;
527 
528       while ((right_targ = *assoc++) != NULL)
529 	{
530 	  int i = match_count;
531 
532 	  while (--i >= 0)
533 	    if (matching_vector[i] == right_targ
534 		&& right_targ->match_priority <= best_match)
535 	      break;
536 
537 	  if (i >= 0)
538 	    {
539 	      match_count = 1;
540 	      break;
541 	    }
542 	}
543     }
544 
545   /* We still have more than one equally good match, and at least some
546      of the targets support match priority.  Choose the first of the
547      best matches.  */
548   if (matching_vector && match_count > 1 && best_count != match_count)
549     {
550       int i;
551 
552       for (i = 0; i < match_count; i++)
553 	{
554 	  right_targ = matching_vector[i];
555 	  if (right_targ->match_priority <= best_match)
556 	    break;
557 	}
558       match_count = 1;
559     }
560 
561   /* There is way too much undoing of half-known state here.  We
562      really shouldn't iterate on live bfd's.  Note that saving the
563      whole bfd and restoring it would be even worse; the first thing
564      you notice is that the cached bfd file position gets out of sync.  */
565   if (preserve_match.marker != NULL)
566     cleanup = bfd_preserve_restore (abfd, &preserve_match);
567 
568   if (match_count == 1)
569     {
570       abfd->xvec = right_targ;
571       /* If we come out of the loop knowing that the last target that
572 	 matched is the one we want, then ABFD should still be in a usable
573 	 state (except possibly for XVEC).  This is not just an
574 	 optimisation.  In the case of plugins a match against the
575 	 plugin target can result in the bfd being changed such that
576 	 it no longer matches the plugin target, nor will it match
577 	 RIGHT_TARG again.  */
578       if (match_targ != right_targ)
579 	{
580 	  bfd_reinit (abfd, initial_section_id, &preserve, cleanup);
581 	  bfd_release (abfd, preserve.marker);
582 	  if (bfd_seek (abfd, 0, SEEK_SET) != 0)
583 	    goto err_ret;
584 	  cleanup = BFD_SEND_FMT (abfd, _bfd_check_format, (abfd));
585 	  BFD_ASSERT (cleanup != NULL);
586 	}
587 
588     ok_ret:
589       /* If the file was opened for update, then `output_has_begun'
590 	 some time ago when the file was created.  Do not recompute
591 	 sections sizes or alignments in _bfd_set_section_contents.
592 	 We can not set this flag until after checking the format,
593 	 because it will interfere with creation of BFD sections.  */
594       if (abfd->direction == both_direction)
595 	abfd->output_has_begun = true;
596 
597       free (matching_vector);
598       if (preserve_match.marker != NULL)
599 	bfd_preserve_finish (abfd, &preserve_match);
600       bfd_preserve_finish (abfd, &preserve);
601       bfd_set_error_handler (orig_error_handler);
602 
603       struct per_xvec_message **list = _bfd_per_xvec_warn (abfd->xvec, 0);
604       if (*list)
605 	print_warnmsg (list);
606       list = _bfd_per_xvec_warn (NULL, 0);
607       for (size_t i = 0; i < _bfd_target_vector_entries + 1; i++)
608 	clear_warnmsg (list++);
609       --in_check_format;
610 
611       /* File position has moved, BTW.  */
612       return true;
613     }
614 
615   if (match_count == 0)
616     {
617     err_unrecog:
618       bfd_set_error (bfd_error_file_not_recognized);
619     err_ret:
620       if (cleanup)
621 	cleanup (abfd);
622       abfd->xvec = save_targ;
623       abfd->format = bfd_unknown;
624       free (matching_vector);
625       goto out;
626     }
627 
628   /* Restore original target type and format.  */
629   abfd->xvec = save_targ;
630   abfd->format = bfd_unknown;
631   bfd_set_error (bfd_error_file_ambiguously_recognized);
632 
633   if (matching)
634     {
635       *matching = (char **) matching_vector;
636       matching_vector[match_count] = NULL;
637       /* Return target names.  This is a little nasty.  Maybe we
638 	 should do another bfd_malloc?  */
639       while (--match_count >= 0)
640 	{
641 	  const char *name = matching_vector[match_count]->name;
642 	  *(const char **) &matching_vector[match_count] = name;
643 	}
644     }
645   else
646     free (matching_vector);
647   if (cleanup)
648     cleanup (abfd);
649  out:
650   if (preserve_match.marker != NULL)
651     bfd_preserve_finish (abfd, &preserve_match);
652   bfd_preserve_restore (abfd, &preserve);
653   bfd_set_error_handler (orig_error_handler);
654   struct per_xvec_message **list = _bfd_per_xvec_warn (NULL, 0);
655   struct per_xvec_message **one = NULL;
656   for (size_t i = 0; i < _bfd_target_vector_entries + 1; i++)
657     {
658       if (list[i])
659 	{
660 	  if (!one)
661 	    one = list + i;
662 	  else
663 	    {
664 	      one = NULL;
665 	      break;
666 	    }
667 	}
668     }
669   if (one)
670     print_warnmsg (one);
671   for (size_t i = 0; i < _bfd_target_vector_entries + 1; i++)
672     clear_warnmsg (list++);
673   --in_check_format;
674   return false;
675 }
676 
677 /*
678 FUNCTION
679 	bfd_set_format
680 
681 SYNOPSIS
682 	bool bfd_set_format (bfd *abfd, bfd_format format);
683 
684 DESCRIPTION
685 	This function sets the file format of the BFD @var{abfd} to the
686 	format @var{format}. If the target set in the BFD does not
687 	support the format requested, the format is invalid, or the BFD
688 	is not open for writing, then an error occurs.
689 */
690 
691 bool
bfd_set_format(bfd * abfd,bfd_format format)692 bfd_set_format (bfd *abfd, bfd_format format)
693 {
694   if (bfd_read_p (abfd)
695       || (unsigned int) abfd->format >= (unsigned int) bfd_type_end)
696     {
697       bfd_set_error (bfd_error_invalid_operation);
698       return false;
699     }
700 
701   if (abfd->format != bfd_unknown)
702     return abfd->format == format;
703 
704   /* Presume the answer is yes.  */
705   abfd->format = format;
706 
707   if (!BFD_SEND_FMT (abfd, _bfd_set_format, (abfd)))
708     {
709       abfd->format = bfd_unknown;
710       return false;
711     }
712 
713   return true;
714 }
715 
716 /*
717 FUNCTION
718 	bfd_format_string
719 
720 SYNOPSIS
721 	const char *bfd_format_string (bfd_format format);
722 
723 DESCRIPTION
724 	Return a pointer to a const string
725 	<<invalid>>, <<object>>, <<archive>>, <<core>>, or <<unknown>>,
726 	depending upon the value of @var{format}.
727 */
728 
729 const char *
bfd_format_string(bfd_format format)730 bfd_format_string (bfd_format format)
731 {
732   if (((int) format < (int) bfd_unknown)
733       || ((int) format >= (int) bfd_type_end))
734     return "invalid";
735 
736   switch (format)
737     {
738     case bfd_object:
739       return "object";		/* Linker/assembler/compiler output.  */
740     case bfd_archive:
741       return "archive";		/* Object archive file.  */
742     case bfd_core:
743       return "core";		/* Core dump.  */
744     default:
745       return "unknown";
746     }
747 }
748