This is the mail archive of the libc-hacker@sourceware.cygnus.com mailing list for the glibc project.

Note that libc-hacker is a closed list. You may look at the archives of this list, but subscription and posting are not open.


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

A patch for binutils (Re: the setrlimit changes in glibc 2.1.3)


> > > 
> > > Install glibc 2.1.2 (before the setrlimit changes), do a "make libfoo.so",
> > > then upgrade to the current glibc and in the same directory do a "make
> > > test". The link will fail.
> > > 
> > 
> > Thanks. It is what I need. I will try to fix the linker.
> 
> I happen to have this testcase handy.  It may be easier to deal with
> (it could actually be turned into an expect test for the linker).
> 
> Just do 'make'.  It should build properly, but it doesn't.
> 

Thanks. Here is a patch for binutils 2.9.5.0.22. Ian, what do you
think?


H.J.
----
Thu Jan 13 11:03:29 2000  H.J. Lu  <hjl@gnu.org>

	* elflink.h (elf_link_add_object_symbols): Bound the external
	references to the default version to the hidden version.

Index: elflink.h
===================================================================
RCS file: /work/cvs/gnu/binutils/bfd/elflink.h,v
retrieving revision 1.14
diff -u -p -r1.14 elflink.h
--- elflink.h	1999/11/01 22:47:51	1.14
+++ elflink.h	2000/01/13 19:18:31
@@ -1463,7 +1463,12 @@ elf_link_add_object_symbols (abfd, info)
              version, we create an indirect symbol from the default
              name to the fully decorated name.  This will cause
              external references which do not specify a version to be
-             bound to this version of the symbol.  */
+             bound to this version of the symbol.
+	     
+	     If this symbol is hidden, we create an indirect symbol
+	     from the default version the hidden one. This will cause
+	     external references to the default version to be bound to
+	     this symbol. */
 	  if (definition)
 	    {
 	      char *p;
@@ -1738,6 +1743,117 @@ elf_link_add_object_symbols (abfd, info)
 				       & ELF_LINK_HASH_REF_REGULAR) != 0)
 				    dynsym = true;
 				}
+			    }
+			}
+		    }
+		}
+	      else if (p != NULL)
+		{
+		  char *defaultversion;
+		  struct elf_link_hash_entry *hi;
+		  boolean override;
+
+		  defaultversion = bfd_hash_allocate (&info->hash->table,
+						 strlen (name) + 2);
+		  if (defaultversion == NULL)
+		    goto error_return;
+		  strncpy (defaultversion, name, p - name + 1);
+		  defaultversion[p - name + 1] = ELF_VER_CHR;
+		  strcpy (&defaultversion[p - name + 2], p + 1);
+
+		  /* We are going to create a new symbol.  Merge it
+                     with any existing symbol with this name.  For the
+                     purposes of the merge, act as though we were
+                     defining the symbol we just defined, although we
+                     actually going to define an indirect symbol.  */
+		  type_change_ok = false;
+		  size_change_ok = false;
+		  if (! elf_merge_symbol (abfd, info, defaultversion, &sym, &sec,
+					  &value, &hi, &override,
+					  &type_change_ok, &size_change_ok))
+		    goto error_return;
+
+		  if (override
+		      || ! (_bfd_generic_link_add_one_symbol
+			    (info, abfd, defaultversion, BSF_INDIRECT,
+			     bfd_ind_section_ptr, (bfd_vma) 0, name, false,
+			     collect, (struct bfd_link_hash_entry **) &hi)))
+		    goto error_return;
+
+		  /* If there is a duplicate definition somewhere,
+		     then HI may not point to an indirect symbol.  We
+		     will have reported an error to the user in that
+		     case.  */
+
+		  if (hi->root.type == bfd_link_hash_indirect)
+		    {
+		      struct elf_link_hash_entry *ht;
+
+		      /* If the symbol became indirect, then we assume
+			 that we have not seen a definition before.  */
+		      BFD_ASSERT ((hi->elf_link_hash_flags
+				   & (ELF_LINK_HASH_DEF_DYNAMIC
+				      | ELF_LINK_HASH_DEF_REGULAR))
+				  == 0);
+
+		      ht = (struct elf_link_hash_entry *) hi->root.u.i.link;
+
+		      /* Copy down any references that we may have
+			 already seen to the symbol which just became
+			 indirect.  */
+		      ht->elf_link_hash_flags |=
+			(hi->elf_link_hash_flags
+			 & (ELF_LINK_HASH_REF_DYNAMIC
+			    | ELF_LINK_HASH_REF_REGULAR
+			    | ELF_LINK_HASH_REF_REGULAR_NONWEAK
+			    | ELF_LINK_NON_GOT_REF));
+
+		      /* Copy over the global and procedure linkage table
+			 offset entries.  These may have been already set
+			 up by a check_relocs routine.  */
+		      if (ht->got.offset == (bfd_vma) -1)
+			{
+			  ht->got.offset = hi->got.offset;
+			  hi->got.offset = (bfd_vma) -1;
+			}
+		      BFD_ASSERT (hi->got.offset == (bfd_vma) -1);
+
+		      if (ht->plt.offset == (bfd_vma) -1)
+			{
+			  ht->plt.offset = hi->plt.offset;
+			  hi->plt.offset = (bfd_vma) -1;
+			}
+		      BFD_ASSERT (hi->plt.offset == (bfd_vma) -1);
+
+		      if (ht->dynindx == -1)
+			{
+			  ht->dynindx = hi->dynindx;
+			  ht->dynstr_index = hi->dynstr_index;
+			  hi->dynindx = -1;
+			  hi->dynstr_index = 0;
+			}
+		      BFD_ASSERT (hi->dynindx == -1);
+
+		      /* FIXME: There may be other information to copy
+			 over for particular targets.  */
+
+		      /* See if the new flags lead us to realize that
+			 the symbol must be dynamic.  */
+		      if (! dynsym)
+			{
+			  if (! dynamic)
+			    {
+			      if (info->shared
+				  || ((hi->elf_link_hash_flags
+				       & ELF_LINK_HASH_REF_DYNAMIC)
+				      != 0))
+				dynsym = true;
+			    }
+			  else
+			    {
+			      if ((hi->elf_link_hash_flags
+				   & ELF_LINK_HASH_REF_REGULAR) != 0)
+				dynsym = true;
 			    }
 			}
 		    }

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