diff options
Diffstat (limited to 'bfd')
-rw-r--r-- | bfd/bfd-in2.h | 7 | ||||
-rw-r--r-- | bfd/coffcode.h | 4 | ||||
-rw-r--r-- | bfd/elf32-ppc.c | 44 | ||||
-rw-r--r-- | bfd/elf64-ppc.c | 40 | ||||
-rw-r--r-- | bfd/format.c | 84 | ||||
-rw-r--r-- | bfd/version.h | 2 |
6 files changed, 120 insertions, 61 deletions
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h index b013ef9..2ff3e93 100644 --- a/bfd/bfd-in2.h +++ b/bfd/bfd-in2.h @@ -2903,8 +2903,15 @@ bool generic_core_file_matches_executable_p (bfd *core_bfd, bfd *exec_bfd); /* Extracted from format.c. */ +bool bfd_check_format_lto (bfd *abfd, bfd_format format, + bool lto_sections_removed); + bool bfd_check_format (bfd *abfd, bfd_format format); +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); diff --git a/bfd/coffcode.h b/bfd/coffcode.h index b81195d..a2ee036 100644 --- a/bfd/coffcode.h +++ b/bfd/coffcode.h @@ -909,7 +909,9 @@ fill_comdat_hash (bfd *abfd) if (! _bfd_coff_get_external_symbols (abfd)) return true; - esymstart = esym = (bfd_byte *) obj_coff_external_syms (abfd); + esymstart = esym = obj_coff_external_syms (abfd); + if (esym == NULL) + return true; esymend = esym + obj_raw_syment_count (abfd) * bfd_coff_symesz (abfd); for (struct internal_syment isym; diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c index 3fd9f28..1ed995b 100644 --- a/bfd/elf32-ppc.c +++ b/bfd/elf32-ppc.c @@ -53,6 +53,10 @@ static bfd_reloc_status_type ppc_elf_addr16_ha_reloc static bfd_reloc_status_type ppc_elf_unhandled_reloc (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **); +#ifndef ARRAY_SIZE +#define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0])) +#endif + /* Branch prediction bit for branch taken relocs. */ #define BRANCH_PREDICT_BIT 0x200000 /* Mask to set RA in memory instructions. */ @@ -702,13 +706,10 @@ ppc_elf_howto_init (void) { unsigned int i, type; - for (i = 0; - i < sizeof (ppc_elf_howto_raw) / sizeof (ppc_elf_howto_raw[0]); - i++) + for (i = 0; i < ARRAY_SIZE (ppc_elf_howto_raw); i++) { type = ppc_elf_howto_raw[i].type; - if (type >= (sizeof (ppc_elf_howto_table) - / sizeof (ppc_elf_howto_table[0]))) + if (type >= ARRAY_SIZE (ppc_elf_howto_table)) abort (); ppc_elf_howto_table[type] = &ppc_elf_howto_raw[i]; } @@ -870,9 +871,7 @@ ppc_elf_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, { unsigned int i; - for (i = 0; - i < sizeof (ppc_elf_howto_raw) / sizeof (ppc_elf_howto_raw[0]); - i++) + for (i = 0; i < ARRAY_SIZE (ppc_elf_howto_raw); i++) if (ppc_elf_howto_raw[i].name != NULL && strcasecmp (ppc_elf_howto_raw[i].name, r_name) == 0) return &ppc_elf_howto_raw[i]; @@ -894,7 +893,8 @@ ppc_elf_info_to_howto (bfd *abfd, ppc_elf_howto_init (); r_type = ELF32_R_TYPE (dst->r_info); - if (r_type >= R_PPC_max) + if (r_type >= ARRAY_SIZE (ppc_elf_howto_table) + || ppc_elf_howto_table[r_type] == NULL) { /* xgettext:c-format */ _bfd_error_handler (_("%pB: unsupported relocation type %#x"), @@ -904,19 +904,6 @@ ppc_elf_info_to_howto (bfd *abfd, } cache_ptr->howto = ppc_elf_howto_table[r_type]; - - /* Just because the above assert didn't trigger doesn't mean that - ELF32_R_TYPE (dst->r_info) is necessarily a valid relocation. */ - if (cache_ptr->howto == NULL) - { - /* xgettext:c-format */ - _bfd_error_handler (_("%pB: unsupported relocation type %#x"), - abfd, r_type); - bfd_set_error (bfd_error_bad_value); - - return false; - } - return true; } @@ -7088,12 +7075,11 @@ ppc_elf_relocate_section (bfd *output_bfd, /* For relocs against symbols from removed linkonce sections, or sections discarded by a linker script, we just want the section contents zeroed. Avoid any special processing. */ - howto = NULL; - if (r_type < R_PPC_max) - howto = ppc_elf_howto_table[r_type]; - - _bfd_clear_contents (howto, input_bfd, input_section, - contents, rel->r_offset); + if (r_type < ARRAY_SIZE (ppc_elf_howto_table) + && ppc_elf_howto_table[r_type] != NULL) + _bfd_clear_contents (ppc_elf_howto_table[r_type], + input_bfd, input_section, + contents, rel->r_offset); wrel->r_offset = rel->r_offset; wrel->r_info = 0; wrel->r_addend = 0; @@ -7653,7 +7639,7 @@ ppc_elf_relocate_section (bfd *output_bfd, addend = rel->r_addend; save_unresolved_reloc = unresolved_reloc; howto = NULL; - if (r_type < R_PPC_max) + if (r_type < ARRAY_SIZE (ppc_elf_howto_table)) howto = ppc_elf_howto_table[r_type]; tls_type = 0; diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c index e6c90a6..7868063 100644 --- a/bfd/elf64-ppc.c +++ b/bfd/elf64-ppc.c @@ -1379,7 +1379,8 @@ ppc64_elf_info_to_howto (bfd *abfd, arelent *cache_ptr, ppc_howto_init (); type = ELF64_R_TYPE (dst->r_info); - if (type >= ARRAY_SIZE (ppc64_elf_howto_table)) + if (type >= ARRAY_SIZE (ppc64_elf_howto_table) + || ppc64_elf_howto_table[type] == NULL) { /* xgettext:c-format */ _bfd_error_handler (_("%pB: unsupported relocation type %#x"), @@ -1388,15 +1389,6 @@ ppc64_elf_info_to_howto (bfd *abfd, arelent *cache_ptr, return false; } cache_ptr->howto = ppc64_elf_howto_table[type]; - if (cache_ptr->howto == NULL || cache_ptr->howto->name == NULL) - { - /* xgettext:c-format */ - _bfd_error_handler (_("%pB: unsupported relocation type %#x"), - abfd, type); - bfd_set_error (bfd_error_bad_value); - return false; - } - return true; } @@ -5104,7 +5096,7 @@ ppc64_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, if (!ppc64_elf_howto_table[R_PPC64_ADDR32]) ppc_howto_init (); /* xgettext:c-format */ - info->callbacks->einfo (_("%H: %s reloc unsupported " + info->callbacks->einfo (_("%H: %s unsupported " "in shared libraries and PIEs\n"), abfd, sec, rel->r_offset, ppc64_elf_howto_table[r_type]->name); @@ -5274,7 +5266,7 @@ ppc64_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, if (ppc64_sec->sec_type != sec_toc || rel->r_offset % 8 != 0) { - info->callbacks->einfo (_("%H: %s reloc unsupported here\n"), + info->callbacks->einfo (_("%H: %s unsupported here\n"), abfd, sec, rel->r_offset, ppc64_elf_howto_table[r_type]->name); bfd_set_error (bfd_error_bad_value); @@ -15685,9 +15677,11 @@ ppc64_elf_relocate_section (bfd *output_bfd, if (sec != NULL && discarded_section (sec)) { - _bfd_clear_contents (ppc64_elf_howto_table[r_type], - input_bfd, input_section, - contents, rel->r_offset); + if (r_type < ARRAY_SIZE (ppc64_elf_howto_table) + && ppc64_elf_howto_table[r_type] != NULL) + _bfd_clear_contents (ppc64_elf_howto_table[r_type], + input_bfd, input_section, + contents, rel->r_offset); wrel->r_offset = rel->r_offset; wrel->r_info = 0; wrel->r_addend = 0; @@ -15750,6 +15744,8 @@ ppc64_elf_relocate_section (bfd *output_bfd, relocs are used with non-tls syms. */ if (r_symndx != STN_UNDEF && r_type != R_PPC64_NONE + && r_type < ARRAY_SIZE (ppc64_elf_howto_table) + && ppc64_elf_howto_table[r_type] != NULL && (h == NULL || h->elf.root.type == bfd_link_hash_defined || h->elf.root.type == bfd_link_hash_defweak) @@ -16865,9 +16861,15 @@ ppc64_elf_relocate_section (bfd *output_bfd, switch (r_type) { default: - /* xgettext:c-format */ - _bfd_error_handler (_("%pB: %s unsupported"), - input_bfd, ppc64_elf_howto_table[r_type]->name); + if (r_type < ARRAY_SIZE (ppc64_elf_howto_table) + && ppc64_elf_howto_table[r_type] != NULL) + /* xgettext:c-format */ + _bfd_error_handler (_("%pB: %s unsupported"), + input_bfd, ppc64_elf_howto_table[r_type]->name); + else + /* xgettext:c-format */ + _bfd_error_handler (_("%pB: unsupported relocation type %#x"), + input_bfd, r_type); bfd_set_error (bfd_error_bad_value); ret = false; @@ -17909,7 +17911,7 @@ ppc64_elf_relocate_section (bfd *output_bfd, /* Dynamic relocs are not propagated for SEC_DEBUGGING sections because such sections are not SEC_ALLOC and thus ld.so will not process them. */ - howto = ppc64_elf_howto_table[(int) r_type]; + howto = ppc64_elf_howto_table[r_type]; if (unresolved_reloc && !((input_section->flags & SEC_DEBUGGING) != 0 && h->elf.def_dynamic) diff --git a/bfd/format.c b/bfd/format.c index a909b70..f3a0774 100644 --- a/bfd/format.c +++ b/bfd/format.c @@ -56,16 +56,19 @@ extern const size_t _bfd_target_vector_entries; /* FUNCTION - bfd_check_format + bfd_check_format_lto SYNOPSIS - bool bfd_check_format (bfd *abfd, bfd_format format); + bool bfd_check_format_lto (bfd *abfd, bfd_format format, + bool lto_sections_removed); 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 @@ -100,9 +103,30 @@ 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 (abfd, format, NULL); + return bfd_check_format_matches_lto (abfd, format, NULL, false); } struct bfd_preserve @@ -407,11 +431,12 @@ bfd_set_lto_type (bfd *abfd ATTRIBUTE_UNUSED) /* FUNCTION - bfd_check_format_matches + bfd_check_format_matches_lto SYNOPSIS - bool bfd_check_format_matches - (bfd *abfd, bfd_format format, char ***matching); + bool bfd_check_format_matches_lto + (bfd *abfd, bfd_format format, char ***matching, + bool lto_sections_removed); DESCRIPTION Like <<bfd_check_format>>, except when it returns FALSE with @@ -423,10 +448,14 @@ DESCRIPTION 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 (bfd *abfd, bfd_format format, char ***matching) +bfd_check_format_matches_lto (bfd *abfd, bfd_format format, + char ***matching, + bool lto_sections_removed ATTRIBUTE_UNUSED) { extern const bfd_target binary_vec; const bfd_target * const *target; @@ -495,8 +524,13 @@ bfd_check_format_matches (bfd *abfd, bfd_format format, char ***matching) if (!bfd_preserve_save (abfd, &preserve, NULL)) goto err_ret; - /* If the target type was explicitly specified, just check that target. */ - if (!abfd->target_defaulted) + /* If the target type was explicitly specified, just check that target. + If LTO_SECTION_REMOVED is true, don't match the plugin target. */ + if (!abfd->target_defaulted +#if BFD_SUPPORTS_PLUGINS + && (!lto_sections_removed || !bfd_plugin_target_p (abfd->xvec)) +#endif + ) { if (bfd_seek (abfd, 0, SEEK_SET) != 0) /* rewind! */ goto err_ret; @@ -540,10 +574,12 @@ bfd_check_format_matches (bfd *abfd, bfd_format format, char ***matching) 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. */ + check the default target twice. If LTO_SECTION_REMOVED is + true, don't match the plugin target. */ if (*target == &binary_vec #if BFD_SUPPORTS_PLUGINS - || (match_count != 0 && bfd_plugin_target_p (*target)) + || ((lto_sections_removed || match_count != 0) + && bfd_plugin_target_p (*target)) #endif || (!abfd->target_defaulted && *target == save_targ)) continue; @@ -797,6 +833,32 @@ bfd_check_format_matches (bfd *abfd, bfd_format format, char ***matching) /* 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 diff --git a/bfd/version.h b/bfd/version.h index 7573409..c4f5e1b 100644 --- a/bfd/version.h +++ b/bfd/version.h @@ -16,7 +16,7 @@ In releases, the date is not included in either version strings or sonames. */ -#define BFD_VERSION_DATE 20250724 +#define BFD_VERSION_DATE 20250729 #define BFD_VERSION @bfd_version@ #define BFD_VERSION_STRING @bfd_version_package@ @bfd_version_string@ #define REPORT_BUGS_TO @report_bugs_to@ |