PATCH: Fix visibility for MIPS (Re: 2 problems with ELF visibility)

H . J . Lu hjl@lucon.org
Mon Apr 22 12:44:00 GMT 2002


On Mon, Apr 22, 2002 at 12:06:57PM -0700, H . J . Lu wrote:
> There are 2 problems with ELF visibility:
> 
> 2. _bfd_elf_link_record_dynamic_symbol in elflink.c doesn't call
> elf_backend_hide_symbol. Instead, it sets ELF_LINK_FORCED_LOCAL directly.
> It doesn't work with MIPS. I got
> 
> mips-linux-gcc -O2 -pipe -D_GNU_SOURCE -D_REENTRANT -Wall -Wpointer-arith
> -Wstrict-prototypes -Wmissing-prototypes -Wno-char-subscripts -o test1 -static
> test1.o  ./.libs/libpopt.a
> /export/tools/lib/gcc-lib/mips-linux/2.96/../../../../mips-linux/bin/ld: not enough
> GOT space for local GOT entries
> /export/tools/lib/gcc-lib/mips-linux/2.96/../../../../mips-linux/bin/ld: BFD
> 2.12.90.0.5 20020421 internal error, aborting at
> /home/hjl/work/gnu/src/tools/tools/bfd/elfxx-mips.c line 5276 in
> _bfd_mips_elf_relocate_section
> 
> You have to use elf_backend_hide_symbol to turn a global symbol into local
> on MIPS. How should we fix it?
> 

I am enclosing a patch here. Any comments?


H.J.
-------------- next part --------------
2002-04-22  H.J. Lu  (hjl@gnu.org)

	* elfxx-mips.c (mips_elf_link_hash_entry): Add forced_local.
	(mips_elf_link_hash_newfunc): Initialize forced_local to false.
	(mips_elf_record_global_got_symbol): Call _bfd_mips_elf_hide_symbol
	to hide a global symbol.
	(_bfd_mips_elf_hide_symbol): Return if forced_local is true. Set
	forced_local to true. 

--- bfd/elfxx-mips.c.visi	Sun Apr 21 16:57:52 2002
+++ bfd/elfxx-mips.c	Mon Apr 22 12:40:50 2002
@@ -116,6 +116,9 @@ struct mips_elf_link_hash_entry
   /* This is like the call_stub field, but it is used if the function
      being called returns a floating point value.  */
   asection *call_fp_stub;
+
+  /* Are we forced local?  .*/
+  boolean forced_local;
 };
 
 /* MIPS ELF linker hash table.  */
@@ -582,6 +585,7 @@ mips_elf_link_hash_newfunc (entry, table
       ret->need_fn_stub = false;
       ret->call_stub = NULL;
       ret->call_fp_stub = NULL;
+      ret->forced_local = false;
     }
 
   return (struct bfd_hash_entry *) ret;
@@ -1686,9 +1690,18 @@ mips_elf_record_global_got_symbol (h, in
 {
   /* A global symbol in the GOT must also be in the dynamic symbol
      table.  */
-  if (h->dynindx == -1
-      && !bfd_elf32_link_record_dynamic_symbol (info, h))
-    return false;
+  if (h->dynindx == -1)
+    {
+      switch (ELF_ST_VISIBILITY (h->other))
+	{
+	case STV_INTERNAL:
+	case STV_HIDDEN:
+	  _bfd_mips_elf_hide_symbol (info, h, true);
+	  break;
+	}
+      if (!bfd_elf32_link_record_dynamic_symbol (info, h))
+	return false;
+    }
 
   /* If we've already marked this entry as needing GOT space, we don't
      need to do it again.  */
@@ -6451,7 +6464,12 @@ _bfd_mips_elf_hide_symbol (info, entry, 
   asection *got;
   struct mips_got_info *g;
   struct mips_elf_link_hash_entry *h;
+
   h = (struct mips_elf_link_hash_entry *) entry;
+  if (h->forced_local)
+    return;
+  h->forced_local = true;
+
   dynobj = elf_hash_table (info)->dynobj;
   got = bfd_get_section_by_name (dynobj, ".got");
   g = (struct mips_got_info *) elf_section_data (got)->tdata;


More information about the Binutils mailing list