hooks for versioning symbol manipulation

Richard Henderson rth@cygnus.com
Sun Feb 13 15:15:00 GMT 2000


The elf symbol versioning code had a long-standing

    /* FIXME: There may be other information to copy
       over for particular targets.  */

Well, IA-64 is such a target.  PA64 is as well, but since
they're not using glibc on HP/UX, no one's noticed.


r~


        * elf-bfd.h (struct elf_link_hash_table): Add copy_indirect and
        hide_symbol members.
        (elf_link_hash_copy_indirect): New.
        (elf_link_hash_hide_symbol): New.
        * elflink.h (elf_link_add_object_symbols): Break out copy from 
        indirect new new symbol to elf.c.
        (elf_link_assign_sym_version): Break out privatization of
        non-exported symbol to elf.c.
        * elf.c (_bfd_elf_link_hash_copy_indirect): New.
        (_bfd_elf_link_hash_hide_symbol): New.
        (_bfd_elf_link_hash_table_init): Init copy_indirect and hide_symbol.

Index: elf-bfd.h
===================================================================
RCS file: /cvs/cvsfiles/devo/bfd/elf-bfd.h,v
retrieving revision 1.57
diff -c -p -d -r1.57 elf-bfd.h
*** elf-bfd.h	1999/11/26 01:57:45	1.57
--- elf-bfd.h	2000/02/13 22:03:40
*************** struct elf_link_hash_table
*** 240,245 ****
--- 240,251 ----
    PTR stab_info;
    /* A linked list of local symbols to be added to .dynsym.  */
    struct elf_link_local_dynamic_entry *dynlocal;
+ 
+   void (*copy_indirect) PARAMS ((struct elf_link_hash_table *,
+ 				 struct elf_link_hash_entry *,
+ 				 struct elf_link_hash_entry *));
+   void (*hide_symbol) PARAMS ((struct elf_link_hash_table *,
+ 			       struct elf_link_hash_entry *));
  };
  
  /* Look up an entry in an ELF linker hash table.  */
*************** struct elf_link_hash_table
*** 260,265 ****
--- 266,281 ----
  /* Get the ELF linker hash table from a link_info structure.  */
  
  #define elf_hash_table(p) ((struct elf_link_hash_table *) ((p)->hash))
+ 
+ /* Call the copy_indirect method.  */
+ 
+ #define elf_link_hash_copy_indirect(TABLE,DIR,IND) \
+   ((*(TABLE)->copy_indirect) ((TABLE), (DIR), (IND)))
+ 
+ /* Call the hide_symbol method.  */
+ 
+ #define elf_link_hash_hide_symbol(TABLE,SYM) \
+   ((*(TABLE)->hide_symbol) ((TABLE), (SYM)))
  
  /* Constant information held for an ELF backend.  */
  
Index: elf.c
===================================================================
RCS file: /cvs/cvsfiles/devo/bfd/elf.c,v
retrieving revision 1.244
diff -c -p -d -r1.244 elf.c
*** elf.c	2000/01/19 00:04:34	1.244
--- elf.c	2000/02/13 22:03:40
*************** _bfd_elf_link_hash_newfunc (entry, table
*** 883,888 ****
--- 883,941 ----
    return (struct bfd_hash_entry *) ret;
  }
  
+ /* Copy data from an indirect symbol to its direct symbol, hiding the
+    old indirect symbol.  */
+ 
+ static void
+ _bfd_elf_link_hash_copy_indirect (table, dir, ind)
+      struct elf_link_hash_table *table;
+      struct elf_link_hash_entry *dir, *ind;
+ {
+   /* Copy down any references that we may have already seen to the
+      symbol which just became indirect.  */
+ 
+   dir->elf_link_hash_flags |=
+     (ind->elf_link_hash_flags
+      & (ELF_LINK_HASH_REF_DYNAMIC
+ 	| ELF_LINK_HASH_REF_REGULAR
+ 	| ELF_LINK_HASH_REF_REGULAR_NONWEAK));
+ 
+   /* Copy over the global and procedure linkage table offset entries.
+      These may have been already set up by a check_relocs routine.  */
+   if (dir->got.offset == (bfd_vma) -1)
+     {
+       dir->got.offset = ind->got.offset;
+       ind->got.offset = (bfd_vma) -1;
+     }
+   BFD_ASSERT (ind->got.offset == (bfd_vma) -1);
+ 
+   if (dir->plt.offset == (bfd_vma) -1)
+     {
+       dir->plt.offset = ind->plt.offset;
+       ind->plt.offset = (bfd_vma) -1;
+     }
+   BFD_ASSERT (ind->plt.offset == (bfd_vma) -1);
+ 
+   if (dir->dynindx == -1)
+     {
+       dir->dynindx = ind->dynindx;
+       dir->dynstr_index = ind->dynstr_index;
+       ind->dynindx = -1;
+       ind->dynstr_index = 0;
+     }
+   BFD_ASSERT (ind->dynindx == -1);
+ }
+ 
+ static void
+ _bfd_elf_link_hash_hide_symbol(table, h)
+      struct elf_link_hash_table *table;
+      struct elf_link_hash_entry *h;
+ {
+   h->elf_link_hash_flags &= ~ELF_LINK_HASH_NEEDS_PLT;
+   h->dynindx = -1;
+   h->plt.offset = (bfd_vma) -1;
+ }
+ 
  /* Initialize an ELF linker hash table.  */
  
  boolean
*************** _bfd_elf_link_hash_table_init (table, ab
*** 902,907 ****
--- 955,962 ----
    table->needed = NULL;
    table->hgot = NULL;
    table->stab_info = NULL;
+   table->copy_indirect = _bfd_elf_link_hash_copy_indirect;
+   table->hide_symbol = _bfd_elf_link_hash_hide_symbol;
    return _bfd_link_hash_table_init (&table->root, abfd, newfunc);
  }
  
Index: elflink.h
===================================================================
RCS file: /cvs/cvsfiles/devo/bfd/elflink.h,v
retrieving revision 1.146
diff -c -p -d -r1.146 elflink.h
*** elflink.h	1999/12/30 15:27:01	1.146
--- elflink.h	2000/02/13 22:03:40
*************** elf_link_add_object_symbols (abfd, info)
*** 1689,1732 ****
  				  == 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));
! 
! 		      /* 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.  */
--- 1689,1696 ----
  				  == 0);
  
  		      ht = (struct elf_link_hash_entry *) hi->root.u.i.link;
! 		      elf_link_hash_copy_indirect (elf_hash_table (info),
! 						   ht, hi);
  
  		      /* See if the new flags lead us to realize that
  			 the symbol must be dynamic.  */
*************** elf_link_add_object_symbols (abfd, info)
*** 1799,1841 ****
  					  | ELF_LINK_HASH_DEF_REGULAR))
  				      == 0);
  
! 			  /* Copy down any references that we may have
!                              already seen to the symbol which just
!                              became indirect.  */
! 			  h->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));
! 
! 			  /* Copy over the global and procedure linkage
!                              table offset entries.  These may have been
!                              already set up by a check_relocs routine.  */
! 			  if (h->got.offset == (bfd_vma) -1)
! 			    {
! 			      h->got.offset = hi->got.offset;
! 			      hi->got.offset = (bfd_vma) -1;
! 			    }
! 			  BFD_ASSERT (hi->got.offset == (bfd_vma) -1);
! 
! 			  if (h->plt.offset == (bfd_vma) -1)
! 			    {
! 			      h->plt.offset = hi->plt.offset;
! 			      hi->plt.offset = (bfd_vma) -1;
! 			    }
! 			  BFD_ASSERT (hi->got.offset == (bfd_vma) -1);
! 
! 			  if (h->dynindx == -1)
! 			    {
! 			      h->dynindx = hi->dynindx;
! 			      h->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.  */
--- 1763,1770 ----
  					  | ELF_LINK_HASH_DEF_REGULAR))
  				      == 0);
  
! 			  elf_link_hash_copy_indirect (elf_hash_table (info),
! 						       h, hi);
  
  			  /* See if the new flags lead us to realize
                               that the symbol must be dynamic.  */
*************** elf_link_assign_sym_version (h, data)
*** 3699,3708 ****
  			      && ! sinfo->export_dynamic)
  			    {
  			      h->elf_link_hash_flags |= ELF_LINK_FORCED_LOCAL;
! 			      h->elf_link_hash_flags &=~
! 				ELF_LINK_HASH_NEEDS_PLT;
! 			      h->dynindx = -1;
! 			      h->plt.offset = (bfd_vma) -1;
  			      /* FIXME: The name of the symbol has
  				 already been recorded in the dynamic
  				 string table section.  */
--- 3628,3635 ----
  			      && ! sinfo->export_dynamic)
  			    {
  			      h->elf_link_hash_flags |= ELF_LINK_FORCED_LOCAL;
! 			      elf_link_hash_hide_symbol (elf_hash_table (info),
! 							 h);
  			      /* FIXME: The name of the symbol has
  				 already been recorded in the dynamic
  				 string table section.  */
*************** elf_link_assign_sym_version (h, data)
*** 3814,3822 ****
  			  && ! sinfo->export_dynamic)
  			{
  			  h->elf_link_hash_flags |= ELF_LINK_FORCED_LOCAL;
! 			  h->elf_link_hash_flags &=~ ELF_LINK_HASH_NEEDS_PLT;
! 			  h->dynindx = -1;
! 			  h->plt.offset = (bfd_vma) -1;
  			  /* FIXME: The name of the symbol has already
  			     been recorded in the dynamic string table
  			     section.  */
--- 3741,3747 ----
  			  && ! sinfo->export_dynamic)
  			{
  			  h->elf_link_hash_flags |= ELF_LINK_FORCED_LOCAL;
! 			  elf_link_hash_hide_symbol (elf_hash_table (info), h);
  			  /* FIXME: The name of the symbol has already
  			     been recorded in the dynamic string table
  			     section.  */
*************** elf_link_assign_sym_version (h, data)
*** 3838,3846 ****
  	      && ! sinfo->export_dynamic)
  	    {
  	      h->elf_link_hash_flags |= ELF_LINK_FORCED_LOCAL;
! 	      h->elf_link_hash_flags &=~ ELF_LINK_HASH_NEEDS_PLT;
! 	      h->dynindx = -1;
! 	      h->plt.offset = (bfd_vma) -1;
  	      /* FIXME: The name of the symbol has already been
  		 recorded in the dynamic string table section.  */
  	    }
--- 3763,3769 ----
  	      && ! sinfo->export_dynamic)
  	    {
  	      h->elf_link_hash_flags |= ELF_LINK_FORCED_LOCAL;
! 	      elf_link_hash_hide_symbol (elf_hash_table (info), h);
  	      /* FIXME: The name of the symbol has already been
  		 recorded in the dynamic string table section.  */
  	    }


More information about the Binutils mailing list