2000-11-07 H.J. Lu <hjl@gnu.org>
authorH.J. Lu <hjl.tools@gmail.com>
Wed, 8 Nov 2000 00:24:23 +0000 (00:24 +0000)
committerH.J. Lu <hjl.tools@gmail.com>
Wed, 8 Nov 2000 00:24:23 +0000 (00:24 +0000)
* doc/as.texinfo (.symver): Updated for versioned symbol
reference.

* obj.h (format_ops): Add the frob_file_before_adjust field.

* config/obj-aout.c (aout_format_ops): Set the
frob_file_before_adjust field to 0.
* config/obj-coff.c (coff_format_ops): Likewise.
* config/obj-ecoff.c (ecoff_format_ops): Likewise.

* config/obj-elf.c (obj_elf_symver): Allow duplicated version
name.
(elf_frob_file_before_adjust): New function to remove unneeded
versioned symbols from the symbol table.
(elf_format_ops): Set the frob_file_before_adjust field to
elf_frob_file_before_adjust.

* config/obj-elf.h (obj_frob_file_before_adjust): Defined if
not defined.

* config/obj-multi.h (obj_frob_file_before_adjust): Defined.

gas/ChangeLog
gas/config/obj-aout.c
gas/config/obj-coff.c
gas/config/obj-ecoff.c
gas/config/obj-elf.c
gas/config/obj-elf.h
gas/config/obj-multi.h
gas/doc/as.texinfo
gas/obj.h

index fd576ca..a3ca474 100644 (file)
@@ -1,3 +1,27 @@
+2000-11-07  H.J. Lu  <hjl@gnu.org>
+
+       * doc/as.texinfo (.symver): Updated for versioned symbol
+       reference.
+
+       * obj.h (format_ops): Add the frob_file_before_adjust field.
+
+       * config/obj-aout.c (aout_format_ops): Set the
+       frob_file_before_adjust field to 0.
+       * config/obj-coff.c (coff_format_ops): Likewise.
+       * config/obj-ecoff.c (ecoff_format_ops): Likewise.
+
+       * config/obj-elf.c (obj_elf_symver): Allow duplicated version
+       name.
+       (elf_frob_file_before_adjust): New function to remove unneeded
+       versioned symbols from the symbol table.
+       (elf_format_ops): Set the frob_file_before_adjust field to
+       elf_frob_file_before_adjust.
+
+       * config/obj-elf.h (obj_frob_file_before_adjust): Defined if
+       not defined.
+
+       * config/obj-multi.h (obj_frob_file_before_adjust): Defined.
+
 2000-11-07  Peter Targett  <peter.targett@arccores.com>
 
        * gas/config/tc-arc.h: Avoid warnings for LITTLE_ENDIAN and
index f24af61..67bb18e 100644 (file)
@@ -732,6 +732,7 @@ const struct format_ops aout_format_ops =
   0,   /* app_file */
   obj_aout_frob_symbol,
   obj_aout_frob_file,
+  0,   /* frob_file_before_adjust */
   0,   /* frob_file_after_relocs */
   0,   /* s_get_size */
   0,   /* s_set_size */
index 54c968f..e66f17b 100644 (file)
@@ -4653,6 +4653,7 @@ const struct format_ops coff_format_ops =
   c_dot_file_symbol,
   coff_frob_symbol,
   0,   /* frob_file */
+  0,   /* frob_file_before_adjust */
   coff_frob_file_after_relocs,
   0,   /* s_get_size */
   0,   /* s_set_size */
index 42eaf59..3f80e7d 100644 (file)
@@ -309,6 +309,7 @@ const struct format_ops ecoff_format_ops =
   ecoff_new_file,
   obj_ecoff_frob_symbol,
   ecoff_frob_file,
+  0,   /* frob_file_before_adjust */
   0,   /* frob_file_after_relocs */
   0,   /* s_get_size */
   0,   /* s_set_size */
index 4e7f3a3..bad6259 100644 (file)
@@ -1107,14 +1107,6 @@ obj_elf_symver (ignore)
 
   *input_line_pointer = c;
 
-  if (symbol_get_obj (sym)->versioned_name != NULL)
-    {
-      as_bad (_("multiple .symver directives for symbol `%s'"),
-             S_GET_NAME (sym));
-      ignore_rest_of_line ();
-      return;
-    }
-
   SKIP_WHITESPACE ();
   if (*input_line_pointer != ',')
     {
@@ -1133,16 +1125,34 @@ obj_elf_symver (ignore)
       *input_line_pointer++ = c;
     }
 
-  symbol_get_obj (sym)->versioned_name = xstrdup (name);
+  if (symbol_get_obj (sym)->versioned_name == NULL)
+    {
+      symbol_get_obj (sym)->versioned_name = xstrdup (name);
 
-  *input_line_pointer = c;
+      *input_line_pointer = c;
 
-  if (strchr (symbol_get_obj (sym)->versioned_name, ELF_VER_CHR) == NULL)
+      if (strchr (symbol_get_obj (sym)->versioned_name,
+                                 ELF_VER_CHR) == NULL)
+       {
+         as_bad (_("missing version name in `%s' for symbol `%s'"),
+                 symbol_get_obj (sym)->versioned_name,
+                 S_GET_NAME (sym));
+         ignore_rest_of_line ();
+         return;
+       }
+    }
+  else
     {
-      as_bad (_("missing version name in `%s' for symbol `%s'"),
-             symbol_get_obj (sym)->versioned_name, S_GET_NAME (sym));
-      ignore_rest_of_line ();
-      return;
+      if (strcmp (symbol_get_obj (sym)->versioned_name, name))
+       {
+         as_bad (_("multiple versions [`%s'|`%s'] for symbol `%s'"),
+                 name, symbol_get_obj (sym)->versioned_name,
+                 S_GET_NAME (sym));
+         ignore_rest_of_line ();
+         return;
+       }
+
+      *input_line_pointer = c;
     }
 
   demand_empty_rest_of_line ();
@@ -1754,6 +1764,24 @@ elf_frob_file ()
 #endif
 }
 
+/* It removes any unneeded versioned symbols from the symbol table. */
+
+void
+elf_frob_file_before_adjust ()
+{
+  if (symbol_rootP)
+    {
+      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);
+    }
+}
+
 /* It is required that we let write_relocs have the opportunity to
    optimize away fixups before output has begun, since it is possible
    to eliminate all fixups for a section and thus we never should
@@ -1958,6 +1986,7 @@ const struct format_ops elf_format_ops =
   elf_file_symbol,
   elf_frob_symbol,
   elf_frob_file,
+  elf_frob_file_before_adjust,
   elf_frob_file_after_relocs,
   elf_s_get_size, elf_s_set_size,
   elf_s_get_align, elf_s_set_align,
index 70ee61a..37004d7 100644 (file)
@@ -132,6 +132,11 @@ extern asection *gdb_section;
 #endif
 extern void elf_frob_file PARAMS ((void));
 
+#ifndef obj_frob_file_before_adjust
+#define obj_frob_file_before_adjust  elf_frob_file_before_adjust
+#endif
+extern void elf_frob_file_before_adjust PARAMS ((void));
+
 #ifndef obj_frob_file_after_relocs
 #define obj_frob_file_after_relocs  elf_frob_file_after_relocs
 #endif
index 3b80f38..1d68a0c 100644 (file)
         ? (*this_format->frob_file) ()                 \
         : (void) 0)
 
+#define obj_frob_file_before_adjust()                  \
+       (this_format->frob_file_before_adjust           \
+        ? (*this_format->frob_file_before_adjust) ()   \
+        : (void) 0)
+
 #define obj_frob_file_after_relocs()                   \
        (this_format->frob_file_after_relocs            \
         ? (*this_format->frob_file_after_relocs) ()    \
index c0d3276..2b73d3d 100644 (file)
@@ -4937,8 +4937,8 @@ For ELF targets, the @code{.symver} directive is used like this:
 @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.  The @code{.versym} directive effectively creates a symbol
+If the symbol @var{name} is defined within the file
+being assembled, the @code{.versym} 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
@@ -4951,6 +4951,11 @@ the name of a node specified in the version script supplied to the linker when
 building a shared library.  If you are attempting to override a versioned
 symbol from a shared library, then @var{nodename} should correspond to the
 nodename of the symbol you are trying to override.
+
+If the symbol @var{name} is not defined within the file being assembled, all
+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.
 @end ifset
 
 @ifset COFF
index 71f35e8..4c9759f 100644 (file)
--- a/gas/obj.h
+++ b/gas/obj.h
@@ -54,6 +54,7 @@ struct format_ops {
   void (*app_file) PARAMS ((const char *));
   void (*frob_symbol) PARAMS ((symbolS *, int *));
   void (*frob_file) PARAMS ((void));
+  void (*frob_file_before_adjust) PARAMS ((void));
   void (*frob_file_after_relocs) PARAMS ((void));
   bfd_vma (*s_get_size) PARAMS ((symbolS *));
   void (*s_set_size) PARAMS ((symbolS *, bfd_vma));