--- gcc/tlink.c.jj	2012-01-30 00:08:28.000000000 +0100
+++ gcc/tlink.c	2012-02-03 10:13:08.799161429 +0100
@@ -67,10 +67,17 @@ typedef struct file_hash_entry
   int tweaking;
 } file;
 
+typedef struct demangled_equiv_entry
+{
+  const char *mangled;
+  struct demangled_equiv_entry *next;
+} demangled_equiv;
+
 typedef struct demangled_hash_entry
 {
   const char *key;
   const char *mangled;
+  demangled_equiv *equiv;
 } demangled;
 
 /* Hash and comparison functions for these hash tables.  */
@@ -598,10 +605,43 @@ demangle_new_symbols (void)
 	continue;
 
       dem = demangled_hash_lookup (p, true);
-      dem->mangled = sym->key;
+      if (dem->mangled)
+	{
+	  demangled_equiv *equiv = XCNEW (demangled_equiv);
+	  equiv->mangled = sym->key;
+	  equiv->next = dem->equiv;
+	  dem->equiv = equiv;
+	}
+      else
+        dem->mangled = sym->key;
     }
 }
 
+/* Helper function of scan_linker_output.  Handle a single symbol SYM.
+   Returns 1 if an error happened, 0 otherwise.  */
+
+static bool
+handle_sym (FILE *stream, symbol *sym)
+{
+  if (sym && sym->tweaked)
+    {
+      error ("'%s' was assigned to '%s', but was not defined "
+	     "during recompilation, or vice versa",
+	     sym->key, sym->file->key);
+      fclose (stream);
+      return true;
+    }
+  if (sym && !sym->tweaking)
+    {
+      if (tlink_verbose >= 2)
+	fprintf (stderr, _("collect: tweaking %s in %s\n"),
+		 sym->key, sym->file->key);
+      sym->tweaking = 1;
+      file_push (sym->file);
+    }
+  return false;
+}
+
 /* Step through the output of the linker, in the file named FNAME, and
    adjust the settings for each symbol encountered.  */
 
@@ -719,7 +759,19 @@ scan_linker_output (const char *fname)
 	      *q = 0;
 	      dem = demangled_hash_lookup (p, false);
 	      if (dem)
-		sym = symbol_hash_lookup (dem->mangled, false);
+		{
+		  if (dem->equiv)
+		    {
+		      demangled_equiv *equiv;
+		      for (equiv = dem->equiv; equiv; equiv = equiv->next)
+			{
+			  sym = symbol_hash_lookup (equiv->mangled, false);
+			  if (handle_sym (stream, sym))
+			    return 0;
+			}
+		    }
+		  sym = symbol_hash_lookup (dem->mangled, false);
+		}
 	      else
 		{
 		  if (!strncmp (p, USER_LABEL_PREFIX,
@@ -730,22 +782,8 @@ scan_linker_output (const char *fname)
 	    }
 	}
 
-      if (sym && sym->tweaked)
-	{
-	  error ("'%s' was assigned to '%s', but was not defined "
-		 "during recompilation, or vice versa",
-		 sym->key, sym->file->key);
-	  fclose (stream);
-	  return 0;
-	}
-      if (sym && !sym->tweaking)
-	{
-	  if (tlink_verbose >= 2)
-	    fprintf (stderr, _("collect: tweaking %s in %s\n"),
-		     sym->key, sym->file->key);
-	  sym->tweaking = 1;
-	  file_push (sym->file);
-	}
+      if (handle_sym (stream, sym))
+	return 0;
 
       obstack_free (&temporary_obstack, temporary_firstobj);
     }
