[binutils-gdb] PR26979, Visibility of undefined foo@v1 should constrain foo@@v1

Alan Modra amodra@sourceware.org
Tue Dec 1 01:00:09 GMT 2020


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=5160d0f323d47031cb73c39a4dbd31d8976b4c8e

commit 5160d0f323d47031cb73c39a4dbd31d8976b4c8e
Author: Alan Modra <amodra@gmail.com>
Date:   Mon Nov 30 19:19:00 2020 +1030

    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.

Diff:
---
 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(-)

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  <amodra@gmail.com>
+
+	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  <amodra@gmail.com>
 
 	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  <amodra@gmail.com>
+
+	* 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  <hongjiu.lu@intel.com>
 
 	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:


More information about the Binutils-cvs mailing list