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 12, 2005, Nick Clifton <nickc@redhat.com> wrote:

> Hi Alex,
>> Ok to install?

> Sorry no.  The code itself is fine,

Not really, see below.

> but the new weakref1.[sd] test is not.  It causes new failures for
> lots of different toolchains, including, but not limited to:

As it turned out, your list of targets uncovered at least one bug that
affected all targets, including ELF ones (but, oddly, not x86), and
whose fix enabled me to address one of the FIXMEs in the old testcase:
we were failing to resolve properly chains of weakrefs ending in a
global defined symbols, and in some cases we failed to omit the
weakrefd from the symbol table even if it was not referenced.  This
required a bit of tweaking of COFF support in the assembler to avoid
making unreferenced weakrefds external, and a pair of new hooks for PE
to move the special .weak handling from the pseudo handler to
something that would be called by S_SET_WEAK, and to enable its
effects to be reversed.  We now get proper weak symbols on COFF and
PE too.

>   arc-elf h8300-elf i386-coff i686-pc-cygwin ip2k-elf m32r-elf
>   m68k-elf maxq-coff mcore-pe mingw32-pe mips-elf mn10300-elf
>   powerpc-ibm-aix5.2.0 sh-nto

> I have only looked at a few logs so far, but I suspect that the
> problem is going to be the same with all of them - your weakref1.d
> file is too restrictive in the output it is checking for, and it does
> not make allowances for extra symbols that particular ports may insert
> into an object file.

Yeah, I had to relax it significantly to enable it to match coff.  I
ended up splitting up the testcase into a number of tests, using nm to
determine whether a symbol was handled correctly, and using objdump
only to check for relocations.  That said, the relocation checks had
to accept variations of symbol or section plus addend that, in some
cases (symbol + addend) don't even make sense to me, but I figured I
wouldn't try to change the behavior for ports I'm not familiar with.
I've verified that the apparent errors are present without weakref
too, so I just left it alone and arranged for the relocation regexps
to match.

> If you can fix this testcase so that it does not introduce new
> failures, (or if you can show for specific toolchains that the
> failures are due to real, target-specific bugs) then you have my
> approval to check your patch in.

Here's the revised patch.  Tested on amd64-linux-gnu and all of the
above.  Ok to install?

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-20 04:00:01.000000000 -0200
+++ gas/read.c	2005-10-20 04:00:29.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;
+
+  exp.X_op = O_symbol;
+  exp.X_add_number = 0;
+  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-20 04:00:01.000000000 -0200
+++ gas/read.h	2005-10-20 04:00:29.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-20 04:00:01.000000000 -0200
+++ gas/struc-symbol.h	2005-10-20 04:00:29.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-20 04:00:01.000000000 -0200
+++ gas/symbols.c	2005-10-20 04:00:29.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-20 04:00:01.000000000 -0200
+++ gas/symbols.h	2005-10-20 04:00:29.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-20 04:00:01.000000000 -0200
+++ gas/write.c	2005-10-20 04:00:29.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-20 04:00:01.000000000 -0200
+++ gas/doc/as.texinfo	2005-10-20 04:00:29.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-20 04:00:01.000000000 -0200
+++ gas/doc/internals.texi	2005-10-20 04:00:29.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-20 04:00:01.000000000 -0200
+++ gas/testsuite/gas/all/gas.exp	2005-10-20 04:00:29.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-20 04:00:29.000000000 -0200
@@ -0,0 +1,108 @@
+#objdump: -r
+#name: weakref tests, relocations
+
+#...
+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-20 04:00:29.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
+lr1 = l
+.long lr1
+
+.long lr2
+.weakref lr2, nr2
+lr2 = l
+.long lr2
+
+Wwr3 = l
+.long Wwr3
+.weakref Wwr3, wr3
+.long Wwr3
+
+Wwr4 = l
+.weakref Wwr4, wr4
+.long Wwr4
+
+Wwr5 = l
+.long Wwr5
+.weakref Wwr5, wr5
+
+.weakref lr6, ur6
+.long lr6
+lr6 = l
+.long ur6
+
+.weakref lr7, nr7
+.long lr7
+lr7:
+.long lr7
+
+/* d# target symbol definitions */
+.weakref Wld1, ld1
+.long Wld1
+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-20 04:00:29.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-20 04:00:29.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-20 04:00:02.000000000 -0200
+++ gas/config/obj-coff.c	2005-10-20 04:00:29.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-20 04:00:02.000000000 -0200
+++ gas/config/obj-coff.h	2005-10-20 04:00:29.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-20 04:00:29.000000000 -0200
@@ -0,0 +1,62 @@
+#nm: --undefined-only --no-sort
+#name: weakref tests, weak undefined syms
+#source: weakref1.s
+
+# 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-20 03:38:49.000000000 -0200
@@ -0,0 +1,14 @@
+#nm: --defined-only --extern-only --no-sort
+#name: weakref tests, global syms
+#source: weakref1.s
+
+# 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-20 03:57:10.000000000 -0200
@@ -0,0 +1,33 @@
+#nm: --defined-only --no-sort
+#name: weakref tests, local syms
+#source: weakref1.s
+#not-target: *-*-aix*
+
+# the rest of this file is generated with the following script:
+# # script begin
+# sed -n 's,^\(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-20 03:35:04.000000000 -0200
@@ -0,0 +1,50 @@
+#nm: --undefined-only --no-sort
+#name: weakref tests, strong undefined syms
+#source: weakref1.s
+
+# 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]