[binutils-gdb] elflink.c: input object compatibility checks
Alan Modra via Binutils-cvs <[email protected]>
| Newsgroups | gmane.comp.gnu.binutils.cvs |
|---|---|
| Message-ID | <[email protected]> |
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=d77630b6d6e9fae8cf74e32816cb52e7b2ffcbcb commit d77630b6d6e9fae8cf74e32816cb52e7b2ffcbcb Author: Alan Modra <[email protected]> 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. */