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]

A patch for ".symver name,name2@@@nodename"


The idea is I can use ".symver name,name2@@@nodename" in files where
`name' may or may be defined. If `name' is defined, `name2@@nodename'
will replace `name'. `name2@@nodename' will resolve name2 as well as
`name2@nodename'. If `name' is not defined, references to `name' will
be replaced by references to `name2@nodename'. It can be used to
provide verioned symbols in an archive.


-- 
H.J. Lu (hjl@gnu.org)
---
2000-11-08  H.J. Lu  <hjl@gnu.org>

	* config/obj-elf.c (obj_elf_symver): Reformat.
	(elf_frob_symbol): Support ".symver name,name2@@@nodename".
	(elf_frob_file_before_adjust): Likewise.

	* doc/as.texinfo: Updated for ".symver name,name2@@@nodename"
	and ".symver name,name2@@@nodename".
	Fix a typo.

Index: config/obj-elf.c
===================================================================
RCS file: /work/cvs/gnu/binutils/gas/config/obj-elf.c,v
retrieving revision 1.23
diff -u -p -r1.23 obj-elf.c
--- config/obj-elf.c	2000/11/07 01:04:42	1.23
+++ config/obj-elf.c	2000/11/08 19:29:08
@@ -1131,7 +1131,7 @@ obj_elf_symver (ignore)
       *input_line_pointer = c;
 
       if (strchr (symbol_get_obj (sym)->versioned_name,
-				  ELF_VER_CHR) == NULL)
+		  ELF_VER_CHR) == NULL)
 	{
 	  as_bad (_("missing version name in `%s' for symbol `%s'"),
 		  symbol_get_obj (sym)->versioned_name,
@@ -1653,6 +1653,11 @@ elf_frob_symbol (symp, puntp)
 
   if (sy_obj->versioned_name != NULL)
     {
+      char *p;
+
+      p = strchr (sy_obj->versioned_name, ELF_VER_CHR);
+      know (p != NULL);
+
       /* This symbol was given a new name with the .symver directive.
 
          If this is an external reference, just rename the symbol to
@@ -1666,13 +1671,9 @@ elf_frob_symbol (symp, puntp)
 
       if (! S_IS_DEFINED (symp))
 	{
-	  char *p;
-
 	  /* Verify that the name isn't using the @@ syntax--this is
              reserved for definitions of the default version to link
              against.  */
-	  p = strchr (sy_obj->versioned_name, ELF_VER_CHR);
-	  know (p != NULL);
 	  if (p[1] == ELF_VER_CHR)
 	    {
 	      as_bad (_("invalid attempt to declare external version name as default in symbol `%s'"),
@@ -1683,36 +1684,50 @@ elf_frob_symbol (symp, puntp)
 	}
       else
 	{
-	  symbolS *symp2;
+	  if (p [1] == ELF_VER_CHR && p [2] == ELF_VER_CHR)
+	    {
+	      size_t l;
 
-	  /* FIXME: Creating a new symbol here is risky.  We're in the
-             final loop over the symbol table.  We can get away with
-             it only because the symbol goes to the end of the list,
-             where the loop will still see it.  It would probably be
-             better to do this in obj_frob_file_before_adjust.  */
+	      /* The @@@ syntax is a special case. It renames the
+		 symbol name to versioned_name with one `@' removed.  */
+	      l = strlen (&p[3]) + 1;
+	      memmove (&p [2], &p[3], l);
+	      S_SET_NAME (symp, sy_obj->versioned_name);
+	    }
+	  else
+	    {
+	      symbolS *symp2;
+
+	      /* FIXME: Creating a new symbol here is risky.  We're
+		 in the final loop over the symbol table.  We can
+		 get away with it only because the symbol goes to
+		 the end of the list, where the loop will still see
+		 it.  It would probably be better to do this in
+		 obj_frob_file_before_adjust.  */
 
-	  symp2 = symbol_find_or_make (sy_obj->versioned_name);
+	      symp2 = symbol_find_or_make (sy_obj->versioned_name);
 
-	  /* Now we act as though we saw symp2 = sym.  */
+	      /* Now we act as though we saw symp2 = sym.  */
 
-	  S_SET_SEGMENT (symp2, S_GET_SEGMENT (symp));
+	      S_SET_SEGMENT (symp2, S_GET_SEGMENT (symp));
 
-	  /* Subtracting out the frag address here is a hack because
-             we are in the middle of the final loop.  */
-	  S_SET_VALUE (symp2,
-		       (S_GET_VALUE (symp)
-			- symbol_get_frag (symp)->fr_address));
+	      /* Subtracting out the frag address here is a hack
+		 because we are in the middle of the final loop.  */
+	      S_SET_VALUE (symp2,
+			   (S_GET_VALUE (symp)
+			    - symbol_get_frag (symp)->fr_address));
 
-	  symbol_set_frag (symp2, symbol_get_frag (symp));
+	      symbol_set_frag (symp2, symbol_get_frag (symp));
 
-	  /* This will copy over the size information.  */
-	  copy_symbol_attributes (symp2, symp);
+	      /* This will copy over the size information.  */
+	      copy_symbol_attributes (symp2, symp);
 
-	  if (S_IS_WEAK (symp))
-	    S_SET_WEAK (symp2);
+	      if (S_IS_WEAK (symp))
+		S_SET_WEAK (symp2);
 
-	  if (S_IS_EXTERNAL (symp))
-	    S_SET_EXTERNAL (symp2);
+	      if (S_IS_EXTERNAL (symp))
+		S_SET_EXTERNAL (symp2);
+	    }
 	}
     }
 
@@ -1773,11 +1788,29 @@ elf_frob_file_before_adjust ()
       symbolS *symp;
 
       for (symp = symbol_rootP; symp; symp = symbol_next (symp))
-	if (symbol_get_obj (symp)->versioned_name
-	    && !S_IS_DEFINED (symp)
-	    && symbol_used_p (symp) == 0
-	    && symbol_used_in_reloc_p (symp) == 0)
-	  symbol_remove (symp, &symbol_rootP, &symbol_lastP);
+	if (symbol_get_obj (symp)->versioned_name)
+	  {
+	    if (!S_IS_DEFINED (symp))
+	      {
+		char *p;
+
+		/* The @@@ syntax is a special case. If the symbol is
+		   not defined, 2 `@'s will be removed from the
+		   versioned_name.  */
+
+		p = strchr (symbol_get_obj (symp)->versioned_name,
+			    ELF_VER_CHR);
+		know (p != NULL);
+		if (p [1] == ELF_VER_CHR && p [2] == ELF_VER_CHR)
+		  {
+		    size_t l = strlen (&p[3]) + 1;
+		    memmove (&p [1], &p[3], l);
+		  }
+		if (symbol_used_p (symp) == 0
+		    && symbol_used_in_reloc_p (symp) == 0)
+		  symbol_remove (symp, &symbol_rootP, &symbol_lastP);
+	      }
+	  }
     }
 }
 
Index: doc/as.texinfo
===================================================================
RCS file: /work/cvs/gnu/binutils/gas/doc/as.texinfo,v
retrieving revision 1.16
diff -u -p -r1.16 as.texinfo
--- doc/as.texinfo	2000/11/08 00:33:58	1.16
+++ doc/as.texinfo	2000/11/08 20:22:56
@@ -4933,12 +4933,12 @@ There are cases where it may make sense 
 into an application itself so as to override a versioned symbol from a
 shared library.
 
-For ELF targets, the @code{.symver} directive is used like this:
+For ELF targets, the @code{.symver} directive can be used like this:
 @smallexample
 .symver @var{name}, @var{name2@@nodename}
 @end smallexample
 If the symbol @var{name} is defined within the file
-being assembled, the @code{.versym} directive effectively creates a symbol
+being assembled, the @code{.symver} directive effectively creates a symbol
 alias with the name @var{name2@@nodename}, and in fact the main reason that we
 just don't try and create a regular alias is that the @var{@@} character isn't
 permitted in symbol names.  The @var{name2} part of the name is the actual name
@@ -4956,6 +4956,24 @@ If the symbol @var{name} is not defined 
 references to @var{name} will be changed to @var{name2@@nodename}.  If no
 reference to @var{name} is made, @var{name2@@nodename} will be removed from the
 symbol table.
+
+Another usage of the @code{.symver} directive is:
+@smallexample
+.symver @var{name}, @var{name2@@@@nodename}
+@end smallexample
+In this case, the symbol @var{name} must exist and be defined within
+the file being assembled. It is similiar to @var{name2@@nodename}. The
+difference is @var{name2@@@@nodename} will also be used to resolve
+references to @var{name2} by the linker.
+
+The third usage of the @code{.symver} directive is:
+@smallexample
+.symver @var{name}, @var{name2@@@@@@nodename}
+@end smallexample
+When @var{name} is not defined within the
+file being assembled, it is treated as @var{name2@@nodename}. When
+@var{name} is defined within the file being assembled, the symbol
+name, @var{name}, will be changed to @var{name2@@@@nodename}.
 @end ifset
 
 @ifset COFF

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