diff options
Diffstat (limited to 'bfd/format.c')
-rw-r--r-- | bfd/format.c | 144 |
1 files changed, 53 insertions, 91 deletions
diff --git a/bfd/format.c b/bfd/format.c index f3a0774..bd9fa8d 100644 --- a/bfd/format.c +++ b/bfd/format.c @@ -56,19 +56,16 @@ extern const size_t _bfd_target_vector_entries; /* FUNCTION - bfd_check_format_lto + bfd_check_format SYNOPSIS - bool bfd_check_format_lto (bfd *abfd, bfd_format format, - bool lto_sections_removed); + bool bfd_check_format (bfd *abfd, bfd_format format); DESCRIPTION Verify if the file attached to the BFD @var{abfd} is compatible with the format @var{format} (i.e., one of <<bfd_object>>, <<bfd_archive>> or <<bfd_core>>). - If LTO_SECTION_REMOVED is true, ignore plugin target. - If the BFD has been set to a specific target before the call, only the named target and format combination is checked. If the target has not been set, or has been set to @@ -103,30 +100,9 @@ DESCRIPTION */ bool -bfd_check_format_lto (bfd *abfd, bfd_format format, - bool lto_sections_removed) -{ - return bfd_check_format_matches_lto (abfd, format, NULL, - lto_sections_removed); -} - - -/* -FUNCTION - bfd_check_format - -SYNOPSIS - bool bfd_check_format (bfd *abfd, bfd_format format); - -DESCRIPTION - Similar to bfd_check_format_plugin, except plugin target isn't - ignored. -*/ - -bool bfd_check_format (bfd *abfd, bfd_format format) { - return bfd_check_format_matches_lto (abfd, format, NULL, false); + return bfd_check_format_matches (abfd, format, NULL); } struct bfd_preserve @@ -413,6 +389,11 @@ bfd_set_lto_type (bfd *abfd ATTRIBUTE_UNUSED) abfd->object_only_section = sec; break; } + else if (strcmp (sec->name, ".llvm.lto") == 0) + { + type = lto_fat_ir_object; + break; + } else if (lsection.major_version == 0 && startswith (sec->name, ".gnu.lto_.lto.") && bfd_get_section_contents (abfd, sec, &lsection, 0, @@ -431,36 +412,32 @@ bfd_set_lto_type (bfd *abfd ATTRIBUTE_UNUSED) /* FUNCTION - bfd_check_format_matches_lto + bfd_check_format_matches SYNOPSIS - bool bfd_check_format_matches_lto - (bfd *abfd, bfd_format format, char ***matching, - bool lto_sections_removed); + bool bfd_check_format_matches + (bfd *abfd, bfd_format format, char ***matching); DESCRIPTION Like <<bfd_check_format>>, except when it returns FALSE with - <<bfd_errno>> set to <<bfd_error_file_ambiguously_recognized>>. In that - case, if @var{matching} is not NULL, it will be filled in with - a NULL-terminated list of the names of the formats that matched, - allocated with <<malloc>>. + <<bfd_errno>> set to <<bfd_error_file_ambiguously_recognized>>. + In that case, if @var{matching} is not NULL, it will be filled + in with a NULL-terminated list of the names of the formats + that matched, allocated with <<malloc>>. Then the user may choose a format and try again. When done with the list that @var{matching} points to, the caller should free it. - - If LTO_SECTION_REMOVED is true, ignore plugin target. */ bool -bfd_check_format_matches_lto (bfd *abfd, bfd_format format, - char ***matching, - bool lto_sections_removed ATTRIBUTE_UNUSED) +bfd_check_format_matches (bfd *abfd, bfd_format format, char ***matching) { extern const bfd_target binary_vec; const bfd_target * const *target; const bfd_target **matching_vector = NULL; const bfd_target *save_targ, *right_targ, *ar_right_targ, *match_targ; + const bfd_target *fail_targ; int match_count, best_count, best_match; int ar_match_index; unsigned int initial_section_id = _bfd_section_id; @@ -481,10 +458,7 @@ bfd_check_format_matches_lto (bfd *abfd, bfd_format format, } if (abfd->format != bfd_unknown) - { - bfd_set_lto_type (abfd); - return abfd->format == format; - } + return abfd->format == format; if (matching != NULL || *bfd_associated_vector != NULL) { @@ -524,20 +498,34 @@ bfd_check_format_matches_lto (bfd *abfd, bfd_format format, if (!bfd_preserve_save (abfd, &preserve, NULL)) goto err_ret; - /* If the target type was explicitly specified, just check that target. - If LTO_SECTION_REMOVED is true, don't match the plugin target. */ + /* If the target type was explicitly specified, just check that target. */ + fail_targ = NULL; if (!abfd->target_defaulted #if BFD_SUPPORTS_PLUGINS - && (!lto_sections_removed || !bfd_plugin_target_p (abfd->xvec)) + && !(abfd->plugin_format == bfd_plugin_no + && bfd_plugin_target_p (save_targ)) #endif - ) + ) { if (bfd_seek (abfd, 0, SEEK_SET) != 0) /* rewind! */ goto err_ret; cleanup = BFD_SEND_FMT (abfd, _bfd_check_format, (abfd)); - if (cleanup) + /* When called from strip, don't treat archive member nor + standalone fat IR object as an IR object. For archive + member, it will be copied as an unknown object if the + plugin target is in use or it is a slim IR object. For + standalone fat IR object, it will be copied as non-IR + object. */ + if (cleanup +#if BFD_SUPPORTS_PLUGINS + && (!abfd->is_strip_input + || !bfd_plugin_target_p (abfd->xvec) + || (abfd->lto_type != lto_fat_ir_object + && abfd->my_archive == NULL)) +#endif + ) goto ok_ret; /* For a long time the code has dropped through to check all @@ -554,10 +542,10 @@ bfd_check_format_matches_lto (bfd *abfd, bfd_format format, target. */ if (format == bfd_archive && save_targ == &binary_vec) goto err_unrecog; + fail_targ = save_targ; } - /* Since the target type was defaulted, check them all in the hope - that one will be uniquely recognized. */ + /* Check all targets in the hope that one will be recognized. */ right_targ = NULL; ar_right_targ = NULL; match_targ = NULL; @@ -571,26 +559,26 @@ bfd_check_format_matches_lto (bfd *abfd, bfd_format format, void **high_water; /* 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 LTO_SECTION_REMOVED is - true, don't match the plugin target. */ + searching. Also, don't check the current target twice when + it has failed already. + Don't match the plugin target during linking if we have + another alternative since we want to properly set the input + format before allowing a plugin to claim the file. + Also as an optimisation don't match the plugin target when + abfd->plugin_format is set to bfd_plugin_no. (This occurs + when LTO sections have been stripped or when we have a + recursive call here from the plugin object_p via + bfd_plugin_get_symbols_in_object_only.) */ if (*target == &binary_vec + || *target == fail_targ #if BFD_SUPPORTS_PLUGINS - || ((lto_sections_removed || match_count != 0) + || (((abfd->is_linker_input && match_count != 0) + || abfd->plugin_format == bfd_plugin_no) && bfd_plugin_target_p (*target)) #endif - || (!abfd->target_defaulted && *target == save_targ)) + ) continue; -#if BFD_SUPPORTS_PLUGINS - /* If the plugin target is explicitly specified when a BFD file - is opened, don't check it twice. */ - if (bfd_plugin_specified_p () && bfd_plugin_target_p (*target)) - continue; -#endif - /* If we already tried a match, the bfd is modified and may have sections attached, which will confuse the next _bfd_check_format call. */ @@ -833,32 +821,6 @@ bfd_check_format_matches_lto (bfd *abfd, bfd_format format, /* FUNCTION - bfd_check_format_matches - -SYNOPSIS - bool bfd_check_format_matches - (bfd *abfd, bfd_format format, char ***matching); - -DESCRIPTION - Like <<bfd_check_format>>, except when it returns FALSE with - <<bfd_errno>> set to <<bfd_error_file_ambiguously_recognized>>. In that - case, if @var{matching} is not NULL, it will be filled in with - a NULL-terminated list of the names of the formats that matched, - allocated with <<malloc>>. - Then the user may choose a format and try again. - - When done with the list that @var{matching} points to, the caller - should free it. -*/ - -bool -bfd_check_format_matches (bfd *abfd, bfd_format format, char ***matching) -{ - return bfd_check_format_matches_lto (abfd, format, matching, false); -} - -/* -FUNCTION bfd_set_format SYNOPSIS |