From 5160d0f323d47031cb73c39a4dbd31d8976b4c8e Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Mon, 30 Nov 2020 19:19:00 +1030 Subject: [PATCH] PR26979, Visibility of undefined foo@v1 should constrain foo@@v1 Also, undefined foo should constrain the visibility of foo@@v1 just as it does for a later plain foo definition. bfd/ PR 26979 * elf-bfd.h (elf_backend_merge_symbol_attribute): Update prototype. * elf32-m68hc1x.h (elf32_m68hc11_merge_symbol_attribute): Likewise. * elfxx-mips.h (_bfd_mips_elf_merge_symbol_attribute): Likewise. * elfxx-x86.h (_bfd_x86_elf_merge_symbol_attribute): Likewise. * elf32-m68hc1x.c (elf32_m68hc11_merge_symbol_attribute): Replace isym parameter with st_other. Adjust code. * elf64-alpha.c (elf64_alpha_merge_symbol_attribute): Likewise. * elf64-ppc.c (ppc64_elf_merge_symbol_attribute): Likewise. * elfnn-aarch64.c (elfNN_aarch64_merge_symbol_attribute): Likewise. * elfxx-mips.c (_bfd_mips_elf_merge_symbol_attribute): Likewise. * elfxx-x86.c (_bfd_x86_elf_merge_symbol_attribute): Likewise. * elflink.c (elf_merge_st_other): Likewise. (_bfd_elf_merge_symbol, elf_link_add_object_symbols): Adjust to suit. (_bfd_elf_copy_link_hash_symbol_type): Likewise. (_bfd_elf_add_default_symbol): Merge st_other from undecorated symbol and @VER symbol to @@VER symbol. ld/ * testsuite/ld-elf/pr26979a.s, * testsuite/ld-elf/pr26979b.s, * testsuite/ld-elf/pr26979c.s, * testsuite/ld-elf/pr26979.ver, * testsuite/ld-elf/pr26979a.d, * testsuite/ld-elf/pr26979b.d: New tests. --- bfd/ChangeLog | 20 ++++++++++++++++++++ bfd/elf-bfd.h | 3 +-- bfd/elf32-m68hc1x.c | 4 ++-- bfd/elf32-m68hc1x.h | 3 +-- bfd/elf64-alpha.c | 4 ++-- bfd/elf64-ppc.c | 4 ++-- bfd/elflink.c | 24 +++++++++++++++++------- bfd/elfnn-aarch64.c | 4 ++-- bfd/elfxx-mips.c | 8 ++++---- bfd/elfxx-mips.h | 2 +- bfd/elfxx-x86.c | 5 ++--- bfd/elfxx-x86.h | 3 +-- ld/ChangeLog | 9 +++++++++ ld/testsuite/ld-elf/pr26979.ver | 1 + ld/testsuite/ld-elf/pr26979a.d | 12 ++++++++++++ ld/testsuite/ld-elf/pr26979a.s | 3 +++ ld/testsuite/ld-elf/pr26979b.d | 12 ++++++++++++ ld/testsuite/ld-elf/pr26979b.s | 4 ++++ ld/testsuite/ld-elf/pr26979c.s | 3 +++ 19 files changed, 99 insertions(+), 29 deletions(-) create mode 100644 ld/testsuite/ld-elf/pr26979.ver create mode 100644 ld/testsuite/ld-elf/pr26979a.d create mode 100644 ld/testsuite/ld-elf/pr26979a.s create mode 100644 ld/testsuite/ld-elf/pr26979b.d create mode 100644 ld/testsuite/ld-elf/pr26979b.s create mode 100644 ld/testsuite/ld-elf/pr26979c.s diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 83eb64543b0..d7724397960 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,23 @@ +2020-12-01 Alan Modra + + PR 26979 + * elf-bfd.h (elf_backend_merge_symbol_attribute): Update prototype. + * elf32-m68hc1x.h (elf32_m68hc11_merge_symbol_attribute): Likewise. + * elfxx-mips.h (_bfd_mips_elf_merge_symbol_attribute): Likewise. + * elfxx-x86.h (_bfd_x86_elf_merge_symbol_attribute): Likewise. + * elf32-m68hc1x.c (elf32_m68hc11_merge_symbol_attribute): Replace + isym parameter with st_other. Adjust code. + * elf64-alpha.c (elf64_alpha_merge_symbol_attribute): Likewise. + * elf64-ppc.c (ppc64_elf_merge_symbol_attribute): Likewise. + * elfnn-aarch64.c (elfNN_aarch64_merge_symbol_attribute): Likewise. + * elfxx-mips.c (_bfd_mips_elf_merge_symbol_attribute): Likewise. + * elfxx-x86.c (_bfd_x86_elf_merge_symbol_attribute): Likewise. + * elflink.c (elf_merge_st_other): Likewise. + (_bfd_elf_merge_symbol, elf_link_add_object_symbols): Adjust to suit. + (_bfd_elf_copy_link_hash_symbol_type): Likewise. + (_bfd_elf_add_default_symbol): Merge st_other from undecorated + symbol and @VER symbol to @@VER symbol. + 2020-11-28 Alan Modra PR 26907 diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h index e8455d14864..e9c890f6f16 100644 --- a/bfd/elf-bfd.h +++ b/bfd/elf-bfd.h @@ -1295,8 +1295,7 @@ struct elf_backend_data /* Merge the backend specific symbol attribute. */ void (*elf_backend_merge_symbol_attribute) - (struct elf_link_hash_entry *, const Elf_Internal_Sym *, bfd_boolean, - bfd_boolean); + (struct elf_link_hash_entry *, unsigned int, bfd_boolean, bfd_boolean); /* This function, if defined, will return a string containing the name of a target-specific dynamic tag. */ diff --git a/bfd/elf32-m68hc1x.c b/bfd/elf32-m68hc1x.c index 56c51295775..3ac6c670d02 100644 --- a/bfd/elf32-m68hc1x.c +++ b/bfd/elf32-m68hc1x.c @@ -218,12 +218,12 @@ elf32_m68hc11_add_symbol_hook (bfd *abfd, struct bfd_link_info *info, void elf32_m68hc11_merge_symbol_attribute (struct elf_link_hash_entry *h, - const Elf_Internal_Sym *isym, + unsigned int st_other, bfd_boolean definition, bfd_boolean dynamic ATTRIBUTE_UNUSED) { if (definition) - h->other = ((isym->st_other & ~ELF_ST_VISIBILITY (-1)) + h->other = ((st_other & ~ELF_ST_VISIBILITY (-1)) | ELF_ST_VISIBILITY (h->other)); } diff --git a/bfd/elf32-m68hc1x.h b/bfd/elf32-m68hc1x.h index f88f276772b..6e673a83f43 100644 --- a/bfd/elf32-m68hc1x.h +++ b/bfd/elf32-m68hc1x.h @@ -174,8 +174,7 @@ bfd_boolean elf32_m68hc11_add_symbol_hook bfd_vma *valp); void elf32_m68hc11_merge_symbol_attribute - (struct elf_link_hash_entry *, const Elf_Internal_Sym *, - bfd_boolean, bfd_boolean); + (struct elf_link_hash_entry *, unsigned int, bfd_boolean, bfd_boolean); /* Tweak the OSABI field of the elf header. */ diff --git a/bfd/elf64-alpha.c b/bfd/elf64-alpha.c index 7b708f1e9d9..ea7a53160bd 100644 --- a/bfd/elf64-alpha.c +++ b/bfd/elf64-alpha.c @@ -2093,13 +2093,13 @@ elf64_alpha_adjust_dynamic_symbol (struct bfd_link_info *info, static void elf64_alpha_merge_symbol_attribute (struct elf_link_hash_entry *h, - const Elf_Internal_Sym *isym, + unsigned int st_other, bfd_boolean definition, bfd_boolean dynamic) { if (!dynamic && definition) h->other = ((h->other & ELF_ST_VISIBILITY (-1)) - | (isym->st_other & ~ELF_ST_VISIBILITY (-1))); + | (st_other & ~ELF_ST_VISIBILITY (-1))); } /* Symbol versioning can create new symbols, and make our old symbols diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c index 157c454d854..9e592174340 100644 --- a/bfd/elf64-ppc.c +++ b/bfd/elf64-ppc.c @@ -4152,12 +4152,12 @@ ppc64_elf_add_symbol_hook (bfd *ibfd, static void ppc64_elf_merge_symbol_attribute (struct elf_link_hash_entry *h, - const Elf_Internal_Sym *isym, + unsigned int st_other, bfd_boolean definition, bfd_boolean dynamic) { if (definition && (!dynamic || !h->def_regular)) - h->other = ((isym->st_other & ~ELF_ST_VISIBILITY (-1)) + h->other = ((st_other & ~ELF_ST_VISIBILITY (-1)) | ELF_ST_VISIBILITY (h->other)); } diff --git a/bfd/elflink.c b/bfd/elflink.c index 0fbebca372f..512c5044b3b 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -1006,7 +1006,7 @@ _bfd_elf_link_renumber_dynsyms (bfd *output_bfd, static void elf_merge_st_other (bfd *abfd, struct elf_link_hash_entry *h, - const Elf_Internal_Sym *isym, asection *sec, + unsigned int st_other, asection *sec, bfd_boolean definition, bfd_boolean dynamic) { const struct elf_backend_data *bed = get_elf_backend_data (abfd); @@ -1014,12 +1014,12 @@ elf_merge_st_other (bfd *abfd, struct elf_link_hash_entry *h, /* If st_other has a processor-specific meaning, specific code might be needed here. */ if (bed->elf_backend_merge_symbol_attribute) - (*bed->elf_backend_merge_symbol_attribute) (h, isym, definition, + (*bed->elf_backend_merge_symbol_attribute) (h, st_other, definition, dynamic); if (!dynamic) { - unsigned symvis = ELF_ST_VISIBILITY (isym->st_other); + unsigned symvis = ELF_ST_VISIBILITY (st_other); unsigned hvis = ELF_ST_VISIBILITY (h->other); /* Keep the most constraining visibility. Leave the remainder @@ -1028,7 +1028,7 @@ elf_merge_st_other (bfd *abfd, struct elf_link_hash_entry *h, h->other = symvis | (h->other & ~ELF_ST_VISIBILITY (-1)); } else if (definition - && ELF_ST_VISIBILITY (isym->st_other) != STV_DEFAULT + && ELF_ST_VISIBILITY (st_other) != STV_DEFAULT && (sec->flags & SEC_READONLY) == 0) h->protected_def = 1; } @@ -1701,7 +1701,7 @@ _bfd_elf_merge_symbol (bfd *abfd, /* Merge st_other. If the symbol already has a dynamic index, but visibility says it should not be visible, turn it into a local symbol. */ - elf_merge_st_other (abfd, h, sym, sec, newdef, newdyn); + elf_merge_st_other (abfd, h, sym->st_other, sec, newdef, newdyn); if (h->dynindx != -1) switch (ELF_ST_VISIBILITY (h->other)) { @@ -2028,6 +2028,10 @@ _bfd_elf_add_default_symbol (bfd *abfd, ht = (struct elf_link_hash_entry *) hi->root.u.i.link; (*bed->elf_backend_copy_indirect_symbol) (info, ht, hi); + /* If we first saw a reference to SHORTNAME with non-default + visibility, merge that visibility to the @@VER symbol. */ + elf_merge_st_other (abfd, ht, hi->other, sec, TRUE, dynamic); + /* A reference to the SHORTNAME symbol from a dynamic library will be satisfied by the versioned symbol at runtime. In effect, we have a reference to the versioned symbol. */ @@ -2107,6 +2111,11 @@ _bfd_elf_add_default_symbol (bfd *abfd, h->ref_dynamic_nonweak |= hi->ref_dynamic_nonweak; hi->dynamic_def |= h->dynamic_def; + /* If we first saw a reference to @VER symbol with + non-default visibility, merge that visibility to the + @@VER symbol. */ + elf_merge_st_other (abfd, h, hi->other, sec, TRUE, dynamic); + /* See if the new flags lead us to realize that the symbol must be dynamic. */ if (! *dynsym) @@ -5173,7 +5182,8 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info) } /* Merge st_other field. */ - elf_merge_st_other (abfd, h, isym, sec, definition, dynamic); + elf_merge_st_other (abfd, h, isym->st_other, sec, + definition, dynamic); /* We don't want to make debug symbol dynamic. */ if (definition @@ -15027,7 +15037,7 @@ _bfd_elf_copy_link_hash_symbol_type (bfd *abfd, ehdest->target_internal = ehsrc->target_internal; isym.st_other = ehsrc->other; - elf_merge_st_other (abfd, ehdest, &isym, NULL, TRUE, FALSE); + elf_merge_st_other (abfd, ehdest, isym.st_other, NULL, TRUE, FALSE); } /* Append a RELA relocation REL to section S in BFD. */ diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c index a9924e7ec56..fcb61716795 100644 --- a/bfd/elfnn-aarch64.c +++ b/bfd/elfnn-aarch64.c @@ -2854,11 +2854,11 @@ elfNN_aarch64_copy_indirect_symbol (struct bfd_link_info *info, static void elfNN_aarch64_merge_symbol_attribute (struct elf_link_hash_entry *h, - const Elf_Internal_Sym *isym, + unsigned int st_other, bfd_boolean definition ATTRIBUTE_UNUSED, bfd_boolean dynamic ATTRIBUTE_UNUSED) { - unsigned int isym_sto = isym->st_other & ~ELF_ST_VISIBILITY (-1); + unsigned int isym_sto = st_other & ~ELF_ST_VISIBILITY (-1); unsigned int h_sto = h->other & ~ELF_ST_VISIBILITY (-1); if (isym_sto == h_sto) diff --git a/bfd/elfxx-mips.c b/bfd/elfxx-mips.c index c0970fb85d0..4ea04d48c02 100644 --- a/bfd/elfxx-mips.c +++ b/bfd/elfxx-mips.c @@ -16320,21 +16320,21 @@ const struct bfd_elf_special_section _bfd_mips_elf_special_sections[] = definiton of the symbol. */ void _bfd_mips_elf_merge_symbol_attribute (struct elf_link_hash_entry *h, - const Elf_Internal_Sym *isym, + unsigned int st_other, bfd_boolean definition, bfd_boolean dynamic ATTRIBUTE_UNUSED) { - if ((isym->st_other & ~ELF_ST_VISIBILITY (-1)) != 0) + if ((st_other & ~ELF_ST_VISIBILITY (-1)) != 0) { unsigned char other; - other = (definition ? isym->st_other : h->other); + other = (definition ? st_other : h->other); other &= ~ELF_ST_VISIBILITY (-1); h->other = other | ELF_ST_VISIBILITY (h->other); } if (!definition - && ELF_MIPS_IS_OPTIONAL (isym->st_other)) + && ELF_MIPS_IS_OPTIONAL (st_other)) h->other |= STO_OPTIONAL; } diff --git a/bfd/elfxx-mips.h b/bfd/elfxx-mips.h index 4d9630f2662..c84b9268352 100644 --- a/bfd/elfxx-mips.h +++ b/bfd/elfxx-mips.h @@ -144,7 +144,7 @@ extern unsigned long _bfd_elf_mips_mach extern bfd_vma _bfd_mips_elf_sign_extend (bfd_vma, int); extern void _bfd_mips_elf_merge_symbol_attribute - (struct elf_link_hash_entry *, const Elf_Internal_Sym *, bfd_boolean, bfd_boolean); + (struct elf_link_hash_entry *, unsigned int, bfd_boolean, bfd_boolean); extern char *_bfd_mips_elf_get_target_dtag (bfd_vma); extern bfd_boolean _bfd_mips_elf_ignore_undef_symbol (struct elf_link_hash_entry *); diff --git a/bfd/elfxx-x86.c b/bfd/elfxx-x86.c index 97de9f2b537..8246fe5bd1b 100644 --- a/bfd/elfxx-x86.c +++ b/bfd/elfxx-x86.c @@ -1624,7 +1624,7 @@ _bfd_x86_elf_always_size_sections (bfd *output_bfd, void _bfd_x86_elf_merge_symbol_attribute (struct elf_link_hash_entry *h, - const Elf_Internal_Sym *isym, + unsigned int st_other, bfd_boolean definition, bfd_boolean dynamic ATTRIBUTE_UNUSED) { @@ -1632,8 +1632,7 @@ _bfd_x86_elf_merge_symbol_attribute (struct elf_link_hash_entry *h, { struct elf_x86_link_hash_entry *eh = (struct elf_x86_link_hash_entry *) h; - eh->def_protected = (ELF_ST_VISIBILITY (isym->st_other) - == STV_PROTECTED); + eh->def_protected = ELF_ST_VISIBILITY (st_other) == STV_PROTECTED; } } diff --git a/bfd/elfxx-x86.h b/bfd/elfxx-x86.h index 75e0ae3eecb..d3bac465c86 100644 --- a/bfd/elfxx-x86.h +++ b/bfd/elfxx-x86.h @@ -638,8 +638,7 @@ extern bfd_boolean _bfd_x86_elf_always_size_sections (bfd *, struct bfd_link_info *); extern void _bfd_x86_elf_merge_symbol_attribute - (struct elf_link_hash_entry *, const Elf_Internal_Sym *, - bfd_boolean, bfd_boolean); + (struct elf_link_hash_entry *, unsigned int, bfd_boolean, bfd_boolean); extern void _bfd_x86_elf_copy_indirect_symbol (struct bfd_link_info *, struct elf_link_hash_entry *, diff --git a/ld/ChangeLog b/ld/ChangeLog index 9dbb473dcfe..7e09a2f2893 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,12 @@ +2020-12-01 Alan Modra + + * testsuite/ld-elf/pr26979a.s, + * testsuite/ld-elf/pr26979b.s, + * testsuite/ld-elf/pr26979c.s, + * testsuite/ld-elf/pr26979.ver, + * testsuite/ld-elf/pr26979a.d, + * testsuite/ld-elf/pr26979b.d: New tests. + 2020-11-29 H.J. Lu PR ld/26936 diff --git a/ld/testsuite/ld-elf/pr26979.ver b/ld/testsuite/ld-elf/pr26979.ver new file mode 100644 index 00000000000..46ddd300d7d --- /dev/null +++ b/ld/testsuite/ld-elf/pr26979.ver @@ -0,0 +1 @@ +v1 {}; diff --git a/ld/testsuite/ld-elf/pr26979a.d b/ld/testsuite/ld-elf/pr26979a.d new file mode 100644 index 00000000000..1b42598290d --- /dev/null +++ b/ld/testsuite/ld-elf/pr26979a.d @@ -0,0 +1,12 @@ +#source: pr26979a.s +#source: pr26979c.s +#target: [check_shared_lib_support] +#as: +#ld: -shared --version-script=pr26979.ver +#readelf: -sW + +#... +.* GLOBAL PROTECTED .*foo@@v1 +#... +.* GLOBAL PROTECTED .*foo@@v1 +#pass diff --git a/ld/testsuite/ld-elf/pr26979a.s b/ld/testsuite/ld-elf/pr26979a.s new file mode 100644 index 00000000000..c70c7563023 --- /dev/null +++ b/ld/testsuite/ld-elf/pr26979a.s @@ -0,0 +1,3 @@ + .protected foo + .data + .dc.a foo diff --git a/ld/testsuite/ld-elf/pr26979b.d b/ld/testsuite/ld-elf/pr26979b.d new file mode 100644 index 00000000000..06973686e01 --- /dev/null +++ b/ld/testsuite/ld-elf/pr26979b.d @@ -0,0 +1,12 @@ +#source: pr26979b.s +#source: pr26979c.s +#target: [check_shared_lib_support] +#as: +#ld: -shared --version-script=pr26979.ver +#readelf: -sW + +#... +.* GLOBAL PROTECTED .*foo@@v1 +#... +.* GLOBAL PROTECTED .*foo@@v1 +#pass diff --git a/ld/testsuite/ld-elf/pr26979b.s b/ld/testsuite/ld-elf/pr26979b.s new file mode 100644 index 00000000000..e078857d73e --- /dev/null +++ b/ld/testsuite/ld-elf/pr26979b.s @@ -0,0 +1,4 @@ + .protected foo_v1 + .symver foo_v1, foo@v1 + .data + .dc.a foo_v1 diff --git a/ld/testsuite/ld-elf/pr26979c.s b/ld/testsuite/ld-elf/pr26979c.s new file mode 100644 index 00000000000..f74dc1c6f75 --- /dev/null +++ b/ld/testsuite/ld-elf/pr26979c.s @@ -0,0 +1,3 @@ + .globl foo + .symver foo, foo@@@v1 +foo: -- 2.30.2