X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=bfd%2Fformat.c;h=1d1363d18403cef706ec1a81f164c5b6521dd20f;hb=8ff23dba80b80a9f47d75dd43812e041f6674763;hp=f0d1e668c77d49406b3933b66327fccaa67742c1;hpb=033539e2685156ad6ad60e5925bc61cef5ced483;p=deliverable%2Fbinutils-gdb.git diff --git a/bfd/format.c b/bfd/format.c index f0d1e668c7..1d1363d184 100644 --- a/bfd/format.c +++ b/bfd/format.c @@ -1,5 +1,5 @@ /* Generic BFD support for file formats. - Copyright (C) 1990-2014 Free Software Foundation, Inc. + Copyright (C) 1990-2019 Free Software Foundation, Inc. Written by Cygnus Support. This file is part of BFD, the Binary File Descriptor library. @@ -103,7 +103,9 @@ struct bfd_preserve struct bfd_section *sections; struct bfd_section *section_last; unsigned int section_count; + unsigned int section_id; struct bfd_hash_table section_htab; + const struct bfd_build_id *build_id; }; /* When testing an object for compatibility with a particular target @@ -124,8 +126,10 @@ bfd_preserve_save (bfd *abfd, struct bfd_preserve *preserve) preserve->sections = abfd->sections; preserve->section_last = abfd->section_last; preserve->section_count = abfd->section_count; + preserve->section_id = _bfd_section_id; preserve->section_htab = abfd->section_htab; preserve->marker = bfd_alloc (abfd, 1); + preserve->build_id = abfd->build_id; if (preserve->marker == NULL) return FALSE; @@ -136,12 +140,13 @@ bfd_preserve_save (bfd *abfd, struct bfd_preserve *preserve) /* Clear out a subset of BFD state. */ static void -bfd_reinit (bfd *abfd) +bfd_reinit (bfd *abfd, unsigned int section_id) { abfd->tdata.any = NULL; abfd->arch_info = &bfd_default_arch_struct; abfd->flags &= BFD_FLAGS_SAVED; bfd_section_list_clear (abfd); + _bfd_section_id = section_id; } /* Restores bfd state saved by bfd_preserve_save. */ @@ -158,6 +163,8 @@ bfd_preserve_restore (bfd *abfd, struct bfd_preserve *preserve) abfd->sections = preserve->sections; abfd->section_last = preserve->section_last; abfd->section_count = preserve->section_count; + _bfd_section_id = preserve->section_id; + abfd->build_id = preserve->build_id; /* bfd_release frees all memory more recently bfd_alloc'd than its arg, as well as its arg. */ @@ -203,11 +210,15 @@ bfd_boolean bfd_check_format_matches (bfd *abfd, bfd_format format, char ***matching) { extern const bfd_target binary_vec; +#if BFD_SUPPORTS_PLUGINS + extern const bfd_target plugin_vec; +#endif const bfd_target * const *target; const bfd_target **matching_vector = NULL; const bfd_target *save_targ, *right_targ, *ar_right_targ, *match_targ; int match_count, best_count, best_match; int ar_match_index; + unsigned int initial_section_id = _bfd_section_id; struct bfd_preserve preserve; if (matching != NULL) @@ -279,16 +290,22 @@ bfd_check_format_matches (bfd *abfd, bfd_format format, char ***matching) { const bfd_target *temp; - /* Don't check the default target twice. */ + /* The binary target matches anything, so don't return it when + searching. Don't match the plugin target if we have another + alternative since we want to properly set the input format + before allowing a plugin to claim the file. Also, don't + check the default target twice. */ if (*target == &binary_vec - || (!abfd->target_defaulted && *target == save_targ) - || (*target)->match_priority > best_match) +#if BFD_SUPPORTS_PLUGINS + || (match_count != 0 && *target == &plugin_vec) +#endif + || (!abfd->target_defaulted && *target == save_targ)) continue; /* If we already tried a match, the bfd is modified and may have sections attached, which will confuse the next _bfd_check_format call. */ - bfd_reinit (abfd); + bfd_reinit (abfd, initial_section_id); /* Change BFD's target temporarily. */ abfd->xvec = *target; @@ -305,6 +322,16 @@ bfd_check_format_matches (bfd *abfd, bfd_format format, char ***matching) temp = BFD_SEND_FMT (abfd, _bfd_check_format, (abfd)); if (temp) { + int match_priority = temp->match_priority; +#if BFD_SUPPORTS_PLUGINS + /* If this object can be handled by a plugin, give that the + lowest priority; objects both handled by a plugin and + with an underlying object format will be claimed + separately by the plugin. */ + if (*target == &plugin_vec) + match_priority = (*target)->match_priority; +#endif + match_targ = temp; if (preserve.marker != NULL) bfd_preserve_finish (abfd, &preserve); @@ -313,9 +340,6 @@ bfd_check_format_matches (bfd *abfd, bfd_format format, char ***matching) || (bfd_has_map (abfd) && bfd_get_error () != bfd_error_wrong_object_format)) { - /* This format checks out as ok! */ - right_targ = temp; - /* If this is the default target, accept it, even if other targets might match. People who want those other targets have to set the GNUTARGET variable. */ @@ -326,12 +350,17 @@ bfd_check_format_matches (bfd *abfd, bfd_format format, char ***matching) matching_vector[match_count] = temp; match_count++; - if (temp->match_priority < best_match) + if (match_priority < best_match) { - best_match = temp->match_priority; + best_match = match_priority; best_count = 0; } - best_count++; + if (match_priority <= best_match) + { + /* This format checks out as ok! */ + right_targ = temp; + best_count++; + } } else { @@ -430,7 +459,7 @@ bfd_check_format_matches (bfd *abfd, bfd_format format, char ***matching) state (except possibly for XVEC). */ if (match_targ != right_targ) { - bfd_reinit (abfd); + bfd_reinit (abfd, initial_section_id); if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0) goto err_ret; match_targ = BFD_SEND_FMT (abfd, _bfd_check_format, (abfd));