This is the mail archive of the binutils@sourceware.cygnus.com 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]

Re: Symbol visibility revised


On Mon, May 01, 2000 at 09:50:56PM +0200, Martin v. Loewis wrote:
> > Here is the testcase. It failed with your patch.
> 
> I can't reproduce the failure:
> 
> mira% make
> cc -S  -fPIC -O -B./ foo.c
> echo ".hidden bar" >> foo.s
> cc -O -B./ -c foo.s
> cc -shared -o libfoo.so -O -B./ foo.o
> cc -o foo -O -B./ libfoo.so main.c -Wl,-rpath,. -rdynamic
> for f in foo; do echo "Running: $f"; ./$f; \
>   if [ $? != 0 ]; then echo Failed; fi; done
> Running: foo
> Hello
> 

You are right. Here is the modified patch. We should remove PLT
only for hidden and internal symbols.


H.J.
--- bfd/elflink.c.visi	Mon May  1 13:17:51 2000
+++ bfd/elflink.c	Mon May  1 13:17:58 2000
@@ -238,8 +238,8 @@ _bfd_elf_link_record_dynamic_symbol (inf
 	    }
 	  
 	  h->elf_link_hash_flags |= ELF_LINK_FORCED_LOCAL;
-	  break;
-	  
+	  return true;
+
 	default:
 	  break;
 	}
--- bfd/elflink.h.visi	Mon May  1 13:17:54 2000
+++ bfd/elflink.h	Mon May  1 13:36:39 2000
@@ -891,6 +891,7 @@ elf_link_add_object_symbols (abfd, info)
   Elf_External_Sym *esym;
   Elf_External_Sym *esymend;
   struct elf_backend_data *bed;
+  boolean visibility_changed = false;
 
   bed = get_elf_backend_data (abfd);
   add_symbol_hook = bed->elf_add_symbol_hook;
@@ -1581,7 +1582,10 @@ elf_link_add_object_symbols (abfd, info)
 	      unsigned char symvis = ELF_ST_VISIBILITY (sym.st_other);
 	      
 	      if (symvis && (hvis > symvis || hvis == 0))
-		h->other = sym.st_other;
+		{
+		  visibility_changed = true;
+		  h->other = sym.st_other;
+		}
 	      
 	      /* If neither has visibility, use the st_other of the
 	         definition.  This is an arbitrary choice, since the
@@ -1852,6 +1856,18 @@ elf_link_add_object_symbols (abfd, info)
 		    goto error_return;
 		}
 	    }
+	  else if (dynsym && h->dynindx != -1 && visibility_changed)
+	    /* If the symbol already has a dynamic index, but
+	       visibility says it should not be visible, turn it into
+	       a local symbol.  */
+	    switch (ELF_ST_VISIBILITY (h->other))
+	      {
+	      case STV_INTERNAL:
+	      case STV_HIDDEN:  
+		h->elf_link_hash_flags |= ELF_LINK_FORCED_LOCAL;
+		(*bed->elf_backend_hide_symbol) (h);
+		break;
+	      }
 	}
     }
 
@@ -3339,10 +3355,13 @@ elf_fix_symbol_flags (h, eif)
   /* If -Bsymbolic was used (which means to bind references to global
      symbols to the definition within the shared object), and this
      symbol was defined in a regular object, then it actually doesn't
-     need a PLT entry.  */
+     need a PLT entry.  Likewise, if the symbol has internal or
+     hidden visibility, it doesn't need a PLT.  */
   if ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0
       && eif->info->shared
-      && eif->info->symbolic
+      && (eif->info->symbolic
+          || (ELF_ST_VISIBILITY (h->other)
+	      & (STV_INTERNAL | STV_HIDDEN)))
       && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) != 0)
     {
       h->elf_link_hash_flags &=~ ELF_LINK_HASH_NEEDS_PLT;

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