From: Alan Modra Date: Thu, 30 Nov 2017 09:16:17 +0000 (+1030) Subject: readonly_dynrelocs X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=63c1f59d6655;p=binutils-gdb.git readonly_dynrelocs In early October, HJ Lu added support for a number of targets to "Dump dynamic relocation in read-only section with minfo". This extends that support to more targets, displays the symbol involved, and splits the existing function that sets TEXTREL into a "readonly_dynrelocs" and "maybe_set_textrel" function. I'll need "readonly_dynrelocs" if I ever get around to fixing "pr22374 function pointer initialization" fails. am33_2.0, arc, bfin, hppa64, mn10300, and nios2 fail to mark a binary needing text relocations with DT_TEXTREL. That's not good. xtensa also fails to do so but complains about "dangerous relocation: dynamic relocation in read-only section" so I reckon that is fine and have marked the test as an xfail. The other targets need maintainer attention. Curiously, the map file dump wasn't added for x86, so the map test currently fail on x86. It also fails on alpha, am33_2.0, arc, bfin, hppa64, ia64, m68k, mips, mn10300, nios2, score and vax. cris complains with "tmpdir/textrel.o, section .rodata: relocation R_CRIS_32 should not be used in a shared object; recompile with -fPIC" so I've marked it as an xfail. bfd/ * elf32-hppa.c (maybe_set_textrel): Print symbol for map file output. * elf32-ppc.c (maybe_set_textrel): Likewise. * elf64-ppc.c (maybe_set_textrel): Likewise. * elf32-arm.c (readonly_dynrelocs): New function. (maybe_set_textrel): New function, replacing.. (elf32_arm_readonly_dynrelocs): ..this. * elf32-lm32.c (readonly_dynrelocs): New function. (maybe_set_textrel): New function, replacing old version of.. (readonly_dynrelocs): ..this. * elf32-m32r.c (readonly_dynrelocs): New function. (maybe_set_textrel): New function, replacing old version of.. (readonly_dynrelocs): ..this. * elf32-metag.c (readonly_dynrelocs): New function. (maybe_set_textrel): New function, replacing old version of.. (readonly_dynrelocs): ..this. * elf32-nds32.c: Delete unnecessary forward declarations. (readonly_dynrelocs): New function. (maybe_set_textrel): New function, replacing old version of.. (readonly_dynrelocs): ..this. * elf32-or1k.c (readonly_dynrelocs): New function. (maybe_set_textrel): New function, replacing old version of.. (readonly_dynrelocs): ..this. * elf32-s390.c (readonly_dynrelocs): New function. (maybe_set_textrel): New function, replacing old version of.. (readonly_dynrelocs): ..this. * elf32-sh.c (readonly_dynrelocs): New function. (maybe_set_textrel): New function, replacing old version of.. (readonly_dynrelocs): ..this. * elf32-tic6x.c (readonly_dynrelocs): New function. (maybe_set_textrel): New function, replacing.. (elf32_tic6x_readonly_dynrelocs): ..this. * elf32-tilepro.c (readonly_dynrelocs): New function. (maybe_set_textrel): New function, replacing old version of.. (readonly_dynrelocs): ..this. * elf64-s390.c (readonly_dynrelocs): New function. (maybe_set_textrel): New function, replacing old version of.. (readonly_dynrelocs): ..this. * elfnn-aarch64.c (readonly_dynrelocs): New function. (maybe_set_textrel): New function, replacing.. (aarch64_readonly_readonly_dynrelocs): ..this. * elfnn-riscv.c (readonly_dynrelocs): New function. (maybe_set_textrel): New function, replacing old version of.. (readonly_dynrelocs): ..this. * elfxx-sparc.c (readonly_dynrelocs): New function. (maybe_set_textrel): New function, replacing old version of.. (readonly_dynrelocs): ..this. * elfxx-tilegx.c (readonly_dynrelocs): New function. (maybe_set_textrel): New function, replacing old version of.. (readonly_dynrelocs): ..this. ld/ * testsuite/ld-elf/shared.exp: Run new textrel tests. * testsuite/ld-elf/textrel.map: New file. * testsuite/ld-elf/textrel.rd: New file. * testsuite/ld-elf/textrel.s: New file. * testsuite/ld-elf/textrel.warn: New file. --- diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 1b2db461dd5..ae289706673 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,55 @@ +2017-12-01 Alan Modra + + * elf32-hppa.c (maybe_set_textrel): Print symbol for map file output. + * elf32-ppc.c (maybe_set_textrel): Likewise. + * elf64-ppc.c (maybe_set_textrel): Likewise. + * elf32-arm.c (readonly_dynrelocs): New function. + (maybe_set_textrel): New function, replacing.. + (elf32_arm_readonly_dynrelocs): ..this. + * elf32-lm32.c (readonly_dynrelocs): New function. + (maybe_set_textrel): New function, replacing old version of.. + (readonly_dynrelocs): ..this. + * elf32-m32r.c (readonly_dynrelocs): New function. + (maybe_set_textrel): New function, replacing old version of.. + (readonly_dynrelocs): ..this. + * elf32-metag.c (readonly_dynrelocs): New function. + (maybe_set_textrel): New function, replacing old version of.. + (readonly_dynrelocs): ..this. + * elf32-nds32.c: Delete unnecessary forward declarations. + (readonly_dynrelocs): New function. + (maybe_set_textrel): New function, replacing old version of.. + (readonly_dynrelocs): ..this. + * elf32-or1k.c (readonly_dynrelocs): New function. + (maybe_set_textrel): New function, replacing old version of.. + (readonly_dynrelocs): ..this. + * elf32-s390.c (readonly_dynrelocs): New function. + (maybe_set_textrel): New function, replacing old version of.. + (readonly_dynrelocs): ..this. + * elf32-sh.c (readonly_dynrelocs): New function. + (maybe_set_textrel): New function, replacing old version of.. + (readonly_dynrelocs): ..this. + * elf32-tic6x.c (readonly_dynrelocs): New function. + (maybe_set_textrel): New function, replacing.. + (elf32_tic6x_readonly_dynrelocs): ..this. + * elf32-tilepro.c (readonly_dynrelocs): New function. + (maybe_set_textrel): New function, replacing old version of.. + (readonly_dynrelocs): ..this. + * elf64-s390.c (readonly_dynrelocs): New function. + (maybe_set_textrel): New function, replacing old version of.. + (readonly_dynrelocs): ..this. + * elfnn-aarch64.c (readonly_dynrelocs): New function. + (maybe_set_textrel): New function, replacing.. + (aarch64_readonly_readonly_dynrelocs): ..this. + * elfnn-riscv.c (readonly_dynrelocs): New function. + (maybe_set_textrel): New function, replacing old version of.. + (readonly_dynrelocs): ..this. + * elfxx-sparc.c (readonly_dynrelocs): New function. + (maybe_set_textrel): New function, replacing old version of.. + (readonly_dynrelocs): ..this. + * elfxx-tilegx.c (readonly_dynrelocs): New function. + (maybe_set_textrel): New function, replacing old version of.. + (readonly_dynrelocs): ..this. + 2017-12-01 Alan Modra PR 22533 diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c index bd0fee615c0..6f16e2df230 100644 --- a/bfd/elf32-arm.c +++ b/bfd/elf32-arm.c @@ -15091,6 +15091,23 @@ elf32_arm_find_inliner_info (bfd * abfd, return found; } +/* Find dynamic relocs for H that apply to read-only sections. */ + +static asection * +readonly_dynrelocs (struct elf_link_hash_entry *h) +{ + struct elf_dyn_relocs *p; + + for (p = elf32_arm_hash_entry (h)->dyn_relocs; p != NULL; p = p->next) + { + asection *s = p->sec->output_section; + + if (s != NULL && (s->flags & SEC_READONLY) != 0) + return p->sec; + } + return NULL; +} + /* Adjust a symbol defined by a dynamic object and referenced by a regular object. The current definition is in some section of the dynamic object, but we're not including those sections. We have to @@ -15598,28 +15615,29 @@ allocate_dynrelocs_for_symbol (struct elf_link_hash_entry *h, void * inf) return TRUE; } -/* Find any dynamic relocs that apply to read-only sections. */ +/* Set DF_TEXTREL if we find any dynamic relocs that apply to + read-only sections. */ static bfd_boolean -elf32_arm_readonly_dynrelocs (struct elf_link_hash_entry * h, void * inf) +maybe_set_textrel (struct elf_link_hash_entry *h, void *info_p) { - struct elf32_arm_link_hash_entry * eh; - struct elf_dyn_relocs * p; + asection *sec; - eh = (struct elf32_arm_link_hash_entry *) h; - for (p = eh->dyn_relocs; p != NULL; p = p->next) - { - asection *s = p->sec; + if (h->root.type == bfd_link_hash_indirect) + return TRUE; - if (s != NULL && (s->flags & SEC_READONLY) != 0) - { - struct bfd_link_info *info = (struct bfd_link_info *) inf; + sec = readonly_dynrelocs (h); + if (sec != NULL) + { + struct bfd_link_info *info = (struct bfd_link_info *) info_p; - info->flags |= DF_TEXTREL; + info->flags |= DF_TEXTREL; + info->callbacks->minfo + (_("%B: dynamic relocation against `%T' in read-only section `%A'\n"), + sec->owner, h->root.root.string, sec); - /* Not an error, just cut short the traversal. */ - return FALSE; - } + /* Not an error, just cut short the traversal. */ + return FALSE; } return TRUE; } @@ -16016,8 +16034,7 @@ elf32_arm_size_dynamic_sections (bfd * output_bfd ATTRIBUTE_UNUSED, /* If any dynamic relocs apply to a read-only section, then we need a DT_TEXTREL entry. */ if ((info->flags & DF_TEXTREL) == 0) - elf_link_hash_traverse (& htab->root, elf32_arm_readonly_dynrelocs, - info); + elf_link_hash_traverse (&htab->root, maybe_set_textrel, info); if ((info->flags & DF_TEXTREL) != 0) { diff --git a/bfd/elf32-hppa.c b/bfd/elf32-hppa.c index 3f71159531d..57d746eec26 100644 --- a/bfd/elf32-hppa.c +++ b/bfd/elf32-hppa.c @@ -2098,8 +2098,8 @@ maybe_set_textrel (struct elf_link_hash_entry *eh, void *inf) info->flags |= DF_TEXTREL; info->callbacks->minfo - (_("%B: dynamic relocation in read-only section `%A'\n"), - sec->owner, sec); + (_("%B: dynamic relocation against `%T' in read-only section `%A'\n"), + sec->owner, eh->root.root.string, sec); /* Not an error, just cut short the traversal. */ return FALSE; diff --git a/bfd/elf32-lm32.c b/bfd/elf32-lm32.c index e0286d6d521..35911d985e1 100644 --- a/bfd/elf32-lm32.c +++ b/bfd/elf32-lm32.c @@ -1643,6 +1643,24 @@ lm32_elf_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED, } } +/* Find dynamic relocs for H that apply to read-only sections. */ + +static asection * +readonly_dynrelocs (struct elf_link_hash_entry *h) +{ + struct elf_lm32_dyn_relocs *p; + struct elf_lm32_link_hash_entry *eh = (struct elf_lm32_link_hash_entry *) h; + + for (p = eh->dyn_relocs; p != NULL; p = p->next) + { + asection *s = p->sec->output_section; + + if (s != NULL && (s->flags & SEC_READONLY) != 0) + return p->sec; + } + return NULL; +} + /* Adjust a symbol defined by a dynamic object and referenced by a regular object. The current definition is in some section of the dynamic object, but we're not including those sections. We have to @@ -1972,28 +1990,29 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf) return TRUE; } -/* Find any dynamic relocs that apply to read-only sections. */ +/* Set DF_TEXTREL if we find any dynamic relocs that apply to + read-only sections. */ static bfd_boolean -readonly_dynrelocs (struct elf_link_hash_entry *h, void * inf) +maybe_set_textrel (struct elf_link_hash_entry *h, void *info_p) { - struct elf_lm32_link_hash_entry *eh; - struct elf_lm32_dyn_relocs *p; + asection *sec; - eh = (struct elf_lm32_link_hash_entry *) h; - for (p = eh->dyn_relocs; p != NULL; p = p->next) - { - asection *s = p->sec->output_section; + if (h->root.type == bfd_link_hash_indirect) + return TRUE; - if (s != NULL && (s->flags & SEC_READONLY) != 0) - { - struct bfd_link_info *info = (struct bfd_link_info *) inf; + sec = readonly_dynrelocs (h); + if (sec != NULL) + { + struct bfd_link_info *info = (struct bfd_link_info *) info_p; - info->flags |= DF_TEXTREL; + info->flags |= DF_TEXTREL; + info->callbacks->minfo + (_("%B: dynamic relocation against `%T' in read-only section `%A'\n"), + sec->owner, h->root.root.string, sec); - /* Not an error, just cut short the traversal. */ - return FALSE; - } + /* Not an error, just cut short the traversal. */ + return FALSE; } return TRUE; } @@ -2189,8 +2208,7 @@ lm32_elf_size_dynamic_sections (bfd *output_bfd, /* If any dynamic relocs apply to a read-only section, then we need a DT_TEXTREL entry. */ if ((info->flags & DF_TEXTREL) == 0) - elf_link_hash_traverse (&htab->root, readonly_dynrelocs, - info); + elf_link_hash_traverse (&htab->root, maybe_set_textrel, info); if ((info->flags & DF_TEXTREL) != 0) { diff --git a/bfd/elf32-m32r.c b/bfd/elf32-m32r.c index 9a7b5c3f9bb..94bd482131d 100644 --- a/bfd/elf32-m32r.c +++ b/bfd/elf32-m32r.c @@ -1757,6 +1757,24 @@ m32r_elf_copy_indirect_symbol (struct bfd_link_info *info, } +/* Find dynamic relocs for H that apply to read-only sections. */ + +static asection * +readonly_dynrelocs (struct elf_link_hash_entry *h) +{ + struct elf_m32r_dyn_relocs *p; + struct elf_m32r_link_hash_entry *eh = (struct elf_m32r_link_hash_entry *) h; + + for (p = eh->dyn_relocs; p != NULL; p = p->next) + { + asection *s = p->sec->output_section; + + if (s != NULL && (s->flags & SEC_READONLY) != 0) + return p->sec; + } + return NULL; +} + /* Adjust a symbol defined by a dynamic object and referenced by a regular object. The current definition is in some section of the dynamic object, but we're not including those sections. We have to @@ -2090,28 +2108,29 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf) return TRUE; } -/* Find any dynamic relocs that apply to read-only sections. */ +/* Set DF_TEXTREL if we find any dynamic relocs that apply to + read-only sections. */ static bfd_boolean -readonly_dynrelocs (struct elf_link_hash_entry *h, void * inf) +maybe_set_textrel (struct elf_link_hash_entry *h, void *info_p) { - struct elf_m32r_link_hash_entry *eh; - struct elf_m32r_dyn_relocs *p; + asection *sec; - eh = (struct elf_m32r_link_hash_entry *) h; - for (p = eh->dyn_relocs; p != NULL; p = p->next) - { - asection *s = p->sec->output_section; + if (h->root.type == bfd_link_hash_indirect) + return TRUE; - if (s != NULL && (s->flags & SEC_READONLY) != 0) - { - struct bfd_link_info *info = (struct bfd_link_info *) inf; + sec = readonly_dynrelocs (h); + if (sec != NULL) + { + struct bfd_link_info *info = (struct bfd_link_info *) info_p; - info->flags |= DF_TEXTREL; + info->flags |= DF_TEXTREL; + info->callbacks->minfo + (_("%B: dynamic relocation against `%T' in read-only section `%A'\n"), + sec->owner, h->root.root.string, sec); - /* Not an error, just cut short the traversal. */ - return FALSE; - } + /* Not an error, just cut short the traversal. */ + return FALSE; } return TRUE; } @@ -2311,8 +2330,7 @@ m32r_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, /* If any dynamic relocs apply to a read-only section, then we need a DT_TEXTREL entry. */ if ((info->flags & DF_TEXTREL) == 0) - elf_link_hash_traverse (&htab->root, readonly_dynrelocs, - info); + elf_link_hash_traverse (&htab->root, maybe_set_textrel, info); if ((info->flags & DF_TEXTREL) != 0) { diff --git a/bfd/elf32-metag.c b/bfd/elf32-metag.c index 3a80cb361a4..30c980e12cd 100644 --- a/bfd/elf32-metag.c +++ b/bfd/elf32-metag.c @@ -2452,6 +2452,23 @@ elf_metag_copy_indirect_symbol (struct bfd_link_info *info, _bfd_elf_link_hash_copy_indirect (info, eh_dir, eh_ind); } +/* Find dynamic relocs for H that apply to read-only sections. */ + +static asection * +readonly_dynrelocs (struct elf_link_hash_entry *h) +{ + struct elf_metag_dyn_reloc_entry *p; + + for (p = metag_elf_hash_entry (h)->dyn_relocs; p != NULL; p = p->hdh_next) + { + asection *s = p->sec->output_section; + + if (s != NULL && (s->flags & SEC_READONLY) != 0) + return p->sec; + } + return NULL; +} + /* Adjust a symbol defined by a dynamic object and referenced by a regular object. The current definition is in some section of the dynamic object, but we're not including those sections. We have to @@ -2779,31 +2796,29 @@ allocate_dynrelocs (struct elf_link_hash_entry *eh, void *inf) return TRUE; } -/* Find any dynamic relocs that apply to read-only sections. */ +/* Set DF_TEXTREL if we find any dynamic relocs that apply to + read-only sections. */ static bfd_boolean -readonly_dynrelocs (struct elf_link_hash_entry *eh, void *inf) +maybe_set_textrel (struct elf_link_hash_entry *h, void *info_p) { - struct elf_metag_link_hash_entry *hh; - struct elf_metag_dyn_reloc_entry *hdh_p; + asection *sec; - if (eh->root.type == bfd_link_hash_warning) - eh = (struct elf_link_hash_entry *) eh->root.u.i.link; + if (h->root.type == bfd_link_hash_indirect) + return TRUE; - hh = (struct elf_metag_link_hash_entry *) eh; - for (hdh_p = hh->dyn_relocs; hdh_p != NULL; hdh_p = hdh_p->hdh_next) + sec = readonly_dynrelocs (h); + if (sec != NULL) { - asection *s = hdh_p->sec->output_section; + struct bfd_link_info *info = (struct bfd_link_info *) info_p; - if (s != NULL && (s->flags & SEC_READONLY) != 0) - { - struct bfd_link_info *info = inf; - - info->flags |= DF_TEXTREL; + info->flags |= DF_TEXTREL; + info->callbacks->minfo + (_("%B: dynamic relocation against `%T' in read-only section `%A'\n"), + sec->owner, h->root.root.string, sec); - /* Not an error, just cut short the traversal. */ - return FALSE; - } + /* Not an error, just cut short the traversal. */ + return FALSE; } return TRUE; } @@ -3032,7 +3047,7 @@ elf_metag_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, /* If any dynamic relocs apply to a read-only section, then we need a DT_TEXTREL entry. */ if ((info->flags & DF_TEXTREL) == 0) - elf_link_hash_traverse (&htab->etab, readonly_dynrelocs, info); + elf_link_hash_traverse (&htab->etab, maybe_set_textrel, info); if ((info->flags & DF_TEXTREL) != 0) { diff --git a/bfd/elf32-nds32.c b/bfd/elf32-nds32.c index 32870eea3b3..65e430cee1e 100644 --- a/bfd/elf32-nds32.c +++ b/bfd/elf32-nds32.c @@ -56,56 +56,8 @@ static bfd_reloc_status_type nds32_elf_sda15_reloc static bfd_reloc_status_type nds32_elf_do_9_pcrel_reloc (bfd *, reloc_howto_type *, asection *, bfd_byte *, bfd_vma, asection *, bfd_vma, bfd_vma); -static void nds32_elf_relocate_hi20 - (bfd *, int, Elf_Internal_Rela *, Elf_Internal_Rela *, bfd_byte *, bfd_vma); -static reloc_howto_type *bfd_elf32_bfd_reloc_type_table_lookup - (enum elf_nds32_reloc_type); -static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup - (bfd *, bfd_reloc_code_real_type); - -/* Target hooks. */ -static void nds32_info_to_howto_rel - (bfd *, arelent *, Elf_Internal_Rela *dst); -static void nds32_info_to_howto - (bfd *, arelent *, Elf_Internal_Rela *dst); -static bfd_boolean nds32_elf_add_symbol_hook - (bfd *, struct bfd_link_info *, Elf_Internal_Sym *, const char **, - flagword *, asection **, bfd_vma *); -static bfd_boolean nds32_elf_relocate_section - (bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, - Elf_Internal_Rela *, Elf_Internal_Sym *, asection **); -static bfd_boolean nds32_elf_object_p (bfd *); -static void nds32_elf_final_write_processing (bfd *, bfd_boolean); -static bfd_boolean nds32_elf_set_private_flags (bfd *, flagword); -static bfd_boolean nds32_elf_merge_private_bfd_data - (bfd *, struct bfd_link_info *); -static bfd_boolean nds32_elf_print_private_bfd_data (bfd *, void *); -static bfd_boolean nds32_elf_check_relocs - (bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *); -static asection *nds32_elf_gc_mark_hook - (asection *, struct bfd_link_info *, Elf_Internal_Rela *, - struct elf_link_hash_entry *, Elf_Internal_Sym *); -static bfd_boolean nds32_elf_adjust_dynamic_symbol - (struct bfd_link_info *, struct elf_link_hash_entry *); -static bfd_boolean nds32_elf_size_dynamic_sections - (bfd *, struct bfd_link_info *); -static bfd_boolean nds32_elf_create_dynamic_sections - (bfd *, struct bfd_link_info *); -static bfd_boolean nds32_elf_finish_dynamic_sections - (bfd *, struct bfd_link_info *info); -static bfd_boolean nds32_elf_finish_dynamic_symbol - (bfd *, struct bfd_link_info *, struct elf_link_hash_entry *, - Elf_Internal_Sym *); -static bfd_boolean nds32_elf_mkobject (bfd *); /* Nds32 helper functions. */ -static bfd_reloc_status_type nds32_elf_final_sda_base - (bfd *, struct bfd_link_info *, bfd_vma *, bfd_boolean); -static bfd_boolean allocate_dynrelocs (struct elf_link_hash_entry *, void *); -static bfd_boolean readonly_dynrelocs (struct elf_link_hash_entry *, void *); -static Elf_Internal_Rela *find_relocs_at_address - (Elf_Internal_Rela *, Elf_Internal_Rela *, - Elf_Internal_Rela *, enum elf_nds32_reloc_type); static bfd_vma calculate_memory_address (bfd *, Elf_Internal_Rela *, Elf_Internal_Sym *, Elf_Internal_Shdr *); static int nds32_get_section_contents (bfd *, asection *, @@ -134,13 +86,6 @@ static bfd_boolean nds32_relax_fp_as_gp static bfd_boolean nds32_fag_remove_unused_fpbase (bfd *abfd, asection *sec, Elf_Internal_Rela *internal_relocs, Elf_Internal_Rela *irelend); -static bfd_byte * -nds32_elf_get_relocated_section_contents (bfd *abfd, - struct bfd_link_info *link_info, - struct bfd_link_order *link_order, - bfd_byte *data, - bfd_boolean relocatable, - asymbol **symbols); enum { @@ -3561,6 +3506,22 @@ nds32_elf_copy_indirect_symbol (struct bfd_link_info *info, _bfd_elf_link_hash_copy_indirect (info, dir, ind); } +/* Find dynamic relocs for H that apply to read-only sections. */ + +static asection * +readonly_dynrelocs (struct elf_link_hash_entry *h) +{ + struct elf_nds32_dyn_relocs *p; + + for (p = elf32_nds32_hash_entry (h)->dyn_relocs; p != NULL; p = p->next) + { + asection *s = p->sec->output_section; + + if (s != NULL && (s->flags & SEC_READONLY) != 0) + return p->sec; + } + return NULL; +} /* Adjust a symbol defined by a dynamic object and referenced by a regular object. The current definition is in some section of the @@ -3893,31 +3854,29 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) return TRUE; } -/* Find any dynamic relocs that apply to read-only sections. */ +/* Set DF_TEXTREL if we find any dynamic relocs that apply to + read-only sections. */ static bfd_boolean -readonly_dynrelocs (struct elf_link_hash_entry *h, void *inf) +maybe_set_textrel (struct elf_link_hash_entry *h, void *info_p) { - struct elf_nds32_link_hash_entry *eh; - struct elf_nds32_dyn_relocs *p; + asection *sec; - if (h->root.type == bfd_link_hash_warning) - h = (struct elf_link_hash_entry *) h->root.u.i.link; + if (h->root.type == bfd_link_hash_indirect) + return TRUE; - eh = (struct elf_nds32_link_hash_entry *) h; - for (p = eh->dyn_relocs; p != NULL; p = p->next) + sec = readonly_dynrelocs (h); + if (sec != NULL) { - asection *s = p->sec->output_section; - - if (s != NULL && (s->flags & SEC_READONLY) != 0) - { - struct bfd_link_info *info = (struct bfd_link_info *) inf; + struct bfd_link_info *info = (struct bfd_link_info *) info_p; - info->flags |= DF_TEXTREL; + info->flags |= DF_TEXTREL; + info->callbacks->minfo + (_("%B: dynamic relocation against `%T' in read-only section `%A'\n"), + sec->owner, h->root.root.string, sec); - /* Not an error, just cut short the traversal. */ - return FALSE; - } + /* Not an error, just cut short the traversal. */ + return FALSE; } return TRUE; } @@ -4113,7 +4072,7 @@ nds32_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, /* If any dynamic relocs apply to a read-only section, then we need a DT_TEXTREL entry. */ if ((info->flags & DF_TEXTREL) == 0) - elf_link_hash_traverse (&htab->root, readonly_dynrelocs, + elf_link_hash_traverse (&htab->root, maybe_set_textrel, (void *) info); if ((info->flags & DF_TEXTREL) != 0) diff --git a/bfd/elf32-or1k.c b/bfd/elf32-or1k.c index c12dea4746b..03accf70956 100644 --- a/bfd/elf32-or1k.c +++ b/bfd/elf32-or1k.c @@ -1921,6 +1921,24 @@ or1k_elf_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED, } } +/* Find dynamic relocs for H that apply to read-only sections. */ + +static asection * +readonly_dynrelocs (struct elf_link_hash_entry *h) +{ + struct elf_or1k_dyn_relocs *p; + struct elf_or1k_link_hash_entry *eh = (struct elf_or1k_link_hash_entry *) h; + + for (p = eh->dyn_relocs; p != NULL; p = p->next) + { + asection *s = p->sec->output_section; + + if (s != NULL && (s->flags & SEC_READONLY) != 0) + return p->sec; + } + return NULL; +} + /* Adjust a symbol defined by a dynamic object and referenced by a regular object. The current definition is in some section of the dynamic object, but we're not including those sections. We have to @@ -2264,28 +2282,29 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf) return TRUE; } -/* Find any dynamic relocs that apply to read-only sections. */ +/* Set DF_TEXTREL if we find any dynamic relocs that apply to + read-only sections. */ static bfd_boolean -readonly_dynrelocs (struct elf_link_hash_entry *h, void * inf) +maybe_set_textrel (struct elf_link_hash_entry *h, void *info_p) { - struct elf_or1k_link_hash_entry *eh; - struct elf_or1k_dyn_relocs *p; + asection *sec; - eh = (struct elf_or1k_link_hash_entry *) h; - for (p = eh->dyn_relocs; p != NULL; p = p->next) - { - asection *s = p->sec->output_section; + if (h->root.type == bfd_link_hash_indirect) + return TRUE; - if (s != NULL && (s->flags & SEC_READONLY) != 0) - { - struct bfd_link_info *info = (struct bfd_link_info *) inf; + sec = readonly_dynrelocs (h); + if (sec != NULL) + { + struct bfd_link_info *info = (struct bfd_link_info *) info_p; - info->flags |= DF_TEXTREL; + info->flags |= DF_TEXTREL; + info->callbacks->minfo + (_("%B: dynamic relocation against `%T' in read-only section `%A'\n"), + sec->owner, h->root.root.string, sec); - /* Not an error, just cut short the traversal. */ - return FALSE; - } + /* Not an error, just cut short the traversal. */ + return FALSE; } return TRUE; } @@ -2499,8 +2518,7 @@ or1k_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, /* If any dynamic relocs apply to a read-only section, then we need a DT_TEXTREL entry. */ if ((info->flags & DF_TEXTREL) == 0) - elf_link_hash_traverse (&htab->root, readonly_dynrelocs, - info); + elf_link_hash_traverse (&htab->root, maybe_set_textrel, info); if ((info->flags & DF_TEXTREL) != 0) { diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c index 80454eb3cee..bd5cc5c44d1 100644 --- a/bfd/elf32-ppc.c +++ b/bfd/elf32-ppc.c @@ -6153,8 +6153,8 @@ maybe_set_textrel (struct elf_link_hash_entry *h, void *info_p) info->flags |= DF_TEXTREL; info->callbacks->minfo - (_("%B: dynamic relocation in read-only section `%A'\n"), - sec->owner, sec); + (_("%B: dynamic relocation against `%T' in read-only section `%A'\n"), + sec->owner, h->root.root.string, sec); /* Not an error, just cut short the traversal. */ return FALSE; diff --git a/bfd/elf32-s390.c b/bfd/elf32-s390.c index d073ea29072..b0f87523d42 100644 --- a/bfd/elf32-s390.c +++ b/bfd/elf32-s390.c @@ -1419,6 +1419,23 @@ elf_s390_adjust_gotplt (struct elf_s390_link_hash_entry *h) h->gotplt_refcount = -1; } +/* Find dynamic relocs for H that apply to read-only sections. */ + +static asection * +readonly_dynrelocs (struct elf_link_hash_entry *h) +{ + struct elf_dyn_relocs *p; + + for (p = elf_s390_hash_entry (h)->dyn_relocs; p != NULL; p = p->next) + { + asection *s = p->sec->output_section; + + if (s != NULL && (s->flags & SEC_READONLY) != 0) + return p->sec; + } + return NULL; +} + /* Adjust a symbol defined by a dynamic object and referenced by a regular object. The current definition is in some section of the dynamic object, but we're not including those sections. We have to @@ -1827,28 +1844,29 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf) return TRUE; } -/* Find any dynamic relocs that apply to read-only sections. */ +/* Set DF_TEXTREL if we find any dynamic relocs that apply to + read-only sections. */ static bfd_boolean -readonly_dynrelocs (struct elf_link_hash_entry *h, void * inf) +maybe_set_textrel (struct elf_link_hash_entry *h, void *info_p) { - struct elf_s390_link_hash_entry *eh; - struct elf_dyn_relocs *p; + asection *sec; - eh = (struct elf_s390_link_hash_entry *) h; - for (p = eh->dyn_relocs; p != NULL; p = p->next) - { - asection *s = p->sec->output_section; + if (h->root.type == bfd_link_hash_indirect) + return TRUE; - if (s != NULL && (s->flags & SEC_READONLY) != 0) - { - struct bfd_link_info *info = (struct bfd_link_info *) inf; + sec = readonly_dynrelocs (h); + if (sec != NULL) + { + struct bfd_link_info *info = (struct bfd_link_info *) info_p; - info->flags |= DF_TEXTREL; + info->flags |= DF_TEXTREL; + info->callbacks->minfo + (_("%B: dynamic relocation against `%T' in read-only section `%A'\n"), + sec->owner, h->root.root.string, sec); - /* Not an error, just cut short the traversal. */ - return FALSE; - } + /* Not an error, just cut short the traversal. */ + return FALSE; } return TRUE; } @@ -2076,7 +2094,7 @@ elf_s390_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, /* If any dynamic relocs apply to a read-only section, then we need a DT_TEXTREL entry. */ if ((info->flags & DF_TEXTREL) == 0) - elf_link_hash_traverse (&htab->elf, readonly_dynrelocs, info); + elf_link_hash_traverse (&htab->elf, maybe_set_textrel, info); if ((info->flags & DF_TEXTREL) != 0) { diff --git a/bfd/elf32-sh.c b/bfd/elf32-sh.c index e451bb6ae32..0ff6a1b2040 100644 --- a/bfd/elf32-sh.c +++ b/bfd/elf32-sh.c @@ -2795,6 +2795,23 @@ sh_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info) return TRUE; } +/* Find dynamic relocs for H that apply to read-only sections. */ + +static asection * +readonly_dynrelocs (struct elf_link_hash_entry *h) +{ + struct elf_sh_dyn_relocs *p; + + for (p = sh_elf_hash_entry (h)->dyn_relocs; p != NULL; p = p->next) + { + asection *s = p->sec->output_section; + + if (s != NULL && (s->flags & SEC_READONLY) != 0) + return p->sec; + } + return NULL; +} + /* Adjust a symbol defined by a dynamic object and referenced by a regular object. The current definition is in some section of the dynamic object, but we're not including those sections. We have to @@ -3282,31 +3299,29 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) return TRUE; } -/* Find any dynamic relocs that apply to read-only sections. */ +/* Set DF_TEXTREL if we find any dynamic relocs that apply to + read-only sections. */ static bfd_boolean -readonly_dynrelocs (struct elf_link_hash_entry *h, void *inf) +maybe_set_textrel (struct elf_link_hash_entry *h, void *info_p) { - struct elf_sh_link_hash_entry *eh; - struct elf_sh_dyn_relocs *p; - - eh = (struct elf_sh_link_hash_entry *) h; - for (p = eh->dyn_relocs; p != NULL; p = p->next) - { - asection *s = p->sec->output_section; + asection *sec; - if (s != NULL && (s->flags & SEC_READONLY) != 0) - { - struct bfd_link_info *info = (struct bfd_link_info *) inf; + if (h->root.type == bfd_link_hash_indirect) + return TRUE; - info->flags |= DF_TEXTREL; + sec = readonly_dynrelocs (h); + if (sec != NULL) + { + struct bfd_link_info *info = (struct bfd_link_info *) info_p; - info->callbacks->minfo (_("%B: dynamic relocation in read-only section `%A'\n"), - p->sec->owner, p->sec); + info->flags |= DF_TEXTREL; + info->callbacks->minfo + (_("%B: dynamic relocation against `%T' in read-only section `%A'\n"), + sec->owner, h->root.root.string, sec); - /* Not an error, just cut short the traversal. */ - return FALSE; - } + /* Not an error, just cut short the traversal. */ + return FALSE; } return TRUE; } @@ -3630,7 +3645,7 @@ sh_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, /* If any dynamic relocs apply to a read-only section, then we need a DT_TEXTREL entry. */ if ((info->flags & DF_TEXTREL) == 0) - elf_link_hash_traverse (&htab->root, readonly_dynrelocs, info); + elf_link_hash_traverse (&htab->root, maybe_set_textrel, info); if ((info->flags & DF_TEXTREL) != 0) { diff --git a/bfd/elf32-tic6x.c b/bfd/elf32-tic6x.c index 8575a266564..fccfb42d202 100644 --- a/bfd/elf32-tic6x.c +++ b/bfd/elf32-tic6x.c @@ -1971,6 +1971,25 @@ elf32_tic6x_fake_sections (bfd *abfd ATTRIBUTE_UNUSED, return TRUE; } +/* Find dynamic relocs for H that apply to read-only sections. */ + +static asection * +readonly_dynrelocs (struct elf_link_hash_entry *h) +{ + struct elf_dyn_relocs *p; + struct elf32_tic6x_link_hash_entry *eh + = (struct elf32_tic6x_link_hash_entry *) h; + + for (p = eh->dyn_relocs; p != NULL; p = p->next) + { + asection *s = p->sec->output_section; + + if (s != NULL && (s->flags & SEC_READONLY) != 0) + return p->sec; + } + return NULL; +} + /* Adjust a symbol defined by a dynamic object and referenced by a regular object. The current definition is in some section of the dynamic object, but we're not including those sections. We have to @@ -3165,28 +3184,29 @@ elf32_tic6x_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) return TRUE; } -/* Find any dynamic relocs that apply to read-only sections. */ +/* Set DF_TEXTREL if we find any dynamic relocs that apply to + read-only sections. */ static bfd_boolean -elf32_tic6x_readonly_dynrelocs (struct elf_link_hash_entry *h, void *inf) +maybe_set_textrel (struct elf_link_hash_entry *h, void *info_p) { - struct elf32_tic6x_link_hash_entry *eh; - struct elf_dyn_relocs *p; + asection *sec; - eh = (struct elf32_tic6x_link_hash_entry *) h; - for (p = eh->dyn_relocs; p != NULL; p = p->next) - { - asection *s = p->sec->output_section; + if (h->root.type == bfd_link_hash_indirect) + return TRUE; - if (s != NULL && (s->flags & SEC_READONLY) != 0) - { - struct bfd_link_info *info = (struct bfd_link_info *) inf; + sec = readonly_dynrelocs (h); + if (sec != NULL) + { + struct bfd_link_info *info = (struct bfd_link_info *) info_p; - info->flags |= DF_TEXTREL; + info->flags |= DF_TEXTREL; + info->callbacks->minfo + (_("%B: dynamic relocation against `%T' in read-only section `%A'\n"), + sec->owner, h->root.root.string, sec); - /* Not an error, just cut short the traversal. */ - return FALSE; - } + /* Not an error, just cut short the traversal. */ + return FALSE; } return TRUE; } @@ -3404,8 +3424,7 @@ elf32_tic6x_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info) /* If any dynamic relocs apply to a read-only section, then we need a DT_TEXTREL entry. */ if ((info->flags & DF_TEXTREL) == 0) - elf_link_hash_traverse (&htab->elf, - elf32_tic6x_readonly_dynrelocs, info); + elf_link_hash_traverse (&htab->elf, maybe_set_textrel, info); if ((info->flags & DF_TEXTREL) != 0) { diff --git a/bfd/elf32-tilepro.c b/bfd/elf32-tilepro.c index 9643e703e06..521ee37f8d4 100644 --- a/bfd/elf32-tilepro.c +++ b/bfd/elf32-tilepro.c @@ -1889,6 +1889,23 @@ tilepro_elf_gc_mark_hook (asection *sec, return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym); } +/* Find dynamic relocs for H that apply to read-only sections. */ + +static asection * +readonly_dynrelocs (struct elf_link_hash_entry *h) +{ + struct tilepro_elf_dyn_relocs *p; + + for (p = tilepro_elf_hash_entry (h)->dyn_relocs; p != NULL; p = p->next) + { + asection *s = p->sec->output_section; + + if (s != NULL && (s->flags & SEC_READONLY) != 0) + return p->sec; + } + return NULL; +} + /* Adjust a symbol defined by a dynamic object and referenced by a regular object. The current definition is in some section of the dynamic object, but we're not including those sections. We have to @@ -2229,31 +2246,29 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) return TRUE; } -/* Find any dynamic relocs that apply to read-only sections. */ +/* Set DF_TEXTREL if we find any dynamic relocs that apply to + read-only sections. */ static bfd_boolean -readonly_dynrelocs (struct elf_link_hash_entry *h, void *inf) +maybe_set_textrel (struct elf_link_hash_entry *h, void *info_p) { - struct tilepro_elf_link_hash_entry *eh; - struct tilepro_elf_dyn_relocs *p; - - eh = (struct tilepro_elf_link_hash_entry *) h; - for (p = eh->dyn_relocs; p != NULL; p = p->next) - { - asection *s = p->sec->output_section; + asection *sec; - if (s != NULL && (s->flags & SEC_READONLY) != 0) - { - struct bfd_link_info *info = (struct bfd_link_info *) inf; + if (h->root.type == bfd_link_hash_indirect) + return TRUE; - info->flags |= DF_TEXTREL; + sec = readonly_dynrelocs (h); + if (sec != NULL) + { + struct bfd_link_info *info = (struct bfd_link_info *) info_p; - info->callbacks->minfo (_("%B: dynamic relocation in read-only section `%A'\n"), - p->sec->owner, p->sec); + info->flags |= DF_TEXTREL; + info->callbacks->minfo + (_("%B: dynamic relocation against `%T' in read-only section `%A'\n"), + sec->owner, h->root.root.string, sec); - /* Not an error, just cut short the traversal. */ - return FALSE; - } + /* Not an error, just cut short the traversal. */ + return FALSE; } return TRUE; } @@ -2504,7 +2519,7 @@ tilepro_elf_size_dynamic_sections (bfd *output_bfd, /* If any dynamic relocs apply to a read-only section, then we need a DT_TEXTREL entry. */ if ((info->flags & DF_TEXTREL) == 0) - elf_link_hash_traverse (&htab->elf, readonly_dynrelocs, info); + elf_link_hash_traverse (&htab->elf, maybe_set_textrel, info); if (info->flags & DF_TEXTREL) { diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c index b7f4029bf56..b0fc02037b2 100644 --- a/bfd/elf64-ppc.c +++ b/bfd/elf64-ppc.c @@ -9890,8 +9890,8 @@ maybe_set_textrel (struct elf_link_hash_entry *h, void *inf) info->flags |= DF_TEXTREL; info->callbacks->minfo - (_("%B: dynamic relocation in read-only section `%A'\n"), - sec->owner, sec); + (_("%B: dynamic relocation against `%T' in read-only section `%A'\n"), + sec->owner, h->root.root.string, sec); /* Not an error, just cut short the traversal. */ return FALSE; diff --git a/bfd/elf64-s390.c b/bfd/elf64-s390.c index 0329c16b0e2..6c53ed395ed 100644 --- a/bfd/elf64-s390.c +++ b/bfd/elf64-s390.c @@ -1351,6 +1351,23 @@ elf_s390_adjust_gotplt (struct elf_s390_link_hash_entry *h) h->gotplt_refcount = -1; } +/* Find dynamic relocs for H that apply to read-only sections. */ + +static asection * +readonly_dynrelocs (struct elf_link_hash_entry *h) +{ + struct elf_dyn_relocs *p; + + for (p = elf_s390_hash_entry (h)->dyn_relocs; p != NULL; p = p->next) + { + asection *s = p->sec->output_section; + + if (s != NULL && (s->flags & SEC_READONLY) != 0) + return p->sec; + } + return NULL; +} + /* Adjust a symbol defined by a dynamic object and referenced by a regular object. The current definition is in some section of the dynamic object, but we're not including those sections. We have to @@ -1763,28 +1780,29 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, return TRUE; } -/* Find any dynamic relocs that apply to read-only sections. */ +/* Set DF_TEXTREL if we find any dynamic relocs that apply to + read-only sections. */ static bfd_boolean -readonly_dynrelocs (struct elf_link_hash_entry *h, void * inf) +maybe_set_textrel (struct elf_link_hash_entry *h, void *info_p) { - struct elf_s390_link_hash_entry *eh; - struct elf_dyn_relocs *p; + asection *sec; - eh = (struct elf_s390_link_hash_entry *) h; - for (p = eh->dyn_relocs; p != NULL; p = p->next) - { - asection *s = p->sec->output_section; + if (h->root.type == bfd_link_hash_indirect) + return TRUE; - if (s != NULL && (s->flags & SEC_READONLY) != 0) - { - struct bfd_link_info *info = (struct bfd_link_info *) inf; + sec = readonly_dynrelocs (h); + if (sec != NULL) + { + struct bfd_link_info *info = (struct bfd_link_info *) info_p; - info->flags |= DF_TEXTREL; + info->flags |= DF_TEXTREL; + info->callbacks->minfo + (_("%B: dynamic relocation against `%T' in read-only section `%A'\n"), + sec->owner, h->root.root.string, sec); - /* Not an error, just cut short the traversal. */ - return FALSE; - } + /* Not an error, just cut short the traversal. */ + return FALSE; } return TRUE; } @@ -2016,8 +2034,7 @@ elf_s390_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, /* If any dynamic relocs apply to a read-only section, then we need a DT_TEXTREL entry. */ if ((info->flags & DF_TEXTREL) == 0) - elf_link_hash_traverse (&htab->elf, readonly_dynrelocs, - info); + elf_link_hash_traverse (&htab->elf, maybe_set_textrel, info); if ((info->flags & DF_TEXTREL) != 0) { diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c index 7f50f77837d..a4ee1364568 100644 --- a/bfd/elfnn-aarch64.c +++ b/bfd/elfnn-aarch64.c @@ -6693,6 +6693,23 @@ elfNN_aarch64_print_private_bfd_data (bfd *abfd, void *ptr) return TRUE; } +/* Find dynamic relocs for H that apply to read-only sections. */ + +static asection * +readonly_dynrelocs (struct elf_link_hash_entry *h) +{ + struct elf_dyn_relocs *p; + + for (p = elf_aarch64_hash_entry (h)->dyn_relocs; p != NULL; p = p->next) + { + asection *s = p->sec->output_section; + + if (s != NULL && (s->flags & SEC_READONLY) != 0) + return p->sec; + } + return NULL; +} + /* Return true if we need copy relocation against EH. */ static bfd_boolean @@ -8260,28 +8277,29 @@ elfNN_aarch64_allocate_local_ifunc_dynrelocs (void **slot, void *inf) return elfNN_aarch64_allocate_ifunc_dynrelocs (h, inf); } -/* Find any dynamic relocs that apply to read-only sections. */ +/* Set DF_TEXTREL if we find any dynamic relocs that apply to + read-only sections. */ static bfd_boolean -aarch64_readonly_dynrelocs (struct elf_link_hash_entry * h, void * inf) +maybe_set_textrel (struct elf_link_hash_entry *h, void *info_p) { - struct elf_aarch64_link_hash_entry * eh; - struct elf_dyn_relocs * p; + asection *sec; - eh = (struct elf_aarch64_link_hash_entry *) h; - for (p = eh->dyn_relocs; p != NULL; p = p->next) - { - asection *s = p->sec; + if (h->root.type == bfd_link_hash_indirect) + return TRUE; - if (s != NULL && (s->flags & SEC_READONLY) != 0) - { - struct bfd_link_info *info = (struct bfd_link_info *) inf; + sec = readonly_dynrelocs (h); + if (sec != NULL) + { + struct bfd_link_info *info = (struct bfd_link_info *) info_p; - info->flags |= DF_TEXTREL; + info->flags |= DF_TEXTREL; + info->callbacks->minfo + (_("%B: dynamic relocation against `%T' in read-only section `%A'\n"), + sec->owner, h->root.root.string, sec); - /* Not an error, just cut short the traversal. */ - return FALSE; - } + /* Not an error, just cut short the traversal. */ + return FALSE; } return TRUE; } @@ -8576,8 +8594,7 @@ elfNN_aarch64_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, /* If any dynamic relocs apply to a read-only section, then we need a DT_TEXTREL entry. */ if ((info->flags & DF_TEXTREL) == 0) - elf_link_hash_traverse (& htab->root, aarch64_readonly_dynrelocs, - info); + elf_link_hash_traverse (&htab->root, maybe_set_textrel, info); if ((info->flags & DF_TEXTREL) != 0) { diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c index 6a56174cf6d..47d2c477036 100644 --- a/bfd/elfnn-riscv.c +++ b/bfd/elfnn-riscv.c @@ -757,6 +757,23 @@ riscv_elf_gc_mark_hook (asection *sec, return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym); } +/* Find dynamic relocs for H that apply to read-only sections. */ + +static asection * +readonly_dynrelocs (struct elf_link_hash_entry *h) +{ + struct riscv_elf_dyn_relocs *p; + + for (p = riscv_elf_hash_entry (h)->dyn_relocs; p != NULL; p = p->next) + { + asection *s = p->sec->output_section; + + if (s != NULL && (s->flags & SEC_READONLY) != 0) + return p->sec; + } + return NULL; +} + /* Adjust a symbol defined by a dynamic object and referenced by a regular object. The current definition is in some section of the dynamic object, but we're not including those sections. We have to @@ -1102,24 +1119,29 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) return TRUE; } -/* Find any dynamic relocs that apply to read-only sections. */ +/* Set DF_TEXTREL if we find any dynamic relocs that apply to + read-only sections. */ static bfd_boolean -readonly_dynrelocs (struct elf_link_hash_entry *h, void *inf) +maybe_set_textrel (struct elf_link_hash_entry *h, void *info_p) { - struct riscv_elf_link_hash_entry *eh; - struct riscv_elf_dyn_relocs *p; + asection *sec; - eh = (struct riscv_elf_link_hash_entry *) h; - for (p = eh->dyn_relocs; p != NULL; p = p->next) + if (h->root.type == bfd_link_hash_indirect) + return TRUE; + + sec = readonly_dynrelocs (h); + if (sec != NULL) { - asection *s = p->sec->output_section; + struct bfd_link_info *info = (struct bfd_link_info *) info_p; - if (s != NULL && (s->flags & SEC_READONLY) != 0) - { - ((struct bfd_link_info *) inf)->flags |= DF_TEXTREL; - return FALSE; - } + info->flags |= DF_TEXTREL; + info->callbacks->minfo + (_("%B: dynamic relocation against `%T' in read-only section `%A'\n"), + sec->owner, h->root.root.string, sec); + + /* Not an error, just cut short the traversal. */ + return FALSE; } return TRUE; } @@ -1329,7 +1351,7 @@ riscv_elf_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info) /* If any dynamic relocs apply to a read-only section, then we need a DT_TEXTREL entry. */ if ((info->flags & DF_TEXTREL) == 0) - elf_link_hash_traverse (&htab->elf, readonly_dynrelocs, info); + elf_link_hash_traverse (&htab->elf, maybe_set_textrel, info); if (info->flags & DF_TEXTREL) { diff --git a/bfd/elfxx-sparc.c b/bfd/elfxx-sparc.c index 13aa6c5613d..89b9a0e8a7b 100644 --- a/bfd/elfxx-sparc.c +++ b/bfd/elfxx-sparc.c @@ -1969,6 +1969,23 @@ _bfd_sparc_elf_fixup_symbol (struct bfd_link_info *info, return TRUE; } +/* Find dynamic relocs for H that apply to read-only sections. */ + +static asection * +readonly_dynrelocs (struct elf_link_hash_entry *h) +{ + struct _bfd_sparc_elf_dyn_relocs *p; + + for (p = _bfd_sparc_elf_hash_entry (h)->dyn_relocs; p != NULL; p = p->next) + { + asection *s = p->sec->output_section; + + if (s != NULL && (s->flags & SEC_READONLY) != 0) + return p->sec; + } + return NULL; +} + /* Adjust a symbol defined by a dynamic object and referenced by a regular object. The current definition is in some section of the dynamic object, but we're not including those sections. We have to @@ -2449,31 +2466,29 @@ allocate_local_dynrelocs (void **slot, void *inf) return allocate_dynrelocs (h, inf); } -/* Find any dynamic relocs that apply to read-only sections. */ +/* Set DF_TEXTREL if we find any dynamic relocs that apply to + read-only sections. */ static bfd_boolean -readonly_dynrelocs (struct elf_link_hash_entry *h, void * inf) +maybe_set_textrel (struct elf_link_hash_entry *h, void *info_p) { - struct _bfd_sparc_elf_link_hash_entry *eh; - struct _bfd_sparc_elf_dyn_relocs *p; - - eh = (struct _bfd_sparc_elf_link_hash_entry *) h; - for (p = eh->dyn_relocs; p != NULL; p = p->next) - { - asection *s = p->sec->output_section; + asection *sec; - if (s != NULL && (s->flags & SEC_READONLY) != 0) - { - struct bfd_link_info *info = (struct bfd_link_info *) inf; + if (h->root.type == bfd_link_hash_indirect) + return TRUE; - info->flags |= DF_TEXTREL; + sec = readonly_dynrelocs (h); + if (sec != NULL) + { + struct bfd_link_info *info = (struct bfd_link_info *) info_p; - info->callbacks->minfo (_("%B: dynamic relocation in read-only section `%A'\n"), - p->sec->owner, p->sec); + info->flags |= DF_TEXTREL; + info->callbacks->minfo + (_("%B: dynamic relocation against `%T' in read-only section `%A'\n"), + sec->owner, h->root.root.string, sec); - /* Not an error, just cut short the traversal. */ - return FALSE; - } + /* Not an error, just cut short the traversal. */ + return FALSE; } return TRUE; } @@ -2732,7 +2747,7 @@ _bfd_sparc_elf_size_dynamic_sections (bfd *output_bfd, /* If any dynamic relocs apply to a read-only section, then we need a DT_TEXTREL entry. */ if ((info->flags & DF_TEXTREL) == 0) - elf_link_hash_traverse (&htab->elf, readonly_dynrelocs, info); + elf_link_hash_traverse (&htab->elf, maybe_set_textrel, info); if (info->flags & DF_TEXTREL) { diff --git a/bfd/elfxx-tilegx.c b/bfd/elfxx-tilegx.c index 5f6622aeb06..19c55417ab2 100644 --- a/bfd/elfxx-tilegx.c +++ b/bfd/elfxx-tilegx.c @@ -2128,6 +2128,23 @@ tilegx_elf_gc_mark_hook (asection *sec, return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym); } +/* Find dynamic relocs for H that apply to read-only sections. */ + +static asection * +readonly_dynrelocs (struct elf_link_hash_entry *h) +{ + struct tilegx_elf_dyn_relocs *p; + + for (p = tilegx_elf_hash_entry (h)->dyn_relocs; p != NULL; p = p->next) + { + asection *s = p->sec->output_section; + + if (s != NULL && (s->flags & SEC_READONLY) != 0) + return p->sec; + } + return NULL; +} + /* Adjust a symbol defined by a dynamic object and referenced by a regular object. The current definition is in some section of the dynamic object, but we're not including those sections. We have to @@ -2471,31 +2488,29 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) return TRUE; } -/* Find any dynamic relocs that apply to read-only sections. */ +/* Set DF_TEXTREL if we find any dynamic relocs that apply to + read-only sections. */ static bfd_boolean -readonly_dynrelocs (struct elf_link_hash_entry *h, void *inf) +maybe_set_textrel (struct elf_link_hash_entry *h, void *info_p) { - struct tilegx_elf_link_hash_entry *eh; - struct tilegx_elf_dyn_relocs *p; - - eh = (struct tilegx_elf_link_hash_entry *) h; - for (p = eh->dyn_relocs; p != NULL; p = p->next) - { - asection *s = p->sec->output_section; + asection *sec; - if (s != NULL && (s->flags & SEC_READONLY) != 0) - { - struct bfd_link_info *info = (struct bfd_link_info *) inf; + if (h->root.type == bfd_link_hash_indirect) + return TRUE; - info->flags |= DF_TEXTREL; + sec = readonly_dynrelocs (h); + if (sec != NULL) + { + struct bfd_link_info *info = (struct bfd_link_info *) info_p; - info->callbacks->minfo (_("%B: dynamic relocation in read-only section `%A'\n"), - p->sec->owner, p->sec); + info->flags |= DF_TEXTREL; + info->callbacks->minfo + (_("%B: dynamic relocation against `%T' in read-only section `%A'\n"), + sec->owner, h->root.root.string, sec); - /* Not an error, just cut short the traversal. */ - return FALSE; - } + /* Not an error, just cut short the traversal. */ + return FALSE; } return TRUE; } @@ -2740,7 +2755,7 @@ tilegx_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, /* If any dynamic relocs apply to a read-only section, then we need a DT_TEXTREL entry. */ if ((info->flags & DF_TEXTREL) == 0) - elf_link_hash_traverse (&htab->elf, readonly_dynrelocs, info); + elf_link_hash_traverse (&htab->elf, maybe_set_textrel, info); if (info->flags & DF_TEXTREL) { diff --git a/ld/ChangeLog b/ld/ChangeLog index 51d50d1705c..0729d2167ab 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,11 @@ +2017-12-01 Alan Modra + + * testsuite/ld-elf/shared.exp: Run new textrel tests. + * testsuite/ld-elf/textrel.map: New file. + * testsuite/ld-elf/textrel.rd: New file. + * testsuite/ld-elf/textrel.s: New file. + * testsuite/ld-elf/textrel.warn: New file. + 2017-11-30 Alan Modra PR 22471 diff --git a/ld/testsuite/ld-elf/shared.exp b/ld/testsuite/ld-elf/shared.exp index 99c34bec8b0..cc145b48cb9 100644 --- a/ld/testsuite/ld-elf/shared.exp +++ b/ld/testsuite/ld-elf/shared.exp @@ -83,6 +83,31 @@ run_ld_link_tests [list \ ] \ ] +run_ld_link_tests [list \ + [list \ + "DT_TEXTREL in shared lib" \ + "$LFLAGS -shared --warn-shared-textrel" \ + "" \ + "$AFLAGS_PIC" \ + {textrel.s} \ + {{ld textrel.warn} \ + {readelf {-d --wide} textrel.rd}} \ + "textrel.so" \ + ] \ +] "xtensa-*-*" + +run_ld_link_tests [list \ + [list \ + "DT_TEXTREL map file warning" \ + "$LFLAGS -shared -M" \ + "" \ + "$AFLAGS_PIC" \ + {textrel.s} \ + {{ld textrel.map}} \ + "textrel.so" \ + ] \ +] "cris*-*-*" + # PR ld/20828 check for correct dynamic symbol table entries where: # - symbols have been defined with a linker script, # - the same symbols have been seen in shared library used in the link, diff --git a/ld/testsuite/ld-elf/textrel.map b/ld/testsuite/ld-elf/textrel.map new file mode 100644 index 00000000000..fa331136f80 --- /dev/null +++ b/ld/testsuite/ld-elf/textrel.map @@ -0,0 +1,3 @@ +#... +.*dynamic relocation .* read-only section.* +#pass diff --git a/ld/testsuite/ld-elf/textrel.rd b/ld/testsuite/ld-elf/textrel.rd new file mode 100644 index 00000000000..cc270dfe428 --- /dev/null +++ b/ld/testsuite/ld-elf/textrel.rd @@ -0,0 +1,3 @@ +#... +.*\(TEXTREL\).* +#pass diff --git a/ld/testsuite/ld-elf/textrel.s b/ld/testsuite/ld-elf/textrel.s new file mode 100644 index 00000000000..b4bfb58c59f --- /dev/null +++ b/ld/testsuite/ld-elf/textrel.s @@ -0,0 +1,5 @@ + .section .rodata,"a",%progbits + .global pfoo, foo +pfoo: + .dc.a foo +foo: diff --git a/ld/testsuite/ld-elf/textrel.warn b/ld/testsuite/ld-elf/textrel.warn new file mode 100644 index 00000000000..51d9ca81227 --- /dev/null +++ b/ld/testsuite/ld-elf/textrel.warn @@ -0,0 +1,3 @@ +#... +.*warning:.*DT_TEXTREL.* +#pass