[binutils-gdb] elflink.c: input object compatibility checks
Alan Modra
amodra@sourceware.org
Mon Aug 17 01:24:24 GMT 2026
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=d77630b6d6e9fae8cf74e32816cb52e7b2ffcbcb
commit d77630b6d6e9fae8cf74e32816cb52e7b2ffcbcb
Author: Alan Modra <amodra@gmail.com>
Date: Thu Aug 6 11:15:12 2026 +0930
elflink.c: input object compatibility checks
A number of places in elflink.c need to check that the input object
relocs are compatible with the output. Extract those checks into a
new function. Note that the seeming extra condition on sec_info_type
in _bfd_elf_link_iterate_on_relocs is just an early out, as
--just-symbols objects will have all section's output_section set to
the absolute section, and that is checked in the loop.
* elflink.c (compatible_format): New function.
(_bfd_elf_link_create_dynstrtab): Use compatible_format.
(_bfd_elf_link_iterate_on_relocs, bfd_elf_gc_sections): Likewise.
(elf_gc_sweep): Likewise. Lose unused obfd param.
Diff:
---
bfd/elflink.c | 73 ++++++++++++++++++++++++-----------------------------------
1 file changed, 30 insertions(+), 43 deletions(-)
diff --git a/bfd/elflink.c b/bfd/elflink.c
index cc29b99ba56..bee57bcdff4 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -282,7 +282,24 @@ _bfd_elf_create_got_section (bfd *dynobj, struct bfd_link_info *info)
return true;
}
-
+
+/* Return true if IBFD is compatible with the output. Used for example
+ to decide whether an object file can hold linker generated dynamic
+ sections, and whether object file relocations can be examined by
+ check_relocs (for plt/got/dyn reloc generation). */
+
+static bool
+compatible_format (struct bfd_link_info *info, bfd *ibfd)
+{
+ return (bfd_get_flavour (ibfd) == bfd_target_elf_flavour
+ && is_elf_hash_table (info->hash)
+ && elf_object_id (ibfd) == elf_hash_table_id (elf_hash_table (info))
+ && !(ibfd->sections != NULL
+ && ibfd->sections->sec_info_type == SEC_INFO_TYPE_JUST_SYMS)
+ && (get_elf_backend_data (ibfd)
+ ->relocs_compatible (ibfd->xvec, info->output_bfd->xvec)));
+}
+
/* Create a strtab to hold the dynamic symbol names. */
static bool
_bfd_elf_link_create_dynstrtab (bfd *abfd, struct bfd_link_info *info)
@@ -299,14 +316,10 @@ _bfd_elf_link_create_dynstrtab (bfd *abfd, struct bfd_link_info *info)
if ((abfd->flags & (DYNAMIC | BFD_PLUGIN)) != 0)
{
bfd *ibfd;
- asection *s;
for (ibfd = info->input_bfds; ibfd; ibfd = ibfd->link.next)
if ((ibfd->flags
& (DYNAMIC | BFD_LINKER_CREATED | BFD_PLUGIN)) == 0
- && bfd_get_flavour (ibfd) == bfd_target_elf_flavour
- && elf_object_id (ibfd) == elf_hash_table_id (hash_table)
- && !((s = ibfd->sections) != NULL
- && s->sec_info_type == SEC_INFO_TYPE_JUST_SYMS))
+ && compatible_format (info, ibfd))
{
abfd = ibfd;
break;
@@ -4270,9 +4283,6 @@ _bfd_elf_link_iterate_on_relocs
bool (*action) (bfd *, struct bfd_link_info *, asection *,
const Elf_Internal_Rela *))
{
- elf_backend_data *bed = get_elf_backend_data (abfd);
- struct elf_link_hash_table *htab = elf_hash_table (info);
-
/* If this object is the same format as the output object, and it is
not a shared library, then let the backend look through the
relocs.
@@ -4291,13 +4301,9 @@ _bfd_elf_link_iterate_on_relocs
I have no idea how to handle linking PIC code into a file of a
different format. It probably can't be done. */
if ((abfd->flags & DYNAMIC) == 0
- && is_elf_hash_table (&htab->root)
- && elf_object_id (abfd) == elf_hash_table_id (htab)
- && (*bed->relocs_compatible) (abfd->xvec, info->output_bfd->xvec))
+ && compatible_format (info, abfd))
{
- asection *o;
-
- for (o = abfd->sections; o != NULL; o = o->next)
+ for (asection *o = abfd->sections; o != NULL; o = o->next)
{
Elf_Internal_Rela *internal_relocs;
bool ok;
@@ -14384,24 +14390,14 @@ _bfd_elf_gc_mark_extra_sections (struct bfd_link_info *info,
}
static bool
-elf_gc_sweep (bfd *obfd, struct bfd_link_info *info)
+elf_gc_sweep (struct bfd_link_info *info)
{
- bfd *sub;
- elf_backend_data *obed = get_elf_backend_data (obfd);
-
- for (sub = info->input_bfds; sub != NULL; sub = sub->link.next)
+ for (bfd *sub = info->input_bfds; sub != NULL; sub = sub->link.next)
{
- asection *o;
-
- if (bfd_get_flavour (sub) != bfd_target_elf_flavour
- || elf_object_id (sub) != elf_hash_table_id (elf_hash_table (info))
- || !obed->relocs_compatible (sub->xvec, obfd->xvec))
- continue;
- o = sub->sections;
- if (o == NULL || o->sec_info_type == SEC_INFO_TYPE_JUST_SYMS)
+ if (!compatible_format (info, sub))
continue;
- for (o = sub->sections; o != NULL; o = o->next)
+ for (asection *o = sub->sections; o != NULL; o = o->next)
{
/* When any section in a section group is kept, we keep all
sections in the section group. If the first member of
@@ -14648,7 +14644,6 @@ bool
bfd_elf_gc_sections (bfd *obfd, struct bfd_link_info *info)
{
bool ok = true;
- bfd *sub;
elf_gc_mark_hook_fn gc_mark_hook;
elf_backend_data *obed = get_elf_backend_data (obfd);
struct elf_link_hash_table *htab;
@@ -14666,7 +14661,7 @@ bfd_elf_gc_sections (bfd *obfd, struct bfd_link_info *info)
/* Try to parse each bfd's .eh_frame section. Point elf_eh_frame_section
at the .eh_frame section if we can mark the FDEs individually. */
- for (sub = info->input_bfds;
+ for (bfd *sub = info->input_bfds;
info->eh_frame_hdr_type != COMPACT_EH_HDR && sub != NULL;
sub = sub->link.next)
{
@@ -14724,24 +14719,16 @@ bfd_elf_gc_sections (bfd *obfd, struct bfd_link_info *info)
/* Grovel through relocs to find out who stays ... */
gc_mark_hook = obed->gc_mark_hook;
- for (sub = info->input_bfds; sub != NULL; sub = sub->link.next)
+ for (bfd *sub = info->input_bfds; sub != NULL; sub = sub->link.next)
{
- asection *o;
-
- if (bfd_get_flavour (sub) != bfd_target_elf_flavour
- || elf_object_id (sub) != elf_hash_table_id (htab)
- || !obed->relocs_compatible (sub->xvec, obfd->xvec))
- continue;
-
- o = sub->sections;
- if (o == NULL || o->sec_info_type == SEC_INFO_TYPE_JUST_SYMS)
+ if (!compatible_format (info, sub))
continue;
/* Start at sections marked with SEC_KEEP (ref _bfd_elf_gc_keep).
Also treat note sections as a root, if the section is not part
of a group. We must keep all PREINIT_ARRAY, INIT_ARRAY as
well as FINI_ARRAY sections for ld -r. */
- for (o = sub->sections; o != NULL; o = o->next)
+ for (asection *o = sub->sections; o != NULL; o = o->next)
if (!o->gc_mark
&& (o->flags & SEC_EXCLUDE) == 0
&& ((o->flags & SEC_KEEP) != 0
@@ -14768,7 +14755,7 @@ bfd_elf_gc_sections (bfd *obfd, struct bfd_link_info *info)
return false;
/* ... and mark SEC_EXCLUDE for those that go. */
- return elf_gc_sweep (obfd, info);
+ return elf_gc_sweep (info);
}
/* Called from check_relocs to record the existence of a VTINHERIT reloc. */
More information about the Binutils-cvs
mailing list