133965Sjdp/* Generic BFD support for file formats. 2218822Sdim Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1999, 2000, 2001, 2002, 3218822Sdim 2003, 2005, 2007 Free Software Foundation, Inc. 433965Sjdp Written by Cygnus Support. 533965Sjdp 6130561Sobrien This file is part of BFD, the Binary File Descriptor library. 733965Sjdp 8130561Sobrien This program is free software; you can redistribute it and/or modify 9130561Sobrien it under the terms of the GNU General Public License as published by 10130561Sobrien the Free Software Foundation; either version 2 of the License, or 11130561Sobrien (at your option) any later version. 1233965Sjdp 13130561Sobrien This program is distributed in the hope that it will be useful, 14130561Sobrien but WITHOUT ANY WARRANTY; without even the implied warranty of 15130561Sobrien MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16130561Sobrien GNU General Public License for more details. 1733965Sjdp 18130561Sobrien You should have received a copy of the GNU General Public License 19130561Sobrien along with this program; if not, write to the Free Software 20218822Sdim Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ 2133965Sjdp 2233965Sjdp/* 2333965SjdpSECTION 2433965Sjdp File formats 2533965Sjdp 2633965Sjdp A format is a BFD concept of high level file contents type. The 2777298Sobrien formats supported by BFD are: 2833965Sjdp 2933965Sjdp o <<bfd_object>> 3033965Sjdp 3133965Sjdp The BFD may contain data, symbols, relocations and debug info. 3233965Sjdp 3333965Sjdp o <<bfd_archive>> 3433965Sjdp 3533965Sjdp The BFD contains other BFDs and an optional index. 3633965Sjdp 3733965Sjdp o <<bfd_core>> 3833965Sjdp 3933965Sjdp The BFD contains the result of an executable core dump. 4033965Sjdp 41218822SdimSUBSECTION 42218822Sdim File format functions 4333965Sjdp*/ 4433965Sjdp 45218822Sdim#include "sysdep.h" 4633965Sjdp#include "bfd.h" 4733965Sjdp#include "libbfd.h" 4833965Sjdp 4933965Sjdp/* IMPORT from targets.c. */ 5033965Sjdpextern const size_t _bfd_target_vector_entries; 5133965Sjdp 5233965Sjdp/* 5333965SjdpFUNCTION 5433965Sjdp bfd_check_format 5533965Sjdp 5633965SjdpSYNOPSIS 57130561Sobrien bfd_boolean bfd_check_format (bfd *abfd, bfd_format format); 5833965Sjdp 5933965SjdpDESCRIPTION 6033965Sjdp Verify if the file attached to the BFD @var{abfd} is compatible 6133965Sjdp with the format @var{format} (i.e., one of <<bfd_object>>, 6233965Sjdp <<bfd_archive>> or <<bfd_core>>). 6333965Sjdp 6433965Sjdp If the BFD has been set to a specific target before the 6533965Sjdp call, only the named target and format combination is 6633965Sjdp checked. If the target has not been set, or has been set to 6733965Sjdp <<default>>, then all the known target backends is 6833965Sjdp interrogated to determine a match. If the default target 6933965Sjdp matches, it is used. If not, exactly one target must recognize 7033965Sjdp the file, or an error results. 7133965Sjdp 72130561Sobrien The function returns <<TRUE>> on success, otherwise <<FALSE>> 7377298Sobrien with one of the following error codes: 7433965Sjdp 7533965Sjdp o <<bfd_error_invalid_operation>> - 7633965Sjdp if <<format>> is not one of <<bfd_object>>, <<bfd_archive>> or 7733965Sjdp <<bfd_core>>. 7833965Sjdp 7933965Sjdp o <<bfd_error_system_call>> - 8033965Sjdp if an error occured during a read - even some file mismatches 8133965Sjdp can cause bfd_error_system_calls. 8233965Sjdp 8333965Sjdp o <<file_not_recognised>> - 8433965Sjdp none of the backends recognised the file format. 8533965Sjdp 8633965Sjdp o <<bfd_error_file_ambiguously_recognized>> - 8733965Sjdp more than one backend recognised the file format. 8833965Sjdp*/ 8933965Sjdp 90130561Sobrienbfd_boolean 91130561Sobrienbfd_check_format (bfd *abfd, bfd_format format) 9233965Sjdp{ 9333965Sjdp return bfd_check_format_matches (abfd, format, NULL); 9433965Sjdp} 9533965Sjdp 9633965Sjdp/* 9733965SjdpFUNCTION 9833965Sjdp bfd_check_format_matches 9933965Sjdp 10033965SjdpSYNOPSIS 101130561Sobrien bfd_boolean bfd_check_format_matches 102130561Sobrien (bfd *abfd, bfd_format format, char ***matching); 10333965Sjdp 10433965SjdpDESCRIPTION 105130561Sobrien Like <<bfd_check_format>>, except when it returns FALSE with 10633965Sjdp <<bfd_errno>> set to <<bfd_error_file_ambiguously_recognized>>. In that 10733965Sjdp case, if @var{matching} is not NULL, it will be filled in with 10833965Sjdp a NULL-terminated list of the names of the formats that matched, 10933965Sjdp allocated with <<malloc>>. 11033965Sjdp Then the user may choose a format and try again. 11133965Sjdp 11233965Sjdp When done with the list that @var{matching} points to, the caller 11377298Sobrien should free it. 11433965Sjdp*/ 11533965Sjdp 116130561Sobrienbfd_boolean 117130561Sobrienbfd_check_format_matches (bfd *abfd, bfd_format format, char ***matching) 11833965Sjdp{ 11960484Sobrien extern const bfd_target binary_vec; 120130561Sobrien const bfd_target * const *target; 121130561Sobrien const bfd_target **matching_vector = NULL; 122130561Sobrien const bfd_target *save_targ, *right_targ, *ar_right_targ; 12333965Sjdp int match_count; 12489857Sobrien int ar_match_index; 12533965Sjdp 12689857Sobrien if (!bfd_read_p (abfd) 12789857Sobrien || (unsigned int) abfd->format >= (unsigned int) bfd_type_end) 12877298Sobrien { 12977298Sobrien bfd_set_error (bfd_error_invalid_operation); 130130561Sobrien return FALSE; 13177298Sobrien } 13233965Sjdp 13333965Sjdp if (abfd->format != bfd_unknown) 134130561Sobrien return abfd->format == format; 13533965Sjdp 13677298Sobrien /* Since the target type was defaulted, check them 13733965Sjdp all in the hope that one will be uniquely recognized. */ 13833965Sjdp save_targ = abfd->xvec; 13933965Sjdp match_count = 0; 14089857Sobrien ar_match_index = _bfd_target_vector_entries; 14177298Sobrien 14233965Sjdp if (matching) 14333965Sjdp { 14489857Sobrien bfd_size_type amt; 14589857Sobrien 14689857Sobrien *matching = NULL; 147130561Sobrien amt = sizeof (*matching_vector) * 2 * _bfd_target_vector_entries; 148130561Sobrien matching_vector = bfd_malloc (amt); 14933965Sjdp if (!matching_vector) 150130561Sobrien return FALSE; 15133965Sjdp } 15277298Sobrien 15333965Sjdp right_targ = 0; 15489857Sobrien ar_right_targ = 0; 15533965Sjdp 15677298Sobrien /* Presume the answer is yes. */ 15733965Sjdp abfd->format = format; 15833965Sjdp 15933965Sjdp /* If the target type was explicitly specified, just check that target. */ 16077298Sobrien if (!abfd->target_defaulted) 16177298Sobrien { 16289857Sobrien if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0) /* rewind! */ 163130561Sobrien { 164130561Sobrien if (matching) 165130561Sobrien free (matching_vector); 166130561Sobrien return FALSE; 167130561Sobrien } 16833965Sjdp 16977298Sobrien right_targ = BFD_SEND_FMT (abfd, _bfd_check_format, (abfd)); 17077298Sobrien 17177298Sobrien if (right_targ) 17277298Sobrien { 17377298Sobrien abfd->xvec = right_targ; /* Set the target as returned. */ 17477298Sobrien 17577298Sobrien if (matching) 17677298Sobrien free (matching_vector); 17777298Sobrien 178218822Sdim /* If the file was opened for update, then `output_has_begun' 179218822Sdim some time ago when the file was created. Do not recompute 180218822Sdim sections sizes or alignments in _bfd_set_section_contents. 181218822Sdim We can not set this flag until after checking the format, 182218822Sdim because it will interfere with creation of BFD sections. */ 183218822Sdim if (abfd->direction == both_direction) 184218822Sdim abfd->output_has_begun = TRUE; 185218822Sdim 186130561Sobrien return TRUE; /* File position has moved, BTW. */ 18777298Sobrien } 18877298Sobrien 18977298Sobrien /* For a long time the code has dropped through to check all 19077298Sobrien targets if the specified target was wrong. I don't know why, 19177298Sobrien and I'm reluctant to change it. However, in the case of an 19277298Sobrien archive, it can cause problems. If the specified target does 19377298Sobrien not permit archives (e.g., the binary target), then we should 19477298Sobrien not allow some other target to recognize it as an archive, but 19577298Sobrien should instead allow the specified target to recognize it as an 19677298Sobrien object. When I first made this change, it broke the PE target, 19777298Sobrien because the specified pei-i386 target did not recognize the 19877298Sobrien actual pe-i386 archive. Since there may be other problems of 19977298Sobrien this sort, I changed this test to check only for the binary 20077298Sobrien target. */ 20177298Sobrien if (format == bfd_archive && save_targ == &binary_vec) 20277298Sobrien { 20377298Sobrien abfd->xvec = save_targ; 20477298Sobrien abfd->format = bfd_unknown; 20577298Sobrien 20677298Sobrien if (matching) 20777298Sobrien free (matching_vector); 20877298Sobrien 20977298Sobrien bfd_set_error (bfd_error_file_not_recognized); 21077298Sobrien 211130561Sobrien return FALSE; 21277298Sobrien } 21333965Sjdp } 21460484Sobrien 21577298Sobrien for (target = bfd_target_vector; *target != NULL; target++) 21677298Sobrien { 21777298Sobrien const bfd_target *temp; 21889857Sobrien bfd_error_type err; 21960484Sobrien 220218822Sdim /* Don't check the default target twice. */ 221218822Sdim if (*target == &binary_vec 222218822Sdim || (!abfd->target_defaulted && *target == save_targ)) 22377298Sobrien continue; 22477298Sobrien 225130561Sobrien abfd->xvec = *target; /* Change BFD's target temporarily. */ 22677298Sobrien 22789857Sobrien if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0) 228130561Sobrien { 229130561Sobrien if (matching) 230130561Sobrien free (matching_vector); 231130561Sobrien return FALSE; 232130561Sobrien } 23333965Sjdp 23477298Sobrien /* If _bfd_check_format neglects to set bfd_error, assume 23577298Sobrien bfd_error_wrong_format. We didn't used to even pay any 23677298Sobrien attention to bfd_error, so I suspect that some 23777298Sobrien _bfd_check_format might have this problem. */ 23877298Sobrien bfd_set_error (bfd_error_wrong_format); 23933965Sjdp 24077298Sobrien temp = BFD_SEND_FMT (abfd, _bfd_check_format, (abfd)); 24133965Sjdp 24277298Sobrien if (temp) 243130561Sobrien { 244130561Sobrien /* This format checks out as ok! */ 24577298Sobrien right_targ = temp; 24677298Sobrien 24777298Sobrien /* If this is the default target, accept it, even if other 24877298Sobrien targets might match. People who want those other targets 24977298Sobrien have to set the GNUTARGET variable. */ 25077298Sobrien if (temp == bfd_default_vector[0]) 25177298Sobrien { 25277298Sobrien match_count = 1; 25377298Sobrien break; 25477298Sobrien } 25589857Sobrien 25689857Sobrien if (matching) 257130561Sobrien matching_vector[match_count] = temp; 25889857Sobrien 25989857Sobrien match_count++; 26033965Sjdp } 26189857Sobrien else if ((err = bfd_get_error ()) == bfd_error_wrong_object_format 26289857Sobrien || err == bfd_error_file_ambiguously_recognized) 26377298Sobrien { 26489857Sobrien /* An archive with objects of the wrong type, or an 26589857Sobrien ambiguous match. We want this target to match if we get 26689857Sobrien no better matches. */ 26789857Sobrien if (ar_right_targ != bfd_default_vector[0]) 26889857Sobrien ar_right_targ = *target; 26989857Sobrien if (matching) 270130561Sobrien matching_vector[ar_match_index] = *target; 27189857Sobrien ar_match_index++; 27289857Sobrien } 27389857Sobrien else if (err != bfd_error_wrong_format) 27489857Sobrien { 27577298Sobrien abfd->xvec = save_targ; 27677298Sobrien abfd->format = bfd_unknown; 27777298Sobrien 27889857Sobrien if (matching) 27977298Sobrien free (matching_vector); 28077298Sobrien 281130561Sobrien return FALSE; 28277298Sobrien } 28377298Sobrien } 28477298Sobrien 28589857Sobrien if (match_count == 0) 28689857Sobrien { 28789857Sobrien /* Try partial matches. */ 28889857Sobrien right_targ = ar_right_targ; 289130561Sobrien 29089857Sobrien if (right_targ == bfd_default_vector[0]) 29189857Sobrien { 29289857Sobrien match_count = 1; 29389857Sobrien } 29489857Sobrien else 29589857Sobrien { 29689857Sobrien match_count = ar_match_index - _bfd_target_vector_entries; 297130561Sobrien 29889857Sobrien if (matching && match_count > 1) 299130561Sobrien memcpy (matching_vector, 300130561Sobrien matching_vector + _bfd_target_vector_entries, 301130561Sobrien sizeof (*matching_vector) * match_count); 302130561Sobrien } 303130561Sobrien } 304130561Sobrien 305130561Sobrien if (match_count > 1 306130561Sobrien && bfd_associated_vector != NULL 307130561Sobrien && matching) 308130561Sobrien { 309130561Sobrien const bfd_target * const *assoc = bfd_associated_vector; 310130561Sobrien 311130561Sobrien while ((right_targ = *assoc++) != NULL) 312130561Sobrien { 313130561Sobrien int i = match_count; 314130561Sobrien 315130561Sobrien while (--i >= 0) 316130561Sobrien if (matching_vector[i] == right_targ) 317130561Sobrien break; 318130561Sobrien 319130561Sobrien if (i >= 0) 32089857Sobrien { 321130561Sobrien match_count = 1; 322130561Sobrien break; 32389857Sobrien } 32489857Sobrien } 32589857Sobrien } 32689857Sobrien 32777298Sobrien if (match_count == 1) 32877298Sobrien { 32977298Sobrien abfd->xvec = right_targ; /* Change BFD's target permanently. */ 33077298Sobrien 33177298Sobrien if (matching) 33233965Sjdp free (matching_vector); 33377298Sobrien 334218822Sdim /* If the file was opened for update, then `output_has_begun' 335218822Sdim some time ago when the file was created. Do not recompute 336218822Sdim sections sizes or alignments in _bfd_set_section_contents. 337218822Sdim We can not set this flag until after checking the format, 338218822Sdim because it will interfere with creation of BFD sections. */ 339218822Sdim if (abfd->direction == both_direction) 340218822Sdim abfd->output_has_begun = TRUE; 341218822Sdim 342130561Sobrien return TRUE; /* File position has moved, BTW. */ 34333965Sjdp } 34433965Sjdp 34577298Sobrien abfd->xvec = save_targ; /* Restore original target type. */ 34677298Sobrien abfd->format = bfd_unknown; /* Restore original format. */ 34733965Sjdp 34833965Sjdp if (match_count == 0) 34933965Sjdp { 35033965Sjdp bfd_set_error (bfd_error_file_not_recognized); 35177298Sobrien 35233965Sjdp if (matching) 35333965Sjdp free (matching_vector); 35433965Sjdp } 35533965Sjdp else 35689857Sobrien { 35789857Sobrien bfd_set_error (bfd_error_file_ambiguously_recognized); 35877298Sobrien 35989857Sobrien if (matching) 36089857Sobrien { 361130561Sobrien *matching = (char **) matching_vector; 36289857Sobrien matching_vector[match_count] = NULL; 363130561Sobrien /* Return target names. This is a little nasty. Maybe we 364130561Sobrien should do another bfd_malloc? */ 365130561Sobrien while (--match_count >= 0) 366130561Sobrien { 367130561Sobrien const char *name = matching_vector[match_count]->name; 368130561Sobrien *(const char **) &matching_vector[match_count] = name; 369130561Sobrien } 37089857Sobrien } 37189857Sobrien } 37289857Sobrien 373130561Sobrien return FALSE; 37433965Sjdp} 37533965Sjdp 37633965Sjdp/* 37733965SjdpFUNCTION 37833965Sjdp bfd_set_format 37933965Sjdp 38033965SjdpSYNOPSIS 381130561Sobrien bfd_boolean bfd_set_format (bfd *abfd, bfd_format format); 38233965Sjdp 38333965SjdpDESCRIPTION 38433965Sjdp This function sets the file format of the BFD @var{abfd} to the 38533965Sjdp format @var{format}. If the target set in the BFD does not 38633965Sjdp support the format requested, the format is invalid, or the BFD 38733965Sjdp is not open for writing, then an error occurs. 38833965Sjdp*/ 38933965Sjdp 390130561Sobrienbfd_boolean 391130561Sobrienbfd_set_format (bfd *abfd, bfd_format format) 39233965Sjdp{ 39389857Sobrien if (bfd_read_p (abfd) 39489857Sobrien || (unsigned int) abfd->format >= (unsigned int) bfd_type_end) 39577298Sobrien { 39677298Sobrien bfd_set_error (bfd_error_invalid_operation); 397130561Sobrien return FALSE; 39877298Sobrien } 39933965Sjdp 40033965Sjdp if (abfd->format != bfd_unknown) 401130561Sobrien return abfd->format == format; 40233965Sjdp 40377298Sobrien /* Presume the answer is yes. */ 40433965Sjdp abfd->format = format; 40533965Sjdp 40677298Sobrien if (!BFD_SEND_FMT (abfd, _bfd_set_format, (abfd))) 40777298Sobrien { 40877298Sobrien abfd->format = bfd_unknown; 409130561Sobrien return FALSE; 41077298Sobrien } 41133965Sjdp 412130561Sobrien return TRUE; 41333965Sjdp} 41433965Sjdp 41533965Sjdp/* 41633965SjdpFUNCTION 41733965Sjdp bfd_format_string 41833965Sjdp 41933965SjdpSYNOPSIS 420130561Sobrien const char *bfd_format_string (bfd_format format); 42133965Sjdp 42233965SjdpDESCRIPTION 42333965Sjdp Return a pointer to a const string 42433965Sjdp <<invalid>>, <<object>>, <<archive>>, <<core>>, or <<unknown>>, 42533965Sjdp depending upon the value of @var{format}. 42633965Sjdp*/ 42733965Sjdp 42889857Sobrienconst char * 429130561Sobrienbfd_format_string (bfd_format format) 43033965Sjdp{ 431130561Sobrien if (((int) format < (int) bfd_unknown) 432130561Sobrien || ((int) format >= (int) bfd_type_end)) 43333965Sjdp return "invalid"; 43477298Sobrien 43577298Sobrien switch (format) 43677298Sobrien { 43777298Sobrien case bfd_object: 438130561Sobrien return "object"; /* Linker/assembler/compiler output. */ 43977298Sobrien case bfd_archive: 44077298Sobrien return "archive"; /* Object archive file. */ 44177298Sobrien case bfd_core: 44277298Sobrien return "core"; /* Core dump. */ 44377298Sobrien default: 44477298Sobrien return "unknown"; 44577298Sobrien } 44633965Sjdp} 447