format.c revision 1.3 1 1.1 christos /* Generic BFD support for file formats.
2 1.3 christos Copyright (C) 1990-2015 Free Software Foundation, Inc.
3 1.1 christos Written by Cygnus Support.
4 1.1 christos
5 1.1 christos This file is part of BFD, the Binary File Descriptor library.
6 1.1 christos
7 1.1 christos This program is free software; you can redistribute it and/or modify
8 1.1 christos it under the terms of the GNU General Public License as published by
9 1.1 christos the Free Software Foundation; either version 3 of the License, or
10 1.1 christos (at your option) any later version.
11 1.1 christos
12 1.1 christos This program is distributed in the hope that it will be useful,
13 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of
14 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 1.1 christos GNU General Public License for more details.
16 1.1 christos
17 1.1 christos You should have received a copy of the GNU General Public License
18 1.1 christos along with this program; if not, write to the Free Software
19 1.1 christos Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
20 1.1 christos MA 02110-1301, USA. */
21 1.1 christos
22 1.1 christos
23 1.1 christos /*
24 1.1 christos SECTION
25 1.1 christos File formats
26 1.1 christos
27 1.1 christos A format is a BFD concept of high level file contents type. The
28 1.1 christos formats supported by BFD are:
29 1.1 christos
30 1.1 christos o <<bfd_object>>
31 1.1 christos
32 1.1 christos The BFD may contain data, symbols, relocations and debug info.
33 1.1 christos
34 1.1 christos o <<bfd_archive>>
35 1.1 christos
36 1.1 christos The BFD contains other BFDs and an optional index.
37 1.1 christos
38 1.1 christos o <<bfd_core>>
39 1.1 christos
40 1.1 christos The BFD contains the result of an executable core dump.
41 1.1 christos
42 1.1 christos SUBSECTION
43 1.1 christos File format functions
44 1.1 christos */
45 1.1 christos
46 1.1 christos #include "sysdep.h"
47 1.1 christos #include "bfd.h"
48 1.1 christos #include "libbfd.h"
49 1.1 christos
50 1.1 christos /* IMPORT from targets.c. */
51 1.1 christos extern const size_t _bfd_target_vector_entries;
52 1.1 christos
53 1.1 christos /*
54 1.1 christos FUNCTION
55 1.1 christos bfd_check_format
56 1.1 christos
57 1.1 christos SYNOPSIS
58 1.1 christos bfd_boolean bfd_check_format (bfd *abfd, bfd_format format);
59 1.1 christos
60 1.1 christos DESCRIPTION
61 1.1 christos Verify if the file attached to the BFD @var{abfd} is compatible
62 1.1 christos with the format @var{format} (i.e., one of <<bfd_object>>,
63 1.1 christos <<bfd_archive>> or <<bfd_core>>).
64 1.1 christos
65 1.1 christos If the BFD has been set to a specific target before the
66 1.1 christos call, only the named target and format combination is
67 1.1 christos checked. If the target has not been set, or has been set to
68 1.1 christos <<default>>, then all the known target backends is
69 1.1 christos interrogated to determine a match. If the default target
70 1.1 christos matches, it is used. If not, exactly one target must recognize
71 1.1 christos the file, or an error results.
72 1.1 christos
73 1.1 christos The function returns <<TRUE>> on success, otherwise <<FALSE>>
74 1.1 christos with one of the following error codes:
75 1.1 christos
76 1.1 christos o <<bfd_error_invalid_operation>> -
77 1.1 christos if <<format>> is not one of <<bfd_object>>, <<bfd_archive>> or
78 1.1 christos <<bfd_core>>.
79 1.1 christos
80 1.1 christos o <<bfd_error_system_call>> -
81 1.1 christos if an error occured during a read - even some file mismatches
82 1.1 christos can cause bfd_error_system_calls.
83 1.1 christos
84 1.1 christos o <<file_not_recognised>> -
85 1.1 christos none of the backends recognised the file format.
86 1.1 christos
87 1.1 christos o <<bfd_error_file_ambiguously_recognized>> -
88 1.1 christos more than one backend recognised the file format.
89 1.1 christos */
90 1.1 christos
91 1.1 christos bfd_boolean
92 1.1 christos bfd_check_format (bfd *abfd, bfd_format format)
93 1.1 christos {
94 1.1 christos return bfd_check_format_matches (abfd, format, NULL);
95 1.1 christos }
96 1.1 christos
97 1.3 christos struct bfd_preserve
98 1.3 christos {
99 1.3 christos void *marker;
100 1.3 christos void *tdata;
101 1.3 christos flagword flags;
102 1.3 christos const struct bfd_arch_info *arch_info;
103 1.3 christos struct bfd_section *sections;
104 1.3 christos struct bfd_section *section_last;
105 1.3 christos unsigned int section_count;
106 1.3 christos struct bfd_hash_table section_htab;
107 1.3 christos };
108 1.3 christos
109 1.3 christos /* When testing an object for compatibility with a particular target
110 1.3 christos back-end, the back-end object_p function needs to set up certain
111 1.3 christos fields in the bfd on successfully recognizing the object. This
112 1.3 christos typically happens in a piecemeal fashion, with failures possible at
113 1.3 christos many points. On failure, the bfd is supposed to be restored to its
114 1.3 christos initial state, which is virtually impossible. However, restoring a
115 1.3 christos subset of the bfd state works in practice. This function stores
116 1.3 christos the subset. */
117 1.3 christos
118 1.3 christos static bfd_boolean
119 1.3 christos bfd_preserve_save (bfd *abfd, struct bfd_preserve *preserve)
120 1.3 christos {
121 1.3 christos preserve->tdata = abfd->tdata.any;
122 1.3 christos preserve->arch_info = abfd->arch_info;
123 1.3 christos preserve->flags = abfd->flags;
124 1.3 christos preserve->sections = abfd->sections;
125 1.3 christos preserve->section_last = abfd->section_last;
126 1.3 christos preserve->section_count = abfd->section_count;
127 1.3 christos preserve->section_htab = abfd->section_htab;
128 1.3 christos preserve->marker = bfd_alloc (abfd, 1);
129 1.3 christos if (preserve->marker == NULL)
130 1.3 christos return FALSE;
131 1.3 christos
132 1.3 christos return bfd_hash_table_init (&abfd->section_htab, bfd_section_hash_newfunc,
133 1.3 christos sizeof (struct section_hash_entry));
134 1.3 christos }
135 1.3 christos
136 1.3 christos /* Clear out a subset of BFD state. */
137 1.3 christos
138 1.3 christos static void
139 1.3 christos bfd_reinit (bfd *abfd)
140 1.3 christos {
141 1.3 christos abfd->tdata.any = NULL;
142 1.3 christos abfd->arch_info = &bfd_default_arch_struct;
143 1.3 christos abfd->flags &= BFD_FLAGS_SAVED;
144 1.3 christos bfd_section_list_clear (abfd);
145 1.3 christos }
146 1.3 christos
147 1.3 christos /* Restores bfd state saved by bfd_preserve_save. */
148 1.3 christos
149 1.3 christos static void
150 1.3 christos bfd_preserve_restore (bfd *abfd, struct bfd_preserve *preserve)
151 1.3 christos {
152 1.3 christos bfd_hash_table_free (&abfd->section_htab);
153 1.3 christos
154 1.3 christos abfd->tdata.any = preserve->tdata;
155 1.3 christos abfd->arch_info = preserve->arch_info;
156 1.3 christos abfd->flags = preserve->flags;
157 1.3 christos abfd->section_htab = preserve->section_htab;
158 1.3 christos abfd->sections = preserve->sections;
159 1.3 christos abfd->section_last = preserve->section_last;
160 1.3 christos abfd->section_count = preserve->section_count;
161 1.3 christos
162 1.3 christos /* bfd_release frees all memory more recently bfd_alloc'd than
163 1.3 christos its arg, as well as its arg. */
164 1.3 christos bfd_release (abfd, preserve->marker);
165 1.3 christos preserve->marker = NULL;
166 1.3 christos }
167 1.3 christos
168 1.3 christos /* Called when the bfd state saved by bfd_preserve_save is no longer
169 1.3 christos needed. */
170 1.3 christos
171 1.3 christos static void
172 1.3 christos bfd_preserve_finish (bfd *abfd ATTRIBUTE_UNUSED, struct bfd_preserve *preserve)
173 1.3 christos {
174 1.3 christos /* It would be nice to be able to free more memory here, eg. old
175 1.3 christos tdata, but that's not possible since these blocks are sitting
176 1.3 christos inside bfd_alloc'd memory. The section hash is on a separate
177 1.3 christos objalloc. */
178 1.3 christos bfd_hash_table_free (&preserve->section_htab);
179 1.3 christos preserve->marker = NULL;
180 1.3 christos }
181 1.3 christos
182 1.1 christos /*
183 1.1 christos FUNCTION
184 1.1 christos bfd_check_format_matches
185 1.1 christos
186 1.1 christos SYNOPSIS
187 1.1 christos bfd_boolean bfd_check_format_matches
188 1.1 christos (bfd *abfd, bfd_format format, char ***matching);
189 1.1 christos
190 1.1 christos DESCRIPTION
191 1.1 christos Like <<bfd_check_format>>, except when it returns FALSE with
192 1.1 christos <<bfd_errno>> set to <<bfd_error_file_ambiguously_recognized>>. In that
193 1.1 christos case, if @var{matching} is not NULL, it will be filled in with
194 1.1 christos a NULL-terminated list of the names of the formats that matched,
195 1.1 christos allocated with <<malloc>>.
196 1.1 christos Then the user may choose a format and try again.
197 1.1 christos
198 1.1 christos When done with the list that @var{matching} points to, the caller
199 1.1 christos should free it.
200 1.1 christos */
201 1.1 christos
202 1.1 christos bfd_boolean
203 1.1 christos bfd_check_format_matches (bfd *abfd, bfd_format format, char ***matching)
204 1.1 christos {
205 1.1 christos extern const bfd_target binary_vec;
206 1.1 christos const bfd_target * const *target;
207 1.1 christos const bfd_target **matching_vector = NULL;
208 1.1 christos const bfd_target *save_targ, *right_targ, *ar_right_targ, *match_targ;
209 1.1 christos int match_count, best_count, best_match;
210 1.1 christos int ar_match_index;
211 1.3 christos struct bfd_preserve preserve;
212 1.1 christos
213 1.1 christos if (matching != NULL)
214 1.1 christos *matching = NULL;
215 1.1 christos
216 1.1 christos if (!bfd_read_p (abfd)
217 1.1 christos || (unsigned int) abfd->format >= (unsigned int) bfd_type_end)
218 1.1 christos {
219 1.1 christos bfd_set_error (bfd_error_invalid_operation);
220 1.1 christos return FALSE;
221 1.1 christos }
222 1.1 christos
223 1.1 christos if (abfd->format != bfd_unknown)
224 1.1 christos return abfd->format == format;
225 1.1 christos
226 1.1 christos if (matching != NULL || *bfd_associated_vector != NULL)
227 1.1 christos {
228 1.1 christos bfd_size_type amt;
229 1.1 christos
230 1.1 christos amt = sizeof (*matching_vector) * 2 * _bfd_target_vector_entries;
231 1.1 christos matching_vector = (const bfd_target **) bfd_malloc (amt);
232 1.1 christos if (!matching_vector)
233 1.1 christos return FALSE;
234 1.1 christos }
235 1.1 christos
236 1.1 christos /* Presume the answer is yes. */
237 1.1 christos abfd->format = format;
238 1.3 christos save_targ = abfd->xvec;
239 1.3 christos preserve.marker = NULL;
240 1.1 christos
241 1.1 christos /* If the target type was explicitly specified, just check that target. */
242 1.1 christos if (!abfd->target_defaulted)
243 1.1 christos {
244 1.1 christos if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0) /* rewind! */
245 1.1 christos goto err_ret;
246 1.1 christos
247 1.1 christos right_targ = BFD_SEND_FMT (abfd, _bfd_check_format, (abfd));
248 1.1 christos
249 1.1 christos if (right_targ)
250 1.1 christos goto ok_ret;
251 1.1 christos
252 1.1 christos /* For a long time the code has dropped through to check all
253 1.1 christos targets if the specified target was wrong. I don't know why,
254 1.1 christos and I'm reluctant to change it. However, in the case of an
255 1.1 christos archive, it can cause problems. If the specified target does
256 1.1 christos not permit archives (e.g., the binary target), then we should
257 1.1 christos not allow some other target to recognize it as an archive, but
258 1.1 christos should instead allow the specified target to recognize it as an
259 1.1 christos object. When I first made this change, it broke the PE target,
260 1.1 christos because the specified pei-i386 target did not recognize the
261 1.1 christos actual pe-i386 archive. Since there may be other problems of
262 1.1 christos this sort, I changed this test to check only for the binary
263 1.1 christos target. */
264 1.1 christos if (format == bfd_archive && save_targ == &binary_vec)
265 1.1 christos goto err_unrecog;
266 1.1 christos }
267 1.1 christos
268 1.3 christos /* Since the target type was defaulted, check them all in the hope
269 1.3 christos that one will be uniquely recognized. */
270 1.3 christos right_targ = NULL;
271 1.3 christos ar_right_targ = NULL;
272 1.3 christos match_targ = NULL;
273 1.3 christos best_match = 256;
274 1.3 christos best_count = 0;
275 1.3 christos match_count = 0;
276 1.3 christos ar_match_index = _bfd_target_vector_entries;
277 1.3 christos
278 1.1 christos for (target = bfd_target_vector; *target != NULL; target++)
279 1.1 christos {
280 1.1 christos const bfd_target *temp;
281 1.1 christos
282 1.1 christos /* Don't check the default target twice. */
283 1.1 christos if (*target == &binary_vec
284 1.1 christos || (!abfd->target_defaulted && *target == save_targ)
285 1.1 christos || (*target)->match_priority > best_match)
286 1.1 christos continue;
287 1.1 christos
288 1.3 christos /* If we already tried a match, the bfd is modified and may
289 1.3 christos have sections attached, which will confuse the next
290 1.3 christos _bfd_check_format call. */
291 1.3 christos bfd_reinit (abfd);
292 1.3 christos
293 1.3 christos /* Change BFD's target temporarily. */
294 1.3 christos abfd->xvec = *target;
295 1.1 christos
296 1.1 christos if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
297 1.1 christos goto err_ret;
298 1.1 christos
299 1.1 christos /* If _bfd_check_format neglects to set bfd_error, assume
300 1.1 christos bfd_error_wrong_format. We didn't used to even pay any
301 1.1 christos attention to bfd_error, so I suspect that some
302 1.1 christos _bfd_check_format might have this problem. */
303 1.1 christos bfd_set_error (bfd_error_wrong_format);
304 1.1 christos
305 1.1 christos temp = BFD_SEND_FMT (abfd, _bfd_check_format, (abfd));
306 1.1 christos if (temp)
307 1.1 christos {
308 1.3 christos match_targ = temp;
309 1.3 christos if (preserve.marker != NULL)
310 1.3 christos bfd_preserve_finish (abfd, &preserve);
311 1.3 christos
312 1.3 christos if (abfd->format != bfd_archive
313 1.3 christos || (bfd_has_map (abfd)
314 1.3 christos && bfd_get_error () != bfd_error_wrong_object_format))
315 1.3 christos {
316 1.3 christos /* This format checks out as ok! */
317 1.3 christos right_targ = temp;
318 1.1 christos
319 1.3 christos /* If this is the default target, accept it, even if
320 1.3 christos other targets might match. People who want those
321 1.3 christos other targets have to set the GNUTARGET variable. */
322 1.3 christos if (temp == bfd_default_vector[0])
323 1.3 christos goto ok_ret;
324 1.3 christos
325 1.3 christos if (matching_vector)
326 1.3 christos matching_vector[match_count] = temp;
327 1.3 christos match_count++;
328 1.3 christos
329 1.3 christos if (temp->match_priority < best_match)
330 1.3 christos {
331 1.3 christos best_match = temp->match_priority;
332 1.3 christos best_count = 0;
333 1.3 christos }
334 1.3 christos best_count++;
335 1.3 christos }
336 1.3 christos else
337 1.1 christos {
338 1.3 christos /* An archive with no armap or objects of the wrong
339 1.3 christos type. We want this target to match if we get no
340 1.3 christos better matches. */
341 1.3 christos if (ar_right_targ != bfd_default_vector[0])
342 1.3 christos ar_right_targ = *target;
343 1.3 christos if (matching_vector)
344 1.3 christos matching_vector[ar_match_index] = *target;
345 1.3 christos ar_match_index++;
346 1.1 christos }
347 1.3 christos
348 1.3 christos if (!bfd_preserve_save (abfd, &preserve))
349 1.3 christos goto err_ret;
350 1.1 christos }
351 1.3 christos else if (bfd_get_error () != bfd_error_wrong_format)
352 1.1 christos goto err_ret;
353 1.1 christos }
354 1.1 christos
355 1.1 christos if (best_count == 1)
356 1.1 christos match_count = 1;
357 1.1 christos
358 1.1 christos if (match_count == 0)
359 1.1 christos {
360 1.1 christos /* Try partial matches. */
361 1.1 christos right_targ = ar_right_targ;
362 1.1 christos
363 1.1 christos if (right_targ == bfd_default_vector[0])
364 1.1 christos {
365 1.1 christos match_count = 1;
366 1.1 christos }
367 1.1 christos else
368 1.1 christos {
369 1.1 christos match_count = ar_match_index - _bfd_target_vector_entries;
370 1.1 christos
371 1.1 christos if (matching_vector && match_count > 1)
372 1.1 christos memcpy (matching_vector,
373 1.1 christos matching_vector + _bfd_target_vector_entries,
374 1.1 christos sizeof (*matching_vector) * match_count);
375 1.1 christos }
376 1.1 christos }
377 1.1 christos
378 1.3 christos /* We have more than one equally good match. If any of the best
379 1.3 christos matches is a target in config.bfd targ_defvec or targ_selvecs,
380 1.3 christos choose it. */
381 1.1 christos if (match_count > 1)
382 1.1 christos {
383 1.1 christos const bfd_target * const *assoc = bfd_associated_vector;
384 1.1 christos
385 1.1 christos while ((right_targ = *assoc++) != NULL)
386 1.1 christos {
387 1.1 christos int i = match_count;
388 1.1 christos
389 1.1 christos while (--i >= 0)
390 1.3 christos if (matching_vector[i] == right_targ
391 1.3 christos && right_targ->match_priority <= best_match)
392 1.1 christos break;
393 1.1 christos
394 1.1 christos if (i >= 0)
395 1.1 christos {
396 1.1 christos match_count = 1;
397 1.1 christos break;
398 1.1 christos }
399 1.1 christos }
400 1.1 christos }
401 1.1 christos
402 1.3 christos /* We still have more than one equally good match, and at least some
403 1.3 christos of the targets support match priority. Choose the first of the
404 1.3 christos best matches. */
405 1.3 christos if (matching_vector && match_count > 1 && best_count != match_count)
406 1.3 christos {
407 1.3 christos int i;
408 1.3 christos
409 1.3 christos for (i = 0; i < match_count; i++)
410 1.3 christos {
411 1.3 christos right_targ = matching_vector[i];
412 1.3 christos if (right_targ->match_priority <= best_match)
413 1.3 christos break;
414 1.3 christos }
415 1.3 christos match_count = 1;
416 1.3 christos }
417 1.3 christos
418 1.3 christos /* There is way too much undoing of half-known state here. We
419 1.3 christos really shouldn't iterate on live bfd's. Note that saving the
420 1.3 christos whole bfd and restoring it would be even worse; the first thing
421 1.3 christos you notice is that the cached bfd file position gets out of sync. */
422 1.3 christos if (preserve.marker != NULL)
423 1.3 christos bfd_preserve_restore (abfd, &preserve);
424 1.3 christos
425 1.1 christos if (match_count == 1)
426 1.1 christos {
427 1.1 christos abfd->xvec = right_targ;
428 1.1 christos /* If we come out of the loop knowing that the last target that
429 1.1 christos matched is the one we want, then ABFD should still be in a usable
430 1.1 christos state (except possibly for XVEC). */
431 1.1 christos if (match_targ != right_targ)
432 1.1 christos {
433 1.3 christos bfd_reinit (abfd);
434 1.1 christos if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
435 1.1 christos goto err_ret;
436 1.1 christos match_targ = BFD_SEND_FMT (abfd, _bfd_check_format, (abfd));
437 1.3 christos BFD_ASSERT (match_targ != NULL);
438 1.1 christos }
439 1.1 christos
440 1.1 christos ok_ret:
441 1.1 christos /* If the file was opened for update, then `output_has_begun'
442 1.1 christos some time ago when the file was created. Do not recompute
443 1.1 christos sections sizes or alignments in _bfd_set_section_contents.
444 1.1 christos We can not set this flag until after checking the format,
445 1.1 christos because it will interfere with creation of BFD sections. */
446 1.1 christos if (abfd->direction == both_direction)
447 1.1 christos abfd->output_has_begun = TRUE;
448 1.1 christos
449 1.1 christos if (matching_vector)
450 1.1 christos free (matching_vector);
451 1.3 christos
452 1.3 christos /* File position has moved, BTW. */
453 1.3 christos return TRUE;
454 1.1 christos }
455 1.1 christos
456 1.1 christos if (match_count == 0)
457 1.1 christos {
458 1.1 christos err_unrecog:
459 1.1 christos bfd_set_error (bfd_error_file_not_recognized);
460 1.1 christos err_ret:
461 1.1 christos abfd->xvec = save_targ;
462 1.1 christos abfd->format = bfd_unknown;
463 1.1 christos if (matching_vector)
464 1.1 christos free (matching_vector);
465 1.3 christos if (preserve.marker != NULL)
466 1.3 christos bfd_preserve_restore (abfd, &preserve);
467 1.1 christos return FALSE;
468 1.1 christos }
469 1.1 christos
470 1.3 christos /* Restore original target type and format. */
471 1.3 christos abfd->xvec = save_targ;
472 1.3 christos abfd->format = bfd_unknown;
473 1.1 christos bfd_set_error (bfd_error_file_ambiguously_recognized);
474 1.1 christos
475 1.1 christos if (matching)
476 1.1 christos {
477 1.1 christos *matching = (char **) matching_vector;
478 1.1 christos matching_vector[match_count] = NULL;
479 1.1 christos /* Return target names. This is a little nasty. Maybe we
480 1.1 christos should do another bfd_malloc? */
481 1.1 christos while (--match_count >= 0)
482 1.1 christos {
483 1.1 christos const char *name = matching_vector[match_count]->name;
484 1.1 christos *(const char **) &matching_vector[match_count] = name;
485 1.1 christos }
486 1.1 christos }
487 1.1 christos return FALSE;
488 1.1 christos }
489 1.1 christos
490 1.1 christos /*
491 1.1 christos FUNCTION
492 1.1 christos bfd_set_format
493 1.1 christos
494 1.1 christos SYNOPSIS
495 1.1 christos bfd_boolean bfd_set_format (bfd *abfd, bfd_format format);
496 1.1 christos
497 1.1 christos DESCRIPTION
498 1.1 christos This function sets the file format of the BFD @var{abfd} to the
499 1.1 christos format @var{format}. If the target set in the BFD does not
500 1.1 christos support the format requested, the format is invalid, or the BFD
501 1.1 christos is not open for writing, then an error occurs.
502 1.1 christos */
503 1.1 christos
504 1.1 christos bfd_boolean
505 1.1 christos bfd_set_format (bfd *abfd, bfd_format format)
506 1.1 christos {
507 1.1 christos if (bfd_read_p (abfd)
508 1.1 christos || (unsigned int) abfd->format >= (unsigned int) bfd_type_end)
509 1.1 christos {
510 1.1 christos bfd_set_error (bfd_error_invalid_operation);
511 1.1 christos return FALSE;
512 1.1 christos }
513 1.1 christos
514 1.1 christos if (abfd->format != bfd_unknown)
515 1.1 christos return abfd->format == format;
516 1.1 christos
517 1.1 christos /* Presume the answer is yes. */
518 1.1 christos abfd->format = format;
519 1.1 christos
520 1.1 christos if (!BFD_SEND_FMT (abfd, _bfd_set_format, (abfd)))
521 1.1 christos {
522 1.1 christos abfd->format = bfd_unknown;
523 1.1 christos return FALSE;
524 1.1 christos }
525 1.1 christos
526 1.1 christos return TRUE;
527 1.1 christos }
528 1.1 christos
529 1.1 christos /*
530 1.1 christos FUNCTION
531 1.1 christos bfd_format_string
532 1.1 christos
533 1.1 christos SYNOPSIS
534 1.1 christos const char *bfd_format_string (bfd_format format);
535 1.1 christos
536 1.1 christos DESCRIPTION
537 1.1 christos Return a pointer to a const string
538 1.1 christos <<invalid>>, <<object>>, <<archive>>, <<core>>, or <<unknown>>,
539 1.1 christos depending upon the value of @var{format}.
540 1.1 christos */
541 1.1 christos
542 1.1 christos const char *
543 1.1 christos bfd_format_string (bfd_format format)
544 1.1 christos {
545 1.1 christos if (((int) format < (int) bfd_unknown)
546 1.1 christos || ((int) format >= (int) bfd_type_end))
547 1.1 christos return "invalid";
548 1.1 christos
549 1.1 christos switch (format)
550 1.1 christos {
551 1.1 christos case bfd_object:
552 1.1 christos return "object"; /* Linker/assembler/compiler output. */
553 1.1 christos case bfd_archive:
554 1.1 christos return "archive"; /* Object archive file. */
555 1.1 christos case bfd_core:
556 1.1 christos return "core"; /* Core dump. */
557 1.1 christos default:
558 1.1 christos return "unknown";
559 1.1 christos }
560 1.1 christos }
561