This is the mail archive of the binutils-cvs@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[binutils-gdb] Relax PR 15228 protected visibility restriction


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

commit b84171287ffe60dd1e7c02262a0493862fa21a97
Author: Alan Modra <amodra@gmail.com>
Date:   Fri Mar 27 15:41:05 2015 +1030

    Relax PR 15228 protected visibility restriction
    
    Allows .dynbss copy of shared library protected visibility variables
    if they are read-only.
    
    To recap: Copying a variable from a shared library into an executable's
    .dynbss is an old hack invented for non-PIC executables, to avoid the
    text relocations you'd otherwise need to access a shared library
    variable.  This works with ELF shared libraries because global
    symbols can be overridden.  The trouble is that protected visibility
    symbols can't be overridden.  A shared library will continue to access
    it's own protected visibility variable while the executable accesses a
    copy.  If either the shared library or the executable updates the
    value then the copy diverges from the original.  This is wrong since
    there is only one definition of the variable in the application.
    
    So I made the linker report an error on attempting to copy protected
    visibility variables into .dynbss.  However, you'll notice the above
    paragraph contains an "If".  An application that does not modify the
    variable value remains correct even though two copies of the variable
    exist.  The linker can detect this situation if the variable was
    defined in a read-only section.
    
    	PR ld/15228
    	PR ld/18167
    	* elflink.c (elf_merge_st_other): Add "sec" parameter.  Don't set
    	protected_def when symbol section is read-only.  Adjust all calls.
    	* elf-bfd.h (struct elf_link_hash_entry): Update protected_def comment.

Diff:
---
 bfd/ChangeLog |  8 ++++++++
 bfd/elf-bfd.h |  3 ++-
 bfd/elflink.c | 12 +++++++-----
 3 files changed, 17 insertions(+), 6 deletions(-)

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 7dea00e..cc8f96f 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,11 @@
+2015-03-27  Alan Modra  <amodra@gmail.com>
+
+	PR ld/15228
+	PR ld/18167
+	* elflink.c (elf_merge_st_other): Add "sec" parameter.  Don't set
+	protected_def when symbol section is read-only.  Adjust all calls.
+	* elf-bfd.h (struct elf_link_hash_entry): Update protected_def comment.
+
 2015-03-26  Tejas Belagod  <tejas.belagod@arm.com>
 
 	* elfnn-aarch64.c (aarch64_build_one_stub): Replace the call to generic
diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h
index 13c32e0..53ef9d8 100644
--- a/bfd/elf-bfd.h
+++ b/bfd/elf-bfd.h
@@ -200,7 +200,8 @@ struct elf_link_hash_entry
   unsigned int pointer_equality_needed : 1;
   /* Symbol is a unique global symbol.  */
   unsigned int unique_global : 1;
-  /* Symbol is defined with non-default visibility.  */
+  /* Symbol is defined by a shared library with non-default visibility
+     in a read/write section.  */
   unsigned int protected_def : 1;
 
   /* String table index in .dynstr if this is a dynamic symbol.  */
diff --git a/bfd/elflink.c b/bfd/elflink.c
index 748ff1b..022a535 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -844,7 +844,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,
+		    const Elf_Internal_Sym *isym, asection *sec,
 		    bfd_boolean definition, bfd_boolean dynamic)
 {
   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
@@ -865,7 +865,9 @@ elf_merge_st_other (bfd *abfd, struct elf_link_hash_entry *h,
       if (symvis - 1 < hvis - 1)
 	h->other = symvis | (h->other & ~ELF_ST_VISIBILITY (-1));
     }
-  else if (definition && ELF_ST_VISIBILITY (isym->st_other) != STV_DEFAULT)
+  else if (definition
+	   && ELF_ST_VISIBILITY (isym->st_other) != STV_DEFAULT
+	   && (sec->flags & SEC_READONLY) == 0)
     h->protected_def = 1;
 }
 
@@ -1417,7 +1419,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, newdef, newdyn);
+      elf_merge_st_other (abfd, h, sym, sec, newdef, newdyn);
       if (h->dynindx != -1)
 	switch (ELF_ST_VISIBILITY (h->other))
 	  {
@@ -4358,7 +4360,7 @@ error_free_dyn:
 	    }
 
 	  /* Merge st_other field.  */
-	  elf_merge_st_other (abfd, h, isym, definition, dynamic);
+	  elf_merge_st_other (abfd, h, isym, sec, definition, dynamic);
 
 	  /* We don't want to make debug symbol dynamic.  */
 	  if (definition && (sec->flags & SEC_DEBUGGING) && !info->relocatable)
@@ -13268,7 +13270,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, TRUE, FALSE);
+  elf_merge_st_other (abfd, ehdest, &isym, NULL, TRUE, FALSE);
 }
 
 /* Append a RELA relocation REL to section S in BFD.  */


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]