aboutsummaryrefslogtreecommitdiff
path: root/bfd
diff options
context:
space:
mode:
Diffstat (limited to 'bfd')
-rw-r--r--bfd/bfd-in2.h7
-rw-r--r--bfd/coffcode.h4
-rw-r--r--bfd/elf32-ppc.c44
-rw-r--r--bfd/elf64-ppc.c40
-rw-r--r--bfd/format.c84
-rw-r--r--bfd/version.h2
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@