This is the mail archive of the binutils@sourceware.org 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]
Other format: [Raw text]

Re: RFC: weakref GCC attribute and .weakref assembly directive


On Oct 21, 2005, Alexandre Oliva <aoliva@redhat.com> wrote:

> On Oct 20, 2005, Nick Clifton <nickc@redhat.com> wrote:
>> sh-nto:
>> Fails with a seg-fault.
>> Recommendation:  Investigate cause of seg-fault.  It will
>> almost certainly be SH-specific, but it would be good to
>> prove this and even better to fix it.

> Erhm...  I can't trigger that on a i686-pc-linux-gnu host, but I
> *think* I did on amd64-linux-gnu, before realizing a number of targets
> were not 64-bit ready and deciding I couldn't, wouldn't make them so
> right now.

I'd failed to initialize the exp used as the value of a weakref
symbol.  It probably fails or works depending on the compiler you
use.

This revised patch addresses all of the issues you brought up, I
believe.  Testing for all targets hasn't completed yet, but since I'm
going to be away for several hours, I thought I'd post it for review.
Ok if tests pass?

Thanks,

Introduce weakref support in the assembler, as described in
http://people.redhat.com/aoliva/writeups/weakref/weakref.txt

Index: gas/ChangeLog
from  Alexandre Oliva  <aoliva@redhat.com>

	* read.c (potable): Add weakref.
	(s_weakref): New.
	* read.h (s_weakref): Declare.
	* struc-symbol.h (struct symbol): Add sy_weakrefr and sy_weakrefd.
	* symbols.c (colon): Clear weakrefr.
	(symbol_find_exact): Rename to, and reimplement in terms of...
	(symbol_find_exact_noref): ... new function.
	(symbol_find): Likewise...
	(symbol_find_noref): ... ditto.
	(resolve_symbol_value): Resolve weakrefr without setting their
	values.
	(S_SET_WEAK): Call hook.
	(S_GET_VALUE): Follow weakref link.
	(S_SET_VALUE): Clear weakrefr.
	(S_IS_WEAK): Follow weakref link.
	(S_IS_WEAKREFR, S_SET_WEAKREFR, S_CLEAR_WEAKREFR): New.
	(S_IS_WEAKREFD, S_SET_WEAKREFD, S_CLEAR_WEAKREFD): New.
	(symbol_set_value_expression, symbol_set_frag): Clear weakrefr.
	(symbol_mark_used): Follow weakref link.
	(print_symbol_value_1): Print weak, weakrefr and weakrefd.
	* symbols.h (symbol_find_noref, symbol_find_exact_noref): Declare.
	(S_IS_WEAKREFR, S_SET_WEAKREFR, S_CLEAR_WEAKREFR): Declare.
	(S_IS_WEAKREFD, S_SET_WEAKREFD, S_CLEAR_WEAKREFD): Declare.
	* write.c (adust_reloc_syms): Follow weakref link.  Do not
	complain if target is undefined.
	(write_object_file): Likewise.  Remove weakrefr symbols.  Drop
	unreferenced weakrefd symbols.
	* config/obj-coff.c (obj_frob_symbol): Do not force WEAKREFD
	symbols EXTERNAL.
	(pecoff_obj_set_weak_hook, pecoff_obj_clear_weak_hook): New.
	* config/obj-coff.h (obj_set_weak_hook, obj_clear_weak_hook): Define.
	* doc/as.texinfo: Document weakref.
	* doc/internals.texi: Document new struct members, internal
	functions and hooks.

Index: gas/testsuite/ChangeLog
from  Alexandre Oliva  <aoliva@redhat.com>

	* gas/all/weakref1.s, gas/all/weakref1.d: New test.
	* gas/all/weakref1g.d, gas/all/weakref1l.d: New tests.
	* gas/all/weakref1u.d, gas/all/weakref1w.d: New tests.
	* gas/all/weakref2.s, gas/all/weakref3.s: New tests.
	* gas/all/gas.exp: Run new tests.

Index: gas/read.c
===================================================================
--- gas/read.c.orig	2005-10-21 10:56:04.000000000 -0200
+++ gas/read.c	2005-10-21 11:34:00.000000000 -0200
@@ -434,6 +434,7 @@
   {"xref", s_ignore, 0},
   {"xstabs", s_xstab, 's'},
   {"warning", s_errwarn, 0},
+  {"weakref", s_weakref, 0},
   {"word", cons, 2},
   {"zero", s_space, 0},
   {NULL, NULL, 0}			/* End sentinel.  */
@@ -3150,6 +3151,124 @@
   const_flag &= ~IN_DEFAULT_SECTION;
 #endif
 }
+
+/* .weakref x, y sets x as an alias to y that, as long as y is not
+   referenced directly, will cause y to become a weak symbol.  */
+void
+s_weakref (int ignore ATTRIBUTE_UNUSED)
+{
+  char *name;
+  char delim;
+  char *end_name;
+  symbolS *symbolP;
+  symbolS *symbolP2;
+  expressionS exp;
+
+  name = input_line_pointer;
+  delim = get_symbol_end ();
+  end_name = input_line_pointer;
+
+  if (name == end_name)
+    {
+      as_bad (_("expected symbol name"));
+      *end_name = delim;
+      ignore_rest_of_line ();
+      return;
+    }
+
+  symbolP = symbol_find_or_make (name);
+
+  *end_name = delim;
+
+  SKIP_WHITESPACE ();
+
+  if (*input_line_pointer != ',')
+    {
+      *end_name = 0;
+      as_bad (_("expected comma after \"%s\""), name);
+      *end_name = delim;
+      ignore_rest_of_line ();
+      return;
+    }
+
+  input_line_pointer++;
+
+  SKIP_WHITESPACE ();
+
+  name = input_line_pointer;
+  delim = get_symbol_end ();
+  end_name = input_line_pointer;
+
+  if (name == end_name)
+    {
+      as_bad (_("expected symbol name"));
+      ignore_rest_of_line ();
+      return;
+    }
+
+  if ((symbolP2 = symbol_find_noref (name, 1)) == NULL
+      && (symbolP2 = md_undefined_symbol (name)) == NULL)
+    {
+      symbolP2 = symbol_find_or_make (name);
+      S_SET_WEAKREFD (symbolP2);
+    }
+  else
+    {
+      symbolS *symp = symbolP2;
+
+      while (S_IS_WEAKREFR (symp) && symp != symbolP)
+	{
+	  expressionS *expP = symbol_get_value_expression (symp);
+
+	  assert (expP->X_op == O_symbol
+		  && expP->X_add_number == 0);
+	  symp = expP->X_add_symbol;
+	}
+      if (symp == symbolP)
+	{
+	  char *loop;
+
+	  loop = concat (S_GET_NAME (symbolP),
+			 " => ", S_GET_NAME (symbolP2), NULL);
+
+	  symp = symbolP2;
+	  while (symp != symbolP)
+	    {
+	      char *old_loop = loop;
+	      symp = symbol_get_value_expression (symp)->X_add_symbol;
+	      loop = concat (loop, " => ", S_GET_NAME (symp), NULL);
+	      free (old_loop);
+	    }
+
+	  as_bad (_("%s: would close weakref loop: %s"),
+		  S_GET_NAME (symbolP), loop);
+
+	  free (loop);
+
+	  *end_name = delim;
+	  ignore_rest_of_line ();
+	  return;
+	}
+
+      /* Short-circuiting instead of just checking here might speed
+	 things up a tiny little bit, but loop error messages would
+	 miss intermediate links.  */
+      /* symbolP2 = symp; */
+    }
+
+  *end_name = delim;
+
+  memset (&exp, 0, sizeof (exp));
+  exp.X_op = O_symbol;
+  exp.X_add_symbol = symbolP2;
+
+  S_SET_SEGMENT (symbolP, undefined_section);
+  symbol_set_value_expression (symbolP, &exp);
+  symbol_set_frag (symbolP, &zero_address_frag);
+  S_SET_WEAKREFR (symbolP);
+
+  demand_empty_rest_of_line ();
+}
 
 
 /* Verify that we are at the end of a line.  If not, issue an error and
Index: gas/read.h
===================================================================
--- gas/read.h.orig	2005-10-21 10:56:04.000000000 -0200
+++ gas/read.h	2005-10-21 11:00:49.000000000 -0200
@@ -185,3 +185,4 @@
 extern void s_xstab (int what);
 extern void s_rva (int);
 extern void s_incbin (int);
+extern void s_weakref (int);
Index: gas/struc-symbol.h
===================================================================
--- gas/struc-symbol.h.orig	2005-10-21 10:56:04.000000000 -0200
+++ gas/struc-symbol.h	2005-10-21 11:00:49.000000000 -0200
@@ -72,6 +72,15 @@
      routines.  */
   unsigned int sy_mri_common : 1;
 
+  /* This is set if the symbol is set with a .weakref directive.  */
+  unsigned int sy_weakrefr : 1;
+
+  /* This is set when the symbol is referenced as part of a .weakref
+     directive, but only if the symbol was not in the symbol table
+     before.  It is cleared as soon as any direct reference to the
+     symbol is present.  */
+  unsigned int sy_weakrefd : 1;
+
 #ifdef OBJ_SYMFIELD_TYPE
   OBJ_SYMFIELD_TYPE sy_obj;
 #endif
Index: gas/symbols.c
===================================================================
--- gas/symbols.c.orig	2005-10-21 10:56:05.000000000 -0200
+++ gas/symbols.c	2005-10-21 11:00:49.000000000 -0200
@@ -309,6 +309,7 @@
 
   if ((symbolP = symbol_find (sym_name)) != 0)
     {
+      S_CLEAR_WEAKREFR (symbolP);
 #ifdef RESOLVE_SYMBOL_REDEFINITION
       if (RESOLVE_SYMBOL_REDEFINITION (symbolP))
 	return symbolP;
@@ -651,18 +652,41 @@
 symbolS *
 symbol_find_exact (const char *name)
 {
+  return symbol_find_exact_noref (name, 0);
+}
+
+symbolS *
+symbol_find_exact_noref (const char *name, int noref)
+{
   struct local_symbol *locsym;
+  symbolS* sym;
 
   locsym = (struct local_symbol *) hash_find (local_hash, name);
   if (locsym != NULL)
     return (symbolS *) locsym;
 
-  return ((symbolS *) hash_find (sy_hash, name));
+  sym = ((symbolS *) hash_find (sy_hash, name));
+
+  /* Any references to the symbol, except for the reference in
+     .weakref, must clear this flag, such that the symbol does not
+     turn into a weak symbol.  Note that we don't have to handle the
+     local_symbol case, since a weakrefd is always promoted out of the
+     local_symbol table when it is turned into a weak symbol.  */
+  if (sym && ! noref)
+    S_CLEAR_WEAKREFD (sym);
+
+  return sym;
 }
 
 symbolS *
 symbol_find (const char *name)
 {
+  return symbol_find_noref (name, 0);
+}
+
+symbolS *
+symbol_find_noref (const char *name, int noref)
+{
 #ifdef tc_canonicalize_symbol_name
   {
     char *copy;
@@ -690,7 +714,7 @@
       *copy = '\0';
     }
 
-  return symbol_find_exact (name);
+  return symbol_find_exact_noref (name, noref);
 }
 
 /* Once upon a time, symbols were kept in a singly linked list.  At
@@ -970,6 +994,19 @@
 	    symp->sy_value.X_op_symbol = NULL;
 
 	do_symbol:
+	  if (S_IS_WEAKREFR (symp))
+	    {
+	      assert (final_val == 0);
+	      if (S_IS_WEAKREFR (add_symbol))
+		{
+		  assert (add_symbol->sy_value.X_op == O_symbol
+			  && add_symbol->sy_value.X_add_number == 0);
+		  add_symbol = add_symbol->sy_value.X_add_symbol;
+		  assert (! S_IS_WEAKREFR (add_symbol));
+		  symp->sy_value.X_add_symbol = add_symbol;
+		}
+	    }
+
 	  if (symp->sy_mri_common)
 	    {
 	      /* This is a symbol inside an MRI common section.  The
@@ -1039,6 +1076,8 @@
 	    }
 
 	  resolved = symbol_resolved_p (add_symbol);
+	  if (S_IS_WEAKREFR (symp))
+	    goto exit_dont_set_value;
 	  break;
 
 	case O_uminus:
@@ -1717,6 +1756,9 @@
       if (!finalize_syms)
 	return val;
     }
+  if (S_IS_WEAKREFR (s))
+    return S_GET_VALUE (s->sy_value.X_add_symbol);
+
   if (s->sy_value.X_op != O_constant)
     {
       static symbolS *recur;
@@ -1751,6 +1793,7 @@
   s->sy_value.X_op = O_constant;
   s->sy_value.X_add_number = (offsetT) val;
   s->sy_value.X_unsigned = 0;
+  S_CLEAR_WEAKREFR (s);
 }
 
 void
@@ -1806,10 +1849,32 @@
 {
   if (LOCAL_SYMBOL_CHECK (s))
     return 0;
+  /* Conceptually, a weakrefr is weak if the referenced symbol is.  We
+     could probably handle a WEAKREFR as always weak though.  E.g., if
+     the referenced symbol has lost its weak status, there's no reason
+     to keep handling the weakrefr as if it was weak.  */
+  if (S_IS_WEAKREFR (s))
+    return S_IS_WEAK (s->sy_value.X_add_symbol);
   return (s->bsym->flags & BSF_WEAK) != 0;
 }
 
 int
+S_IS_WEAKREFR (symbolS *s)
+{
+  if (LOCAL_SYMBOL_CHECK (s))
+    return 0;
+  return s->sy_weakrefr != 0;
+}
+
+int
+S_IS_WEAKREFD (symbolS *s)
+{
+  if (LOCAL_SYMBOL_CHECK (s))
+    return 0;
+  return s->sy_weakrefd != 0;
+}
+
+int
 S_IS_COMMON (symbolS *s)
 {
   if (LOCAL_SYMBOL_CHECK (s))
@@ -2008,11 +2073,71 @@
 {
   if (LOCAL_SYMBOL_CHECK (s))
     s = local_symbol_convert ((struct local_symbol *) s);
+#ifdef obj_set_weak_hook
+  obj_set_weak_hook (s);
+#endif
   s->bsym->flags |= BSF_WEAK;
   s->bsym->flags &= ~(BSF_GLOBAL | BSF_LOCAL);
 }
 
 void
+S_SET_WEAKREFR (symbolS *s)
+{
+  if (LOCAL_SYMBOL_CHECK (s))
+    s = local_symbol_convert ((struct local_symbol *) s);
+  s->sy_weakrefr = 1;
+  /* If the alias was already used, make sure we mark the target as
+     used as well, otherwise it might be dropped from the symbol
+     table.  This may have unintended side effects if the alias is
+     later redirected to another symbol, such as keeping the unused
+     previous target in the symbol table.  Since it will be weak, it's
+     not a big deal.  */
+  if (s->sy_used)
+    symbol_mark_used (s->sy_value.X_add_symbol);
+}
+
+void
+S_CLEAR_WEAKREFR (symbolS *s)
+{
+  if (LOCAL_SYMBOL_CHECK (s))
+    return;
+  s->sy_weakrefr = 0;
+}
+
+void
+S_SET_WEAKREFD (symbolS *s)
+{
+  if (LOCAL_SYMBOL_CHECK (s))
+    s = local_symbol_convert ((struct local_symbol *) s);
+  s->sy_weakrefd = 1;
+  S_SET_WEAK (s);
+}
+
+void
+S_CLEAR_WEAKREFD (symbolS *s)
+{
+  if (LOCAL_SYMBOL_CHECK (s))
+    return;
+  if (s->sy_weakrefd)
+    {
+      s->sy_weakrefd = 0;
+      /* If a weakref target symbol is weak, then it was never
+	 referenced directly before, not even in a .global directive,
+	 so decay it to local.  If it remains undefined, it will be
+	 later turned into a global, like any other undefined
+	 symbol.  */
+      if (s->bsym->flags & BSF_WEAK)
+	{
+#ifdef obj_clear_weak_hook
+	  obj_clear_weak_hook (s);
+#endif
+	  s->bsym->flags &= ~BSF_WEAK;
+	  s->bsym->flags |= BSF_LOCAL;
+	}
+    }
+}
+
+void
 S_SET_THREAD_LOCAL (symbolS *s)
 {
   if (LOCAL_SYMBOL_CHECK (s))
@@ -2095,6 +2220,7 @@
   if (LOCAL_SYMBOL_CHECK (s))
     s = local_symbol_convert ((struct local_symbol *) s);
   s->sy_value = *exp;
+  S_CLEAR_WEAKREFR (s);
 }
 
 /* Return a pointer to the X_add_number component of a symbol.  */
@@ -2129,6 +2255,7 @@
       return;
     }
   s->sy_frag = f;
+  S_CLEAR_WEAKREFR (s);
 }
 
 /* Return the frag of a symbol.  */
@@ -2149,6 +2276,8 @@
   if (LOCAL_SYMBOL_CHECK (s))
     return;
   s->sy_used = 1;
+  if (S_IS_WEAKREFR (s))
+    symbol_mark_used (s->sy_value.X_add_symbol);
 }
 
 /* Clear the mark of whether a symbol has been used.  */
@@ -2472,11 +2601,17 @@
 	fprintf (file, " local");
       if (S_IS_EXTERNAL (sym))
 	fprintf (file, " extern");
+      if (S_IS_WEAK (sym))
+	fprintf (file, " weak");
       if (S_IS_DEBUG (sym))
 	fprintf (file, " debug");
       if (S_IS_DEFINED (sym))
 	fprintf (file, " defined");
     }
+  if (S_IS_WEAKREFR (sym))
+    fprintf (file, " weakrefr");
+  if (S_IS_WEAKREFD (sym))
+    fprintf (file, " weakrefd");
   fprintf (file, " %s", segment_name (S_GET_SEGMENT (sym)));
   if (symbol_resolved_p (sym))
     {
Index: gas/symbols.h
===================================================================
--- gas/symbols.h.orig	2005-10-21 10:56:05.000000000 -0200
+++ gas/symbols.h	2005-10-21 11:00:49.000000000 -0200
@@ -37,7 +37,9 @@
 
 char *decode_local_label_name (char *s);
 symbolS *symbol_find (const char *name);
+symbolS *symbol_find_noref (const char *name, int noref);
 symbolS *symbol_find_exact (const char *name);
+symbolS *symbol_find_exact_noref (const char *name, int noref);
 symbolS *symbol_find_or_make (const char *name);
 symbolS *symbol_make (const char *name);
 symbolS *symbol_new (const char *name, segT segment, valueT value,
@@ -83,6 +85,8 @@
 extern int S_IS_FUNCTION (symbolS *);
 extern int S_IS_EXTERNAL (symbolS *);
 extern int S_IS_WEAK (symbolS *);
+extern int S_IS_WEAKREFR (symbolS *);
+extern int S_IS_WEAKREFD (symbolS *);
 extern int S_IS_COMMON (symbolS *);
 extern int S_IS_DEFINED (symbolS *);
 extern int S_FORCE_RELOC (symbolS *, int);
@@ -98,6 +102,10 @@
 extern void S_SET_NAME (symbolS *, const char *);
 extern void S_CLEAR_EXTERNAL (symbolS *);
 extern void S_SET_WEAK (symbolS *);
+extern void S_SET_WEAKREFR (symbolS *);
+extern void S_CLEAR_WEAKREFR (symbolS *);
+extern void S_SET_WEAKREFD (symbolS *);
+extern void S_CLEAR_WEAKREFD (symbolS *);
 extern void S_SET_THREAD_LOCAL (symbolS *);
 extern void S_SET_VOLATILE (symbolS *);
 extern void S_SET_FORWARD_REF (symbolS *);
Index: gas/write.c
===================================================================
--- gas/write.c.orig	2005-10-21 10:56:05.000000000 -0200
+++ gas/write.c	2005-10-21 11:00:49.000000000 -0200
@@ -678,13 +678,15 @@
 
 	/* If this symbol is equated to an undefined or common symbol,
 	   convert the fixup to being against that symbol.  */
-	if (symbol_equated_reloc_p (sym))
+	if (symbol_equated_reloc_p (sym)
+	    || S_IS_WEAKREFR (sym))
 	  {
 	    symbolS *new_sym
 	      = symbol_get_value_expression (sym)->X_add_symbol;
 	    const char *name = S_GET_NAME (sym);
 	    if (!S_IS_COMMON (new_sym)
 		&& !TC_FAKE_LABEL (name)
+		&& !S_IS_WEAKREFR (sym)
 		&& (!S_IS_EXTERNAL (sym) || S_IS_LOCAL (sym)))
 	      as_bad (_("Local symbol `%s' can't be equated to undefined symbol `%s'"),
 		      name, S_GET_NAME (new_sym));
@@ -1483,11 +1485,13 @@
 
 	  /* Skip symbols which were equated to undefined or common
              symbols.  */
-	  if (symbol_equated_reloc_p (symp))
+	  if (symbol_equated_reloc_p (symp)
+	      || S_IS_WEAKREFR (symp))
 	    {
 	      const char *name = S_GET_NAME (symp);
 	      if (S_IS_COMMON (symp)
 		  && !TC_FAKE_LABEL (name)
+		  && !S_IS_WEAKREFR (symp)
 		  && (!S_IS_EXTERNAL (symp) || S_IS_LOCAL (symp)))
 		{
 		  expressionS *e = symbol_get_value_expression (symp);
@@ -1524,7 +1528,7 @@
 		 opposites.  Sometimes the former checks flags and the
 		 latter examines the name...  */
 	      || (!S_IS_EXTERNAL (symp)
-		  && (punt || S_IS_LOCAL (symp))
+		  && (punt || S_IS_LOCAL (symp) || S_IS_WEAKREFD (symp))
 		  && ! symbol_used_in_reloc_p (symp)))
 	    {
 	      symbol_remove (symp, &symbol_rootP, &symbol_lastP);
Index: gas/doc/as.texinfo
===================================================================
--- gas/doc/as.texinfo.orig	2005-10-21 10:56:05.000000000 -0200
+++ gas/doc/as.texinfo	2005-10-21 11:00:49.000000000 -0200
@@ -3842,6 +3842,7 @@
 
 * Warning::			@code{.warning @var{string}}
 * Weak::                        @code{.weak @var{names}}
+* Weakref::                     @code{.weakref @var{alias}, @var{symbol}}
 * Word::                        @code{.word @var{expressions}}
 * Deprecated::                  Deprecated Directives
 @end menu
@@ -5989,6 +5990,25 @@
 When a weak symbol is created that is not an alias, GAS creates an 
 alternate symbol to hold the default value.
 
+@node Weakref
+@section @code{.weakref @var{alias}, @var{target}}
+
+@cindex @code{weakref} directive
+This directive creates an alias to the target symbol that enables the symbol to
+be referenced with weak-symbol semantics, but without actually making it weak.
+If direct references or definitions of the symbol are present, then the symbol
+will not be weak, but if all references to it are through weak references, the
+symbol will be marked as weak in the symbol table.
+
+The effect is equivalent to moving all references to the alias to a separate
+assembly source file, renaming the alias to the symbol in it, declaring the
+symbol as weak there, and running a reloadable link to merge the object files
+resulting from the assembly of the new source file and the old source file that
+had the references to the alias removed.
+
+The alias itself never makes to the symbol table, and is entirely handled
+within the assembler.
+
 @node Word
 @section @code{.word @var{expressions}}
 
Index: gas/doc/internals.texi
===================================================================
--- gas/doc/internals.texi.orig	2005-10-21 10:56:05.000000000 -0200
+++ gas/doc/internals.texi	2005-10-21 11:00:49.000000000 -0200
@@ -93,6 +93,13 @@
 Whether the symbol is an MRI common symbol created by the @code{COMMON}
 pseudo-op when assembling in MRI mode.
 
+@item sy_weakrefr
+Whether the symbol is a @code{weakref} alias to another symbol.
+
+@item sy_weakrefd
+Whether the symbol is or was referenced by one or more @code{weakref} aliases,
+and has not had any direct references.
+
 @item bsym
 This points to the BFD @code{asymbol} that
 will be used in writing the object file.
@@ -146,7 +153,17 @@
 
 @item S_IS_WEAK
 @cindex S_IS_WEAK
-Return non-zero if the symbol is weak.
+Return non-zero if the symbol is weak, or if it is a @code{weakref} alias or
+symbol that has not been strongly referenced.
+
+@item S_IS_WEAKREFR
+@cindex S_IS_WEAKREFR
+Return non-zero if the symbol is a @code{weakref} alias.
+
+@item S_IS_WEAKREFD
+@cindex S_IS_WEAKREFD
+Return non-zero if the symbol was aliased by a @code{weakref} alias and has not
+had any strong references.
 
 @item S_IS_COMMON
 @cindex S_IS_COMMON
@@ -182,6 +199,29 @@
 @cindex S_SET_WEAK
 Mark the symbol as weak.
 
+@item S_SET_WEAKREFR
+@cindex S_SET_WEAKREFR
+Mark the symbol as the referrer in a @code{weakref} directive.  The symbol it
+aliases must have been set to the value expression before this point.  If the
+alias has already been used, the symbol is marked as used too.
+
+@item S_CLEAR_WEAKREFR
+@cindex S_CLEAR_WEAKREFR
+Clear the @code{weakref} alias status of a symbol.  This is implicitly called
+whenever a symbol is defined or set to a new expression.
+
+@item S_SET_WEAKREFD
+@cindex S_SET_WEAKREFD
+Mark the symbol as the referred symbol in a @code{weakref} directive.
+Implicitly marks the symbol as weak, but see below.  It should only be called
+if the referenced symbol has just been added to the symbol table.
+
+@item S_SET_WEAKREFD
+@cindex S_SET_WEAKREFD
+Clear the @code{weakref} aliased status of a symbol.  This is implicitly called
+whenever the symbol is looked up, as part of a direct reference or a
+definition, but not as part of a @code{weakref} directive.
+
 @item S_GET_TYPE
 @item S_GET_DESC
 @item S_GET_OTHER
@@ -1533,6 +1573,16 @@
 that the symbol should not be included in the object file by defining this
 macro to set its second argument to a non-zero value.
 
+@item obj_set_weak_hook
+@cindex obj_set_weak_hook
+If you define this macro, @code{S_SET_WEAK} will call it before modifying the
+symbol's flags.
+
+@item obj_clear_weak_hook
+@cindex obj_clear_weak_hook
+If you define this macro, @code{S_CLEAR_WEAKREFD} will call it after clearning
+the @code{weakrefd} flag, but before modifying any other flags.
+
 @item obj_frob_file
 @cindex obj_frob_file
 If you define this macro, GAS will call it after the symbol table has been
Index: gas/testsuite/gas/all/gas.exp
===================================================================
--- gas/testsuite/gas/all/gas.exp.orig	2005-10-21 10:56:05.000000000 -0200
+++ gas/testsuite/gas/all/gas.exp	2005-10-21 11:00:49.000000000 -0200
@@ -250,6 +250,14 @@
     run_dump_test quad
 }
 
+run_dump_test weakref1
+run_dump_test weakref1g
+run_dump_test weakref1l
+run_dump_test weakref1u
+run_dump_test weakref1w
+gas_test_error "weakref2.s" "" "e: would close weakref loop: e => a => b => c => d => e"
+gas_test_error "weakref3.s" "" "a: would close weakref loop: a => b => c => d => e => a"
+
 load_lib gas-dg.exp
 dg-init
 dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/err-*.s $srcdir/$subdir/warn-*.s]] "" ""
Index: gas/testsuite/gas/all/weakref1.d
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ gas/testsuite/gas/all/weakref1.d	2005-10-21 11:47:05.000000000 -0200
@@ -0,0 +1,112 @@
+#objdump: -r
+#name: weakref tests, relocations
+# ecoff (OSF/alpha) lacks .weak support
+# pdp11 lacks .long
+# the following must be present in all weakref1*.d
+#not-target: alpha*-*-osf* *-*-ecoff pdp11-aout
+
+#...
+RELOCATION RECORDS FOR \[\.text\]:
+OFFSET +TYPE +VALUE *
+# the rest of this file is generated with the following script:
+# # script begin
+# echo \#...
+# sed -n 's:^\.weakref .*, \(\(u\|\(w\)\).*\)$:.*( \3 |\(sec  0\)).* \1:p' weakref1.s | uniq | while read line; do echo "$line"; echo "#..."; done
+
+# sed -n 's:^\.long \(W\|\)\(.*[^a-z]\)[a-z]*\(\| - .*\)$:\2:p' weakref1.s | sed -e 's,^[lg].*,(&|\\.text)(\\+0x[0-9a-f]+)?,' | sed 's,^,[0-9a-f]+ [^ ]*  +,'
+# # script output:
+#...
+[0-9a-f]+ [^ ]*  +wa1
+[0-9a-f]+ [^ ]*  +ua2
+[0-9a-f]+ [^ ]*  +ua3
+[0-9a-f]+ [^ ]*  +ua3
+[0-9a-f]+ [^ ]*  +ua4
+[0-9a-f]+ [^ ]*  +ua4
+[0-9a-f]+ [^ ]*  +wb1
+[0-9a-f]+ [^ ]*  +ub2
+[0-9a-f]+ [^ ]*  +ub3
+[0-9a-f]+ [^ ]*  +ub3
+[0-9a-f]+ [^ ]*  +ub4
+[0-9a-f]+ [^ ]*  +ub4
+[0-9a-f]+ [^ ]*  +wc1
+[0-9a-f]+ [^ ]*  +wc1
+[0-9a-f]+ [^ ]*  +uc2
+[0-9a-f]+ [^ ]*  +uc2
+[0-9a-f]+ [^ ]*  +uc3
+[0-9a-f]+ [^ ]*  +uc3
+[0-9a-f]+ [^ ]*  +uc3
+[0-9a-f]+ [^ ]*  +uc3
+[0-9a-f]+ [^ ]*  +uc4
+[0-9a-f]+ [^ ]*  +uc4
+[0-9a-f]+ [^ ]*  +uc4
+[0-9a-f]+ [^ ]*  +uc4
+[0-9a-f]+ [^ ]*  +uc5
+[0-9a-f]+ [^ ]*  +uc5
+[0-9a-f]+ [^ ]*  +uc5
+[0-9a-f]+ [^ ]*  +uc5
+[0-9a-f]+ [^ ]*  +uc6
+[0-9a-f]+ [^ ]*  +uc6
+[0-9a-f]+ [^ ]*  +uc6
+[0-9a-f]+ [^ ]*  +uc6
+[0-9a-f]+ [^ ]*  +uc7
+[0-9a-f]+ [^ ]*  +uc7
+[0-9a-f]+ [^ ]*  +uc8
+[0-9a-f]+ [^ ]*  +uc8
+[0-9a-f]+ [^ ]*  +uc9
+[0-9a-f]+ [^ ]*  +uc9
+[0-9a-f]+ [^ ]*  +uc9
+[0-9a-f]+ [^ ]*  +ww1
+[0-9a-f]+ [^ ]*  +ww2
+[0-9a-f]+ [^ ]*  +ww3
+[0-9a-f]+ [^ ]*  +ww3
+[0-9a-f]+ [^ ]*  +ww4
+[0-9a-f]+ [^ ]*  +ww4
+[0-9a-f]+ [^ ]*  +ww5
+[0-9a-f]+ [^ ]*  +ww5
+[0-9a-f]+ [^ ]*  +ww6
+[0-9a-f]+ [^ ]*  +ww7
+[0-9a-f]+ [^ ]*  +ww8
+[0-9a-f]+ [^ ]*  +ww8
+[0-9a-f]+ [^ ]*  +ww9
+[0-9a-f]+ [^ ]*  +ww9
+[0-9a-f]+ [^ ]*  +ww10
+[0-9a-f]+ [^ ]*  +ww10
+[0-9a-f]+ [^ ]*  +um2
+[0-9a-f]+ [^ ]*  +wm3
+[0-9a-f]+ [^ ]*  +um5
+[0-9a-f]+ [^ ]*  +wm6
+[0-9a-f]+ [^ ]*  +wm7
+[0-9a-f]+ [^ ]*  +wm8
+[0-9a-f]+ [^ ]*  +wh2
+[0-9a-f]+ [^ ]*  +wh3
+[0-9a-f]+ [^ ]*  +wh4
+[0-9a-f]+ [^ ]*  +wh5
+[0-9a-f]+ [^ ]*  +wh6
+[0-9a-f]+ [^ ]*  +wh7
+[0-9a-f]+ [^ ]*  +uh8
+[0-9a-f]+ [^ ]*  +uh8
+[0-9a-f]+ [^ ]*  +uh9
+[0-9a-f]+ [^ ]*  +uh9
+[0-9a-f]+ [^ ]*  +(lr1|\.text)(\+0x[0-9a-f]+)?
+[0-9a-f]+ [^ ]*  +(lr1|\.text)(\+0x[0-9a-f]+)?
+[0-9a-f]+ [^ ]*  +(lr2|\.text)(\+0x[0-9a-f]+)?
+[0-9a-f]+ [^ ]*  +(lr2|\.text)(\+0x[0-9a-f]+)?
+[0-9a-f]+ [^ ]*  +wr3
+[0-9a-f]+ [^ ]*  +wr3
+[0-9a-f]+ [^ ]*  +wr4
+[0-9a-f]+ [^ ]*  +wr5
+[0-9a-f]+ [^ ]*  +(lr6|\.text)(\+0x[0-9a-f]+)?
+[0-9a-f]+ [^ ]*  +ur6
+[0-9a-f]+ [^ ]*  +(lr7|\.text)(\+0x[0-9a-f]+)?
+[0-9a-f]+ [^ ]*  +(lr7|\.text)(\+0x[0-9a-f]+)?
+[0-9a-f]+ [^ ]*  +(ld1|\.text)(\+0x[0-9a-f]+)?
+[0-9a-f]+ [^ ]*  +(ld2|\.text)(\+0x[0-9a-f]+)?
+[0-9a-f]+ [^ ]*  +(ld3|\.text)(\+0x[0-9a-f]+)?
+[0-9a-f]+ [^ ]*  +(ld4|\.text)(\+0x[0-9a-f]+)?
+[0-9a-f]+ [^ ]*  +ud5
+[0-9a-f]+ [^ ]*  +(gd6|\.text)(\+0x[0-9a-f]+)?
+[0-9a-f]+ [^ ]*  +(gd7|\.text)(\+0x[0-9a-f]+)?
+[0-9a-f]+ [^ ]*  +(ld8|\.text)(\+0x[0-9a-f]+)?
+[0-9a-f]+ [^ ]*  +(ld8|\.text)(\+0x[0-9a-f]+)?
+[0-9a-f]+ [^ ]*  +(ld9|\.text)(\+0x[0-9a-f]+)?
+[0-9a-f]+ [^ ]*  +(ld9|\.text)(\+0x[0-9a-f]+)?
Index: gas/testsuite/gas/all/weakref1.s
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ gas/testsuite/gas/all/weakref1.s	2005-10-21 11:02:52.000000000 -0200
@@ -0,0 +1,277 @@
+	.text
+l:
+/* a# test references after weakref. */
+	.weakref Wwa1, wa1
+	.long Wwa1
+
+	.weakref Wua2, ua2
+	.long ua2
+
+	.weakref Wua3, ua3
+	.long Wua3
+	.long ua3
+
+	.weakref Wua4, ua4
+	.long ua4
+	.long Wua4
+
+	.weakref Wna5, na5
+
+/* b# test references before weakref.  */
+	.long Wwb1
+	.weakref Wwb1, wb1
+
+	.long ub2
+	.weakref Wub2, ub2
+
+	.long Wub3
+	.long ub3
+	.weakref Wub3, ub3
+
+	.long ub4
+	.long Wub4
+	.weakref Wub4, ub4
+
+/* c# test combinations of references before and after weakref.  */
+	.long Wwc1
+	.weakref Wwc1, wc1
+	.long Wwc1
+
+	.long uc2
+	.weakref Wuc2, uc2
+	.long uc2
+
+	.long Wuc3
+	.long uc3
+	.weakref Wuc3, uc3
+	.long Wuc3
+	.long uc3
+
+	.long uc4
+	.long Wuc4
+	.weakref Wuc4, uc4
+	.long uc4
+	.long Wuc4
+
+	.long Wuc5
+	.long uc5
+	.weakref Wuc5, uc5
+	.long uc5
+	.long Wuc5
+
+	.long uc6
+	.long Wuc6
+	.weakref Wuc6, uc6
+	.long uc6
+	.long Wuc6
+
+	.long uc7
+	.weakref Wuc7, uc7
+	.long Wuc7
+
+	.long Wuc8
+	.weakref Wuc8, uc8
+	.long uc8
+
+	.long Wuc9
+	.weakref Wuc9, uc9
+	.long Wuc9
+	.long uc9
+
+/* w# test that explicitly weak target don't lose the weak status */
+	.weakref Www1, ww1
+	.weak ww1
+	.long ww1
+
+	.weak ww2
+	.weakref Www2, ww2
+	.long ww2
+
+	.weak ww3
+	.long ww3
+	.weakref Www3, ww3
+	.long ww3
+
+	.long ww4
+	.weakref Www4, ww4
+	.weak ww4
+	.long ww4
+
+	.long ww5
+	.weakref Www5, ww5
+	.long ww5
+	.weak ww5
+
+	.weakref Www6, ww6
+	.weak ww6
+	.long Www6
+
+	.weak ww7
+	.weakref Www7, ww7
+	.long Www7
+
+	.weak ww8
+	.long Www8
+	.weakref Www8, ww8
+	.long Www8
+
+	.long Www9
+	.weakref Www9, ww9
+	.weak ww9
+	.long Www9
+
+	.long Www10
+	.weakref Www10, ww10
+	.long Www10
+	.weak ww10
+
+/* m# test multiple weakrefs */
+	.weakref Wnm1, nm1
+	.weakref Wnm1, nm1
+
+	.weakref Wum2, um2
+	.weakref Wum2, um2
+	.long um2
+
+	.weakref Wwm3, wm3
+	.weakref Wwm3, wm3
+	.long Wwm3
+
+	.weakref Wnm4a, nm4
+	.weakref Wnm4b, nm4
+
+	.weakref Wum5a, um5
+	.weakref Wum5b, um5
+	.long um5
+
+	.weakref Wwm6a, wm6
+	.weakref Wwm6b, wm6
+	.long Wwm6a
+
+	.weakref Wwm7a, wm7
+	.weakref Wwm7b, wm7
+	.long Wwm7b
+
+	.weakref Wwm8a, wm8
+	.long Wwm8b
+	.weakref Wwm8b, wm8
+
+/* h# test weakref chain */
+	.weakref Wnh1a, nh1
+	.weakref Wnh1b, Wnh1a
+	.weakref Wnh1c, Wnh1b
+
+	.weakref Wwh2a, wh2
+	.weakref Wwh2b, Wwh2a
+	.long Wwh2b
+
+	.weakref Wwh3a, wh3
+	.weakref Wwh3b, Wwh3a
+	.long Wwh3a
+
+	.weakref Wwh4b, Wwh4a
+	.weakref Wwh4a, wh4
+	.long Wwh4b
+
+	.long Wwh5b
+	.weakref Wwh5a, wh5
+	.weakref Wwh5b, Wwh5a
+
+	.long Wwh6b
+	.weakref Wwh6b, Wwh6a
+	.weakref Wwh6a, wh6
+
+	.weakref Wwh7b, Wwh7a
+	.long Wwh7b
+	.weakref Wwh7a, wh7
+
+	.long Wuh8c
+	.weakref Wuh8a, uh8
+	.weakref Wuh8b, Wuh8a
+	.weakref Wuh8c, Wuh8b
+	.long uh8
+
+	.long Wuh9c
+	.weakref Wuh9c, Wuh9b
+	.weakref Wuh9b, Wuh9a
+	.weakref Wuh9a, uh9
+	.long uh9
+
+/* r# weakref redefinitions, to and from */
+	.weakref lr1, nr1
+	.long lr1
+	.set lr1, l
+	.long lr1
+
+	.long lr2
+	.weakref lr2, nr2
+	.set lr2, l
+	.long lr2
+
+	.set Wwr3, l
+	.long Wwr3
+	.weakref Wwr3, wr3
+	.long Wwr3
+
+	.set Wwr4, l
+	.weakref Wwr4, wr4
+	.long Wwr4
+
+	.set Wwr5, l
+	.long Wwr5
+	.weakref Wwr5, wr5
+
+	.weakref lr6, ur6
+	.long lr6
+	.set lr6, l
+	.long ur6
+
+	.weakref lr7, nr7
+	.long lr7
+lr7:
+	.long lr7
+
+/* d# target symbol definitions */
+	.weakref Wld1, ld1
+	.long Wld1
+	.set ld1, l
+
+	.weakref Wld2, ld2
+	.long Wld2
+ld2:
+
+ld3:
+	.weakref Wld3, ld3
+	.long Wld3
+
+ld4:
+	.long Wld4
+	.weakref Wld4, ld4
+
+	.global ud5
+	.weakref Wud5, ud5
+	.long Wud5
+
+	.global gd6
+	.weakref Wgd6, gd6
+	.long Wgd6
+gd6:
+
+	.weakref Wgd7, gd7
+	.long Wgd7
+	.global gd7
+gd7:
+
+	.long Wld8c
+	.weakref Wld8a, ld8
+	.weakref Wld8b, Wld8a
+	.weakref Wld8c, Wld8b
+	.long ld8
+ld8:
+
+	.long Wld9c
+	.weakref Wld9c, Wld9b
+	.weakref Wld9b, Wld9a
+	.weakref Wld9a, ld9
+	.long ld9
+ld9:
Index: gas/testsuite/gas/all/weakref2.s
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ gas/testsuite/gas/all/weakref2.s	2005-10-21 11:00:49.000000000 -0200
@@ -0,0 +1,5 @@
+.weakref a,b
+.weakref b,c
+.weakref c,d
+.weakref d,e
+.weakref e,a
Index: gas/testsuite/gas/all/weakref3.s
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ gas/testsuite/gas/all/weakref3.s	2005-10-21 11:00:49.000000000 -0200
@@ -0,0 +1,5 @@
+.weakref e,a
+.weakref d,e
+.weakref c,d
+.weakref b,c
+.weakref a,b
Index: gas/config/obj-coff.c
===================================================================
--- gas/config/obj-coff.c.orig	2005-10-21 10:56:05.000000000 -0200
+++ gas/config/obj-coff.c	2005-10-21 11:00:49.000000000 -0200
@@ -1055,6 +1055,39 @@
   return ret;
 }
 
+void
+pecoff_obj_set_weak_hook (symbolS *symbolP)
+{
+  symbolS *alternateP;
+
+  /* See _Microsoft Portable Executable and Common Object
+     File Format Specification_, section 5.5.3.
+     Create a symbol representing the alternate value.
+     coff_frob_symbol will set the value of this symbol from
+     the value of the weak symbol itself.  */
+  S_SET_STORAGE_CLASS (symbolP, C_NT_WEAK);
+  S_SET_NUMBER_AUXILIARY (symbolP, 1);
+  SA_SET_SYM_FSIZE (symbolP, IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY);
+
+  alternateP = symbol_find_or_make (weak_name2altname (S_GET_NAME (symbolP)));
+  S_SET_EXTERNAL (alternateP);
+  S_SET_STORAGE_CLASS (alternateP, C_NT_WEAK);
+
+  SA_SET_SYM_TAGNDX (symbolP, alternateP);
+}
+
+void
+pecoff_obj_clear_weak_hook (symbolS *symbolP)
+{
+  symbolS *alternateP;
+
+  S_SET_STORAGE_CLASS (symbolP, 0);
+  SA_SET_SYM_FSIZE (symbolP, 0);
+
+  alternateP = symbol_find (weak_name2altname (S_GET_NAME (symbolP)));
+  S_CLEAR_EXTERNAL (alternateP);
+}
+
 #endif  /* TE_PE */
 
 /* Handle .weak.  This is a GNU extension in formats other than PE. */
@@ -1065,9 +1098,6 @@
   char *name;
   int c;
   symbolS *symbolP;
-#ifdef TE_PE
-  symbolS *alternateP;
-#endif
 
   do
     {
@@ -1085,23 +1115,6 @@
       SKIP_WHITESPACE ();
       S_SET_WEAK (symbolP);
 
-#ifdef TE_PE
-      /* See _Microsoft Portable Executable and Common Object
-         File Format Specification_, section 5.5.3.
-         Create a symbol representing the alternate value.
-         coff_frob_symbol will set the value of this symbol from
-         the value of the weak symbol itself.  */
-      S_SET_STORAGE_CLASS (symbolP, C_NT_WEAK);
-      S_SET_NUMBER_AUXILIARY (symbolP, 1);
-      SA_SET_SYM_FSIZE (symbolP, IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY);
-
-      alternateP = symbol_find_or_make (weak_name2altname (name));
-      S_SET_EXTERNAL (alternateP);
-      S_SET_STORAGE_CLASS (alternateP, C_NT_WEAK);
-
-      SA_SET_SYM_TAGNDX (symbolP, alternateP);
-#endif
-
       if (c == ',')
 	{
 	  input_line_pointer++;
@@ -1157,12 +1170,19 @@
     {
       /* This is a weak alternate symbol.  All processing of
 	 PECOFFweak symbols is done here, through the alternate.  */
-      symbolS *weakp = symbol_find (weak_altname2name (S_GET_NAME (symp)));
+      symbolS *weakp = symbol_find_noref (weak_altname2name
+					  (S_GET_NAME (symp)), 1);
 
       assert (weakp);
       assert (S_GET_NUMBER_AUXILIARY (weakp) == 1);
 
-      if (symbol_equated_p (weakp))
+      if (! S_IS_WEAK (weakp))
+	{
+	  /* The symbol was turned from weak to strong.  Discard altname.  */
+	  *punt = 1;
+	  return;
+	}
+      else if (symbol_equated_p (weakp))
 	{
 	  /* The weak symbol has an alternate specified; symp is unneeded.  */
 	  S_SET_STORAGE_CLASS (weakp, C_NT_WEAK);
@@ -1225,7 +1245,7 @@
 	  && !SF_GET_STATICS (symp)
 	  && S_GET_STORAGE_CLASS (symp) != C_LABEL
 	  && symbol_constant_p (symp)
-	  && (real = symbol_find (S_GET_NAME (symp)))
+	  && (real = symbol_find_noref (S_GET_NAME (symp), 1))
 	  && S_GET_STORAGE_CLASS (real) == C_NULL
 	  && real != symp)
 	{
@@ -1237,7 +1257,10 @@
       if (!S_IS_DEFINED (symp) && !SF_GET_LOCAL (symp))
 	{
 	  assert (S_GET_VALUE (symp) == 0);
-	  S_SET_EXTERNAL (symp);
+	  if (S_IS_WEAKREFD (symp))
+	    *punt = 1;
+	  else
+	    S_SET_EXTERNAL (symp);
 	}
       else if (S_GET_STORAGE_CLASS (symp) == C_NULL)
 	{
Index: gas/config/obj-coff.h
===================================================================
--- gas/config/obj-coff.h.orig	2005-10-21 10:56:05.000000000 -0200
+++ gas/config/obj-coff.h	2005-10-21 11:00:49.000000000 -0200
@@ -157,6 +157,9 @@
 #ifdef TE_PE
 /* PE weak symbols need USE_UNIQUE.  */
 #define USE_UNIQUE 1
+
+#define obj_set_weak_hook pecoff_obj_set_weak_hook
+#define obj_clear_weak_hook pecoff_obj_clear_weak_hook
 #endif
 
 #ifndef OBJ_COFF_MAX_AUXENTRIES
@@ -384,6 +387,10 @@
 extern void coff_frob_file_after_relocs  (void);
 extern void coff_obj_symbol_new_hook     (symbolS *);
 extern void coff_obj_read_begin_hook     (void);
+#ifdef TE_PE
+extern void pecoff_obj_set_weak_hook     (symbolS *);
+extern void pecoff_obj_clear_weak_hook   (symbolS *);
+#endif
 extern void obj_coff_section             (int);
 extern segT obj_coff_add_segment         (const char *);
 extern void obj_coff_section             (int);
Index: gas/testsuite/gas/all/weakref1w.d
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ gas/testsuite/gas/all/weakref1w.d	2005-10-21 11:46:21.000000000 -0200
@@ -0,0 +1,64 @@
+#nm: --undefined-only --no-sort
+#name: weakref tests, weak undefined syms
+#source: weakref1.s
+# see weakref1.d for comments on the not-targets
+#not-target: alpha*-*-osf* *-*-ecoff pdp11-aout
+
+# the rest of this file is generated with the following script:
+# # script begin
+# sed -n 's:^[ 	]*\.weakref .*, \(w.*\)$:.* w \1:p' weakref1.s | uniq | while read line; do echo "#..."; echo "$line"; done
+# echo \#pass
+# # script output:
+#...
+.* w wa1
+#...
+.* w wb1
+#...
+.* w wc1
+#...
+.* w ww1
+#...
+.* w ww2
+#...
+.* w ww3
+#...
+.* w ww4
+#...
+.* w ww5
+#...
+.* w ww6
+#...
+.* w ww7
+#...
+.* w ww8
+#...
+.* w ww9
+#...
+.* w ww10
+#...
+.* w wm3
+#...
+.* w wm6
+#...
+.* w wm7
+#...
+.* w wm8
+#...
+.* w wh2
+#...
+.* w wh3
+#...
+.* w wh4
+#...
+.* w wh5
+#...
+.* w wh6
+#...
+.* w wh7
+#...
+.* w wr3
+#...
+.* w wr4
+#...
+.* w wr5
+#pass
Index: gas/testsuite/gas/all/weakref1g.d
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ gas/testsuite/gas/all/weakref1g.d	2005-10-21 11:46:40.000000000 -0200
@@ -0,0 +1,18 @@
+#nm: --defined-only --extern-only --no-sort
+#name: weakref tests, global syms
+#source: weakref1.s
+# see weakref1.d for comments on the not-targets
+# ecoff (OSF/alpha) lacks .weak support
+# pdp11 lacks .long
+#not-target: alpha*-*-osf* *-*-ecoff pdp11-aout
+
+# the rest of this file is generated with the following script:
+# # script begin
+# echo \#...
+# sed -n 's,^[ 	]*\.global \(g.*\),.* T \1,p' weakref1.s | uniq
+# echo \#pass
+# # script output:
+#...
+.* T gd6
+.* T gd7
+#pass
Index: gas/testsuite/gas/all/weakref1l.d
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ gas/testsuite/gas/all/weakref1l.d	2005-10-21 11:45:56.000000000 -0200
@@ -0,0 +1,35 @@
+#nm: --defined-only --no-sort
+#name: weakref tests, local syms
+#source: weakref1.s
+# aix drops local symbols
+# see weakref1.d for comments on the other not-targets
+#not-target: *-*-aix* alpha*-*-osf* *-*-ecoff pdp11-aout
+
+# the rest of this file is generated with the following script:
+# # script begin
+# sed -n 's,^\(l[^ ]*\)[ 	]*:.*,.* t \1,p;s:^[ 	]*\.set[ 	][ 	]*\(l[^ ]*\)[ 	]*,.*:.* t \1:p' weakref1.s | uniq | while read line; do echo "#..."; echo "$line"; done
+# echo \#pass
+# # script output:
+#...
+.* t l
+#...
+.* t lr1
+#...
+.* t lr2
+#...
+.* t lr6
+#...
+.* t lr7
+#...
+.* t ld1
+#...
+.* t ld2
+#...
+.* t ld3
+#...
+.* t ld4
+#...
+.* t ld8
+#...
+.* t ld9
+#pass
Index: gas/testsuite/gas/all/weakref1u.d
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ gas/testsuite/gas/all/weakref1u.d	2005-10-21 11:45:50.000000000 -0200
@@ -0,0 +1,53 @@
+#nm: --undefined-only --no-sort
+#name: weakref tests, strong undefined syms
+#source: weakref1.s
+# aout turns undefined into *ABS* symbols.
+# see weakref1.d for comments on the other not-targets
+#not-target: *-*-aout ns32k-*-netbsd alpha*-*-osf* *-*-ecoff pdp11-aout
+
+# the rest of this file is generated with the following script:
+# # script begin
+# sed -n 's:^[ 	]*\.weakref .*, \(u.*\)$:.* U \1:p' weakref1.s | uniq | while read line; do echo "#..."; echo "$line"; done
+# echo \#pass
+# # script output:
+#...
+.* U ua2
+#...
+.* U ua3
+#...
+.* U ua4
+#...
+.* U ub2
+#...
+.* U ub3
+#...
+.* U ub4
+#...
+.* U uc2
+#...
+.* U uc3
+#...
+.* U uc4
+#...
+.* U uc5
+#...
+.* U uc6
+#...
+.* U uc7
+#...
+.* U uc8
+#...
+.* U uc9
+#...
+.* U um2
+#...
+.* U um5
+#...
+.* U uh8
+#...
+.* U uh9
+#...
+.* U ur6
+#...
+.* U ud5
+#pass
-- 
Alexandre Oliva         http://www.lsd.ic.unicamp.br/~oliva/
Red Hat Compiler Engineer   aoliva@{redhat.com, gcc.gnu.org}
Free Software Evangelist  oliva@{lsd.ic.unicamp.br, gnu.org}

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