This is the mail archive of the binutils@sources.redhat.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]
Other format: [Raw text]

PATCH: Fix the weak undefined symbols with non-default visibility


For weak undefined symbols with non-default visibility, they are
supposed to be resolved to 0 and stay 0 at the run-time. Ld can help
ld.so by removing their dynamic relocations.


H.J.
----
bfd/

2003-04-07  H.J. Lu <hjl@gnu.org>

	* elf32-i386.c (allocate_dynrelocs): Don't allocate dynamic
	relocation entries for weak undefined symbols with non-default
	visibility.
	(elf_i386_relocate_section): Initialize the GOT entries and
	skip R_386_32/R_386_PC32 for weak undefined symbols with
	non-default visibility.
 
	* elfxx-ia64.c (allocate_fptr): Don't allocate function
	descriptors for weak undefined symbols with non-default
	visibility.
	(allocate_dynrel_entries): Don't allocate relocation entries
	for symbols resolved to 0.
	(set_got_entry): Don't install dynamic relocation for weak
	undefined symbols with non-default visibility.
	(set_pltoff_entry): Likewise.

	* elflink.h (elf_fix_symbol_flags): Hide weak undefined symbols
	with non-default visibility.
	(elf_link_output_extsym): Don't make weak undefined symbols
	with non-default visibility dynamic.

ld/testsuite/

2003-04-07  H.J. Lu <hjl@gnu.org>

	* ld-elfvsb/main.c: Updated.
	* ld-elfvsb/sh1.c: Likewise.

--- binutils/bfd/elf32-i386.c.zero	2003-03-07 16:44:56.000000000 -0800
+++ binutils/bfd/elf32-i386.c	2003-04-08 09:26:07.000000000 -0700
@@ -1568,8 +1568,10 @@ allocate_dynrelocs (h, inf)
 	    return FALSE;
 	}
 
-      if (info->shared
-	  || WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, 0, h))
+      if ((ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+	   || h->root.type != bfd_link_hash_undefweak)
+	  && (info->shared
+	      || WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, 0, h)))
 	{
 	  asection *s = htab->splt;
 
@@ -1655,8 +1657,10 @@ allocate_dynrelocs (h, inf)
 	htab->srelgot->_raw_size += sizeof (Elf32_External_Rel);
       else if (tls_type == GOT_TLS_GD)
 	htab->srelgot->_raw_size += 2 * sizeof (Elf32_External_Rel);
-      else if (info->shared
-	       || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, h))
+      else if ((ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+		|| h->root.type != bfd_link_hash_undefweak)
+	       && (info->shared
+		   || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, h)))
 	htab->srelgot->_raw_size += sizeof (Elf32_External_Rel);
     }
   else
@@ -2297,7 +2301,9 @@ elf_i386_relocate_section (output_bfd, i
 		      && (info->symbolic
 			  || h->dynindx == -1
 			  || (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL))
-		      && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)))
+		      && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR))
+		  || (ELF_ST_VISIBILITY (h->other)
+		      && h->root.type == bfd_link_hash_undefweak))
 		{
 		  /* This is actually a static link, or it is a
 		     -Bsymbolic link and the symbol is defined
@@ -2421,6 +2427,9 @@ elf_i386_relocate_section (output_bfd, i
 	    break;
 
 	  if ((info->shared
+	       && (h == NULL
+		   || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+		   || h->root.type != bfd_link_hash_undefweak)
 	       && (r_type != R_386_PC32
 		   || (h != NULL
 		       && h->dynindx != -1
--- binutils/bfd/elflink.h.zero	2003-04-08 08:57:59.000000000 -0700
+++ binutils/bfd/elflink.h	2003-04-08 09:26:07.000000000 -0700
@@ -4001,6 +4001,16 @@ elf_fix_symbol_flags (h, eif)
       (*bed->elf_backend_hide_symbol) (eif->info, h, force_local);
     }
 
+  /* If a weak undefined symbol has non-default visibility, we also
+     hide it from the dynamic linker.  */
+  if (ELF_ST_VISIBILITY (h->other)
+      && h->root.type == bfd_link_hash_undefweak)
+    {
+      struct elf_backend_data *bed;
+      bed = get_elf_backend_data (elf_hash_table (eif->info)->dynobj);
+      (*bed->elf_backend_hide_symbol) (eif->info, h, TRUE);
+    }
+
   /* If this is a weak defined symbol in a dynamic object, and we know
      the real definition in the dynamic object, copy interesting flags
      over to the real definition.  */
@@ -6396,7 +6406,9 @@ elf_link_output_extsym (h, data)
      forced local syms when non-shared is due to a historical quirk.  */
   if ((h->dynindx != -1
        || (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) != 0)
-      && (finfo->info->shared
+      && ((finfo->info->shared
+	   && (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+	       || h->root.type != bfd_link_hash_undefweak))
 	  || (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0)
       && elf_hash_table (finfo->info)->dynamic_sections_created)
     {
--- binutils/bfd/elfxx-ia64.c.zero	2003-04-01 14:28:52.000000000 -0800
+++ binutils/bfd/elfxx-ia64.c	2003-04-08 09:26:07.000000000 -0700
@@ -2622,7 +2622,10 @@ allocate_fptr (dyn_i, data)
 	       || h->root.type == bfd_link_hash_warning)
 	  h = (struct elf_link_hash_entry *) h->root.u.i.link;
 
-      if (x->info->shared
+      if ((x->info->shared
+	   && (!h
+	       || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+	       || h->root.type != bfd_link_hash_undefweak))
 	  /* AIX needs an FPTR in this case. */
 	  || (elfNN_ia64_aix_vec (x->info->hash->creator)
 	      && (!h
@@ -2747,15 +2750,18 @@ allocate_dynrel_entries (dyn_i, data)
   struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
   struct elfNN_ia64_link_hash_table *ia64_info;
   struct elfNN_ia64_dyn_reloc_entry *rent;
-  bfd_boolean dynamic_symbol, shared;
+  bfd_boolean dynamic_symbol, shared, resolved_zero;
 
   ia64_info = elfNN_ia64_hash_table (x->info);
   dynamic_symbol = elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info)
     || (elfNN_ia64_aix_vec (x->info->hash->creator)
 	/* Don't allocate an entry for __GLOB_DATA_PTR */
 	&& (!dyn_i->h || strcmp (dyn_i->h->root.root.string,
-	  "__GLOB_DATA_PTR") != 0));
+				 "__GLOB_DATA_PTR") != 0));
   shared = x->info->shared;
+  resolved_zero = dyn_i->h
+    && ELF_ST_VISIBILITY (dyn_i->h->other)
+    && dyn_i->h->root.type == bfd_link_hash_undefweak;
 
   /* Take care of the normal data relocations.  */
 
@@ -2800,8 +2806,12 @@ allocate_dynrel_entries (dyn_i, data)
 
   /* Take care of the GOT and PLT relocations.  */
 
-  if (((dynamic_symbol || shared) && (dyn_i->want_got || dyn_i->want_gotx))
-      || (dyn_i->want_ltoff_fptr && dyn_i->h && dyn_i->h->dynindx != -1))
+  if ((!resolved_zero
+       && (dynamic_symbol || shared)
+       && (dyn_i->want_got || dyn_i->want_gotx))
+      || (dyn_i->want_ltoff_fptr
+	  && dyn_i->h
+	  && dyn_i->h->dynindx != -1))
     ia64_info->rel_got_sec->_raw_size += sizeof (ElfNN_External_Rela);
   if ((dynamic_symbol || shared) && dyn_i->want_tprel)
     ia64_info->rel_got_sec->_raw_size += sizeof (ElfNN_External_Rela);
@@ -2810,7 +2820,7 @@ allocate_dynrel_entries (dyn_i, data)
   if (dynamic_symbol && dyn_i->want_dtprel)
     ia64_info->rel_got_sec->_raw_size += sizeof (ElfNN_External_Rela);
 
-  if (dyn_i->want_pltoff)
+  if (!resolved_zero && dyn_i->want_pltoff)
     {
       bfd_size_type t = 0;
 
@@ -3418,7 +3428,11 @@ set_got_entry (abfd, info, dyn_i, dynind
       bfd_put_64 (abfd, value, got_sec->contents + got_offset);
 
       /* Install a dynamic relocation if needed.  */
-      if ((info->shared && dyn_r_type != R_IA64_DTPREL64LSB)
+      if ((info->shared
+	   && (!dyn_i->h
+	       || ELF_ST_VISIBILITY (dyn_i->h->other) == STV_DEFAULT
+	       || dyn_i->h->root.type != bfd_link_hash_undefweak)
+	   && dyn_r_type != R_IA64_DTPREL64LSB)
           || elfNN_ia64_dynamic_symbol_p (dyn_i->h, info)
 	  || elfNN_ia64_aix_vec (abfd->xvec)
 	  || (dynindx != -1 && dyn_r_type == R_IA64_FPTR64LSB))
@@ -3539,7 +3553,11 @@ set_pltoff_entry (abfd, info, dyn_i, val
       bfd_put_64 (abfd, gp, pltoff_sec->contents + dyn_i->pltoff_offset + 8);
 
       /* Install dynamic relocations if needed.  */
-      if (!is_plt && info->shared)
+      if (!is_plt
+	  && info->shared
+	  && (!dyn_i->h
+	      || ELF_ST_VISIBILITY (dyn_i->h->other) == STV_DEFAULT
+	      || dyn_i->h->root.type != bfd_link_hash_undefweak))
 	{
 	  unsigned int dyn_r_type;
 
--- binutils/ld/testsuite/ld-elfvsb/main.c.zero	2003-04-08 09:22:47.000000000 -0700
+++ binutils/ld/testsuite/ld-elfvsb/main.c	2003-04-08 09:25:44.000000000 -0700
@@ -165,6 +165,37 @@ main_visibility_checkweak ()
 {
   return 1;
 }
+#elif defined (HIDDEN_WEAK_TEST)
+int
+main_visibility_checkcom ()
+{
+  return 1;
+}
+
+#pragma weak visibility_undef_var_weak
+extern int visibility_undef_var_weak;
+asm (".hidden visibility_undef_var_weak");
+
+#pragma weak visibility_undef_func_weak
+extern int visibility_undef_func_weak ();
+asm (".hidden visibility_undef_func_weak");
+
+#pragma weak visibility_var_weak
+extern int visibility_var_weak;
+asm (".hidden visibility_var_weak");
+
+#pragma weak visibility_func_weak
+extern int visibility_func_weak ();
+asm (".hidden visibility_func_weak");
+
+int
+main_visibility_checkweak ()
+{
+  return &visibility_undef_var_weak == NULL
+	 && &visibility_undef_func_weak == NULL
+	 && &visibility_func_weak == NULL
+	 && &visibility_var_weak == NULL;
+}
 #elif defined (HIDDEN_UNDEF_TEST)
 extern int visibility_def;
 asm (".hidden visibility_def");
--- binutils/ld/testsuite/ld-elfvsb/sh1.c.zero	2003-04-08 09:22:18.000000000 -0700
+++ binutils/ld/testsuite/ld-elfvsb/sh1.c	2003-04-08 09:25:36.000000000 -0700
@@ -339,6 +339,37 @@ shlib_visibility_checkweak ()
 {
   return 1;
 }
+#elif defined (HIDDEN_WEAK_TEST)
+#pragma weak shlib_visibility_undef_var_weak
+extern int shlib_visibility_undef_var_weak;
+asm (".hidden shlib_visibility_undef_var_weak");
+
+#pragma weak shlib_visibility_undef_func_weak
+extern int shlib_visibility_undef_func_weak ();
+asm (".hidden shlib_visibility_undef_func_weak");
+
+#pragma weak shlib_visibility_var_weak
+extern int shlib_visibility_var_weak;
+asm (".hidden shlib_visibility_var_weak");
+
+#pragma weak shlib_visibility_func_weak
+extern int shlib_visibility_func_weak ();
+asm (".hidden shlib_visibility_func_weak");
+
+int
+shlib_visibility_checkcom ()
+{
+  return 1;
+}
+
+int
+shlib_visibility_checkweak ()
+{
+  return &shlib_visibility_undef_var_weak == NULL
+	 && &shlib_visibility_undef_func_weak == NULL
+	 && &shlib_visibility_func_weak == NULL
+	 && &shlib_visibility_var_weak == NULL;
+}
 #else
 int
 shlib_visibility_checkcom ()


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