* doc/tm.texi (ASM_WEAKEN_DECL): Document.
authoramodra <amodra@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 1 Mar 2002 06:00:38 +0000 (06:00 +0000)
committeramodra <amodra@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 1 Mar 2002 06:00:38 +0000 (06:00 +0000)
(ASM_WEAKEN_LABEL): Mention ASM_WEAKEN_DECL.
(SUPPORTS_WEAK): Likewise.
* output.h (add_weak): Add tree param.
* varasm.c (add_weak): Likewise.  Save decl.
(struct weak_syms): Add decl field.
(mark_weak_decls): New function.
(init_varasm_once): ggc_add_root mark_weak_decls.
(assemble_start_function): Use ASM_WEAKEN_DECL.
(assemble_variable): Likewise.
(assemble_alias): Likewise.
(declare_weak): Pass decl to add_weak.
(weak_finish): Use ASM_WEAKEN_DECL. Try to find decl.
(remove_from_pending_weak_list): Declare and define for
ASM_WEAKEN_DECL.
* c-pragma.c (handle_pragma_weak): Adjust add_weak call.
* c-pragma.h (HANDLE_PRAGMA_WEAK): Define if ASM_WEAKEN_DECL too.
* defaults.h (SUPPORTS_WEAK): Likewise.
* config/rs6000/linux64.h (ASM_DECLARE_FUNCTION_NAME): Don't emit
.weak for code sym.  Do emit .size for descriptor sym.
(ASM_DECLARE_FUNCTION_SIZE): Define.
* config/rs6000/rs6000.h (ASM_WEAKEN_DECL): Define.
(ASM_OUTPUT_DEF_FROM_DECLS): Don't emit .weak here.  Don't output
.lglobl unless TARGET_XCOFF.  Formatting fixes.
* config/rs6000/xcoff.h (ASM_DECLARE_FUNCTION_NAME): Don't emit
.weak for code sym.
(HANDLE_PRAGMA_WEAK): Remove.
(ASM_WEAKEN_LABEL): Remove.
* config/rs6000/aix.h (HANDLE_SYSV_PRAGMA): Define.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@50181 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/c-pragma.c
gcc/c-pragma.h
gcc/config/rs6000/aix.h
gcc/config/rs6000/linux64.h
gcc/config/rs6000/rs6000.h
gcc/config/rs6000/xcoff.h
gcc/defaults.h
gcc/doc/tm.texi
gcc/output.h
gcc/varasm.c

index 2066310..00ced4e 100644 (file)
@@ -1,3 +1,36 @@
+2002-03-01  Alan Modra  <amodra@bigpond.net.au>
+           David Edelsohn  <edelsohn@gnu.org>
+
+       * doc/tm.texi (ASM_WEAKEN_DECL): Document.
+       (ASM_WEAKEN_LABEL): Mention ASM_WEAKEN_DECL.
+       (SUPPORTS_WEAK): Likewise.
+       * output.h (add_weak): Add tree param.
+       * varasm.c (add_weak): Likewise.  Save decl.
+       (struct weak_syms): Add decl field.
+       (mark_weak_decls): New function.
+       (init_varasm_once): ggc_add_root mark_weak_decls.
+       (assemble_start_function): Use ASM_WEAKEN_DECL.
+       (assemble_variable): Likewise.
+       (assemble_alias): Likewise.
+       (declare_weak): Pass decl to add_weak.
+       (weak_finish): Use ASM_WEAKEN_DECL. Try to find decl.
+       (remove_from_pending_weak_list): Declare and define for
+       ASM_WEAKEN_DECL.
+       * c-pragma.c (handle_pragma_weak): Adjust add_weak call.
+       * c-pragma.h (HANDLE_PRAGMA_WEAK): Define if ASM_WEAKEN_DECL too.
+       * defaults.h (SUPPORTS_WEAK): Likewise.
+       * config/rs6000/linux64.h (ASM_DECLARE_FUNCTION_NAME): Don't emit
+       .weak for code sym.  Do emit .size for descriptor sym.
+       (ASM_DECLARE_FUNCTION_SIZE): Define.
+       * config/rs6000/rs6000.h (ASM_WEAKEN_DECL): Define.
+       (ASM_OUTPUT_DEF_FROM_DECLS): Don't emit .weak here.  Don't output
+       .lglobl unless TARGET_XCOFF.  Formatting fixes.
+       * config/rs6000/xcoff.h (ASM_DECLARE_FUNCTION_NAME): Don't emit
+       .weak for code sym.
+       (HANDLE_PRAGMA_WEAK): Remove.
+       (ASM_WEAKEN_LABEL): Remove.
+       * config/rs6000/aix.h (HANDLE_SYSV_PRAGMA): Define.
+
 2002-03-01  Jason Merrill  <jason@redhat.com>
 
        * tree.h (TARGET_EXPR_SLOT, TARGET_EXPR_INITIAL): New macros.
index f0c2b40..26bf277 100644 (file)
@@ -1,5 +1,5 @@
 /* Handle #pragma, system V.4 style.  Supports #pragma weak and #pragma pack.
-   Copyright (C) 1992, 1997, 1998, 1999, 2000, 2001
+   Copyright (C) 1992, 1997, 1998, 1999, 2000, 2001, 2002
    Free Software Foundation, Inc.
 
 This file is part of GCC.
@@ -298,7 +298,8 @@ handle_pragma_weak (dummy)
   if (t != CPP_EOF)
     warning ("junk at end of #pragma weak");
 
-  add_weak (IDENTIFIER_POINTER (name), value ? IDENTIFIER_POINTER (value) : 0);
+  add_weak (NULL_TREE, IDENTIFIER_POINTER (name),
+           value ? IDENTIFIER_POINTER (value) : NULL);
 }
 #endif
 
index ff00f32..8d0c4f5 100644 (file)
@@ -23,9 +23,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #define GCC_C_PRAGMA_H
 
 #ifdef HANDLE_SYSV_PRAGMA
-/* Support #pragma weak iff ASM_WEAKEN_LABEL and ASM_OUTPUT_WEAK_ALIAS are
-   defined.  */
-#if defined (ASM_WEAKEN_LABEL) && defined (ASM_OUTPUT_WEAK_ALIAS)
+#if ((defined (ASM_WEAKEN_LABEL) && defined (ASM_OUTPUT_WEAK_ALIAS)) \
+     || defined (ASM_WEAKEN_DECL))
 #define HANDLE_PRAGMA_WEAK SUPPORTS_WEAK
 #endif
 
index 2738a37..d8dde5b 100644 (file)
@@ -1,6 +1,6 @@
 /* Definitions of target machine for GNU compiler,
    for IBM RS/6000 POWER running AIX.
-   Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+   Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
 
 This file is part of GNU CC.
 
@@ -27,6 +27,9 @@ Boston, MA 02111-1307, USA.  */
    collect has a chance to see them, so scan the object files directly.  */
 #define COLLECT_EXPORT_LIST
 
+/* Handle #pragma weak and #pragma pack.  */
+#define HANDLE_SYSV_PRAGMA
+
 /* This is the only version of nm that collect2 can work with.  */
 #define REAL_NM_FILE_NAME "/usr/ucb/nm"
 
index b39d4f0..40b64dc 100644 (file)
@@ -1,6 +1,6 @@
 /* Definitions of target machine for GNU compiler,
    for 64 bit powerpc linux.
-   Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+   Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
 
 This file is part of GNU CC.
 
@@ -250,32 +250,39 @@ do {                                              \
       fputs (DOUBLE_INT_ASM_OP, (FILE));                               \
       putc ('.', (FILE));                                              \
       assemble_name ((FILE), (NAME));                                  \
-      putc ('\n', (FILE));                                             \
-      fputs (DOUBLE_INT_ASM_OP, (FILE));                               \
-      fputs (".TOC.@tocbase, 0\n\t.previous\n", (FILE));               \
-                                                                       \
-      if (TREE_PUBLIC (DECL))                                          \
+      fputs (",.TOC.@tocbase,0\n\t.previous\n\t.size\t", (FILE));      \
+      assemble_name ((FILE), (NAME));                                  \
+      fputs (",24\n\t.type\t.", (FILE));                               \
+      assemble_name ((FILE), (NAME));                                  \
+      fputs (",@function\n", (FILE));                                  \
+      if (TREE_PUBLIC (DECL) && ! DECL_WEAK (DECL))                    \
         {                                                              \
-         if (DECL_WEAK (DECL))                                         \
-           fputs ("\t.weak\t", (FILE));                                \
-         else                                                          \
-           fputs ("\t.globl\t", (FILE));                               \
-         putc ('.', (FILE));                                           \
+         fputs ("\t.globl\t.", (FILE));                                \
          assemble_name ((FILE), (NAME));                               \
          putc ('\n', (FILE));                                          \
         }                                                              \
-      fputs (TYPE_ASM_OP, (FILE));                                     \
-      putc ('.', (FILE));                                              \
-      assemble_name ((FILE), (NAME));                                  \
-      putc (',', (FILE));                                              \
-      fprintf ((FILE), TYPE_OPERAND_FMT, "function");                  \
-      putc ('\n', (FILE));                                             \
       ASM_DECLARE_RESULT ((FILE), DECL_RESULT (DECL));                 \
       putc ('.', (FILE));                                              \
       ASM_OUTPUT_LABEL ((FILE), (NAME));                               \
     }                                                                  \
   while (0)
 
+/* This is how to declare the size of a function.  */
+#undef ASM_DECLARE_FUNCTION_SIZE
+#define        ASM_DECLARE_FUNCTION_SIZE(FILE, FNAME, DECL)                    \
+  do                                                                   \
+    {                                                                  \
+      if (!flag_inhibit_size_directive)                                        \
+       {                                                               \
+         fputs ("\t.size\t.", (FILE));                                 \
+         assemble_name ((FILE), (FNAME));                              \
+         fputs (",.-.", (FILE));                                       \
+         assemble_name ((FILE), (FNAME));                              \
+         putc ('\n', (FILE));                                          \
+       }                                                               \
+    }                                                                  \
+  while (0)
+
 /* Return non-zero if this entry is to be written into the constant
    pool in a special way.  We do so if this is a SYMBOL_REF, LABEL_REF
    or a CONST containing one of them.  If -mfp-in-toc (the default),
index 3c509c6..dbb1474 100644 (file)
@@ -2422,43 +2422,71 @@ extern int toc_initialized;
 #define RS6000_WEAK 0
 #endif
 
-/* This implementes the `alias' attribute.  */
-#define ASM_OUTPUT_DEF_FROM_DECLS(FILE,decl,target)    \
-do {                                                   \
-  const char * alias = XSTR (XEXP (DECL_RTL (decl), 0), 0); \
-  const char * name = IDENTIFIER_POINTER (target);     \
-  if (TREE_CODE (decl) == FUNCTION_DECL                        \
-      && DEFAULT_ABI == ABI_AIX)                       \
-    {                                                  \
-      if (TREE_PUBLIC (decl))                          \
-       {                                               \
-         if (RS6000_WEAK && DECL_WEAK (decl))          \
-           {                                           \
-             fputs ("\t.weak .", FILE);                \
-             assemble_name (FILE, alias);              \
-             putc ('\n', FILE);                        \
-           }                                           \
-         else                                          \
-           {                                           \
-             fputs ("\t.globl .", FILE);               \
-             assemble_name (FILE, alias);              \
-             putc ('\n', FILE);                        \
-           }                                           \
-       }                                               \
-      else                                             \
-       {                                               \
-         fputs ("\t.lglobl .", FILE);                  \
-         assemble_name (FILE, alias);                  \
-         putc ('\n', FILE);                            \
-       }                                               \
-      fputs ("\t.set .", FILE);                                \
-      assemble_name (FILE, alias);                     \
-      fputs (",.", FILE);                              \
-      assemble_name (FILE, name);                      \
-      fputc ('\n', FILE);                              \
-    }                                                  \
-  ASM_OUTPUT_DEF (FILE, alias, name);                  \
-} while (0)
+#if RS6000_WEAK
+/* Used in lieu of ASM_WEAKEN_LABEL.  */
+#define        ASM_WEAKEN_DECL(FILE, DECL, NAME, VAL)                          \
+  do                                                                   \
+    {                                                                  \
+      fputs ("\t.weak\t", (FILE));                                     \
+      assemble_name ((FILE), (NAME));                                  \
+      if ((DECL) && TREE_CODE (DECL) == FUNCTION_DECL                  \
+         && DEFAULT_ABI == ABI_AIX)                                    \
+       {                                                               \
+         fputs (",.", (FILE));                                         \
+         assemble_name ((FILE), (NAME));                               \
+       }                                                               \
+      fputc ('\n', (FILE));                                            \
+      if (VAL)                                                         \
+       {                                                               \
+         ASM_OUTPUT_DEF ((FILE), (NAME), (VAL));                       \
+         if ((DECL) && TREE_CODE (DECL) == FUNCTION_DECL               \
+             && DEFAULT_ABI == ABI_AIX)                                \
+           {                                                           \
+             fputs ("\t.set\t.", (FILE));                              \
+             assemble_name ((FILE), (NAME));                           \
+             fputs (",.", (FILE));                                     \
+             assemble_name ((FILE), (VAL));                            \
+             fputc ('\n', (FILE));                                     \
+           }                                                           \
+       }                                                               \
+    }                                                                  \
+  while (0)
+#endif
+
+/* This implements the `alias' attribute.  */
+#undef ASM_OUTPUT_DEF_FROM_DECLS
+#define        ASM_OUTPUT_DEF_FROM_DECLS(FILE, DECL, TARGET)                   \
+  do                                                                   \
+    {                                                                  \
+      const char *alias = XSTR (XEXP (DECL_RTL (DECL), 0), 0);         \
+      const char *name = IDENTIFIER_POINTER (TARGET);                  \
+      if (TREE_CODE (DECL) == FUNCTION_DECL                            \
+         && DEFAULT_ABI == ABI_AIX)                                    \
+       {                                                               \
+         if (TREE_PUBLIC (DECL))                                       \
+           {                                                           \
+             if (!RS6000_WEAK || !DECL_WEAK (DECL))                    \
+               {                                                       \
+                 fputs ("\t.globl\t.", FILE);                          \
+                 assemble_name (FILE, alias);                          \
+                 putc ('\n', FILE);                                    \
+               }                                                       \
+           }                                                           \
+         else if (TARGET_XCOFF)                                        \
+           {                                                           \
+             fputs ("\t.lglobl\t.", FILE);                             \
+             assemble_name (FILE, alias);                              \
+             putc ('\n', FILE);                                        \
+           }                                                           \
+         fputs ("\t.set\t.", FILE);                                    \
+         assemble_name (FILE, alias);                                  \
+         fputs (",.", FILE);                                           \
+         assemble_name (FILE, name);                                   \
+         fputc ('\n', FILE);                                           \
+       }                                                               \
+      ASM_OUTPUT_DEF (FILE, alias, name);                              \
+    }                                                                  \
+   while (0)
 
 /* Output to assembler file text saying following lines
    may contain character constants, extra white space, comments, etc.  */
index e60f3fe..a2ef6ec 100644 (file)
@@ -1,6 +1,6 @@
 /* Definitions of target machine for GNU compiler,
    for some generic XCOFF file format
-   Copyright (C) 2001 Free Software Foundation, Inc.
+   Copyright (C) 2001, 2002 Free Software Foundation, Inc.
 
 This file is part of GNU CC.
 
@@ -345,13 +345,7 @@ toc_section ()                                             \
     SYMBOL_REF_FLAG (sym_ref) = 1;                             \
   if (TREE_PUBLIC (DECL))                                      \
     {                                                          \
-      if (RS6000_WEAK && DECL_WEAK (decl))                     \
-       {                                                       \
-         fputs ("\t.weak .", FILE);                            \
-         RS6000_OUTPUT_BASENAME (FILE, NAME);                  \
-         putc ('\n', FILE);                                    \
-       }                                                       \
-      else                                                     \
+      if (!RS6000_WEAK || !DECL_WEAK (decl))                   \
        {                                                       \
          fputs ("\t.globl .", FILE);                           \
          RS6000_OUTPUT_BASENAME (FILE, NAME);                  \
@@ -464,20 +458,6 @@ toc_section ()                                             \
                xcoff_bss_section_name);                \
      } while (0)
 
-/* Output a weak symbol, if weak support present.  */
-#ifdef HAVE_GAS_WEAK
-#define HANDLE_PRAGMA_WEAK 1
-
-#define ASM_WEAKEN_LABEL(FILE, NAME)   \
-  do                                   \
-    {                                  \
-      fputs ("\t.weak ", (FILE));      \
-      assemble_name ((FILE), (NAME));  \
-      fputc ('\n', (FILE));            \
-    }                                  \
-  while (0)
-#endif /* HAVE_GAS_WEAK */
-
 /* This is how we tell the assembler that two symbols have the same value.  */
 #define SET_ASM_OP "\t.set "
 
index 2a7c567..3071f1f 100644 (file)
@@ -1,5 +1,5 @@
 /* Definitions of various defaults for tm.h macros.
-   Copyright (C) 1992, 1996, 1997, 1998, 1999, 2000, 2001
+   Copyright (C) 1992, 1996, 1997, 1998, 1999, 2000, 2001, 2002
    Free Software Foundation, Inc.
    Contributed by Ron Guilmette (rfg@monkeys.com)
 
@@ -158,7 +158,7 @@ do { ASM_OUTPUT_LABEL(FILE,LABEL_ALTERNATE_NAME (INSN)); } while (0)
 
 /* This determines whether or not we support weak symbols.  */
 #ifndef SUPPORTS_WEAK
-#ifdef ASM_WEAKEN_LABEL
+#if defined (ASM_WEAKEN_LABEL) || defined (ASM_WEAKEN_DECL)
 #define SUPPORTS_WEAK 1
 #else
 #define SUPPORTS_WEAK 0
index 0a9e842..dd22fd0 100644 (file)
@@ -6169,7 +6169,7 @@ itself; before and after that, output the additional assembler syntax
 for making that name global, and a newline.
 
 @findex ASM_WEAKEN_LABEL
-@item ASM_WEAKEN_LABEL
+@item ASM_WEAKEN_LABEL (@var{stream}, @var{name})
 A C statement (sans semicolon) to output to the stdio stream
 @var{stream} some commands that will make the label @var{name} weak;
 that is, available for reference from other files but only used if
@@ -6178,18 +6178,29 @@ no other definition is available.  Use the expression
 itself; before and after that, output the additional assembler syntax
 for making that name weak, and a newline.
 
-If you don't define this macro, GCC will not support weak
-symbols and you should not define the @code{SUPPORTS_WEAK} macro.
+If you don't define this macro or @code{ASM_WEAKEN_DECL}, GCC will not
+support weak symbols and you should not define the @code{SUPPORTS_WEAK}
+macro.
+
+@findex ASM_WEAKEN_DECL
+@item ASM_WEAKEN_DECL (@var{stream}, @var{decl}, @var{name}, @var{value})
+Combines (and replaces) the function of @code{ASM_WEAKEN_LABEL} and
+@code{ASM_OUTPUT_WEAK_ALIAS}, allowing access to the associated function
+or variable decl.  If @var{value} is not @code{NULL}, this C statement
+should output to the stdio stream @var{stream} assembler code which
+defines (equates) the weak symbol @var{name} to have the value
+@var{value}.  If @var{value} is @code{NULL}, it should output commands
+to make @var{name} weak.
 
 @findex SUPPORTS_WEAK
 @item SUPPORTS_WEAK
 A C expression which evaluates to true if the target supports weak symbols.
 
 If you don't define this macro, @file{defaults.h} provides a default
-definition.  If @code{ASM_WEAKEN_LABEL} is defined, the default
-definition is @samp{1}; otherwise, it is @samp{0}.  Define this macro if
-you want to control weak symbol support with a compiler flag such as
-@option{-melf}.
+definition.  If either @code{ASM_WEAKEN_LABEL} or @code{ASM_WEAKEN_DECL}
+is defined, the default definition is @samp{1}; otherwise, it is
+@samp{0}.  Define this macro if you want to control weak symbol support
+with a compiler flag such as @option{-melf}.
 
 @findex MAKE_DECL_ONE_ONLY (@var{decl})
 @item MAKE_DECL_ONE_ONLY
index df5cead..9c7adaf 100644 (file)
@@ -137,7 +137,7 @@ extern const char *get_insn_template PARAMS ((int, rtx));
 
 /* Add function NAME to the weak symbols list.  VALUE is a weak alias
    associated with NAME.  */
-extern int add_weak PARAMS ((const char *, const char *));
+extern int add_weak PARAMS ((tree, const char *, const char *));
 
 /* Functions in flow.c */
 extern void allocate_for_life_analysis PARAMS ((void));
index fa69592..f8fb16c 100644 (file)
@@ -42,6 +42,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "obstack.h"
 #include "hashtab.h"
 #include "c-pragma.h"
+#include "c-tree.h"
 #include "ggc.h"
 #include "langhooks.h"
 #include "tm_p.h"
@@ -166,7 +167,8 @@ static unsigned HOST_WIDE_INT array_size_for_constructor PARAMS ((tree));
 static unsigned min_align              PARAMS ((unsigned, unsigned));
 static void output_constructor         PARAMS ((tree, HOST_WIDE_INT,
                                                 unsigned int));
-#ifdef ASM_WEAKEN_LABEL
+static void mark_weak_decls            PARAMS ((void *));
+#if defined (ASM_WEAKEN_LABEL) || defined (ASM_WEAKEN_DECL)
 static void remove_from_pending_weak_list      PARAMS ((const char *));
 #endif
 static int in_named_entry_eq           PARAMS ((const PTR, const PTR));
@@ -1237,10 +1239,14 @@ assemble_start_function (decl, fnname)
            weak_global_object_name = name;
        }
 
-#ifdef ASM_WEAKEN_LABEL
+#if defined (ASM_WEAKEN_LABEL) || defined (ASM_WEAKEN_DECL)
       if (DECL_WEAK (decl))
        {
+#ifdef ASM_WEAKEN_DECL
+         ASM_WEAKEN_DECL (asm_out_file, decl, fnname, 0);
+#else
          ASM_WEAKEN_LABEL (asm_out_file, fnname);
+#endif
          /* Remove this function from the pending weak list so that
             we do not emit multiple .weak directives for it.  */
          remove_from_pending_weak_list
@@ -1644,10 +1650,14 @@ assemble_variable (decl, top_level, at_end, dont_output_data)
   /* First make the assembler name(s) global if appropriate.  */
   if (TREE_PUBLIC (decl) && DECL_NAME (decl))
     {
-#ifdef ASM_WEAKEN_LABEL
+#if defined (ASM_WEAKEN_LABEL) || defined (ASM_WEAKEN_DECL)
       if (DECL_WEAK (decl))
        {
+#ifdef ASM_WEAKEN_DECL
+         ASM_WEAKEN_DECL (asm_out_file, decl, name, 0);
+#else
          ASM_WEAKEN_LABEL (asm_out_file, name);
+#endif
           /* Remove this variable from the pending weak list so that
              we do not emit multiple .weak directives for it.  */
          remove_from_pending_weak_list
@@ -5012,17 +5022,31 @@ output_constructor (exp, size, align)
 struct weak_syms
 {
   struct weak_syms * next;
+  tree decl;
   const char * name;
   const char * value;
 };
 
 static struct weak_syms * weak_decls;
 
+/* Mark weak_decls for garbage collection.  */
+
+static void
+mark_weak_decls (arg)
+     void *arg;
+{
+  struct weak_syms *t;
+
+  for (t = *(struct weak_syms **) arg; t != NULL; t = t->next)
+    ggc_mark_tree (t->decl);
+}
+
 /* Add function NAME to the weak symbols list.  VALUE is a weak alias
    associated with NAME.  */
 
 int
-add_weak (name, value)
+add_weak (decl, name, value)
+     tree decl;
      const char *name;
      const char *value;
 {
@@ -5034,6 +5058,7 @@ add_weak (name, value)
     return 0;
 
   weak->next = weak_decls;
+  weak->decl = decl;
   weak->name = name;
   weak->value = value;
   weak_decls = weak;
@@ -5052,7 +5077,7 @@ declare_weak (decl)
   else if (TREE_ASM_WRITTEN (decl))
     error_with_decl (decl, "weak declaration of `%s' must precede definition");
   else if (SUPPORTS_WEAK)
-    add_weak (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)), NULL);
+    add_weak (decl, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)), NULL);
   else
     warning_with_decl (decl, "weak declaration of `%s' not supported");
 
@@ -5067,8 +5092,18 @@ weak_finish ()
   if (SUPPORTS_WEAK)
     {
       struct weak_syms *t;
-      for (t = weak_decls; t; t = t->next)
+      for (t = weak_decls; t != NULL; t = t->next)
        {
+#ifdef ASM_WEAKEN_DECL
+         tree decl = t->decl;
+         if (decl == NULL_TREE)
+           {
+             tree name = get_identifier (t->name);
+             if (name)
+               decl = lookup_name (name);
+           }
+         ASM_WEAKEN_DECL (asm_out_file, decl, t->name, t->value);
+#else
 #ifdef ASM_OUTPUT_WEAK_ALIAS
          ASM_OUTPUT_WEAK_ALIAS (asm_out_file, t->name, t->value);
 #else
@@ -5078,6 +5113,7 @@ weak_finish ()
          ASM_WEAKEN_LABEL (asm_out_file, t->name);
 #endif
 #endif
+#endif
        }
     }
 }
@@ -5085,7 +5121,7 @@ weak_finish ()
 /* Remove NAME from the pending list of weak symbols.  This prevents
    the compiler from emitting multiple .weak directives which confuses
    some assemblers.  */
-#ifdef ASM_WEAKEN_LABEL
+#if defined (ASM_WEAKEN_LABEL) || defined (ASM_WEAKEN_DECL)
 static void
 remove_from_pending_weak_list (name)
      const char *name;
@@ -5105,7 +5141,7 @@ remove_from_pending_weak_list (name)
         p = &(t->next);
     }
 }
-#endif /* ASM_WEAKEN_LABEL */
+#endif /* defined (ASM_WEAKEN_LABEL) || defined (ASM_WEAKEN_DECL) */
 
 /* Emit an assembler directive to make the symbol for DECL an alias to
    the symbol for TARGET.  */
@@ -5127,10 +5163,14 @@ assemble_alias (decl, target)
 
   if (TREE_PUBLIC (decl))
     {
-#ifdef ASM_WEAKEN_LABEL
+#if defined (ASM_WEAKEN_LABEL) || defined (ASM_WEAKEN_DECL)
       if (DECL_WEAK (decl))
-       {
+       {
+#ifdef ASM_WEAKEN_DECL
+         ASM_WEAKEN_DECL (asm_out_file, decl, name, 0);
+#else
          ASM_WEAKEN_LABEL (asm_out_file, name);
+#endif
          /* Remove this function from the pending weak list so that
             we do not emit multiple .weak directives for it.  */
          remove_from_pending_weak_list
@@ -5147,12 +5187,16 @@ assemble_alias (decl, target)
   ASM_OUTPUT_DEF (asm_out_file, name, IDENTIFIER_POINTER (target));
 #endif
   TREE_ASM_WRITTEN (decl) = 1;
-#else
-#ifdef ASM_OUTPUT_WEAK_ALIAS
+#else /* !ASM_OUTPUT_DEF */
+#if defined (ASM_OUTPUT_WEAK_ALIAS) || defined (ASM_WEAKEN_DECL)
   if (! DECL_WEAK (decl))
     warning ("only weak aliases are supported in this configuration");
 
+#ifdef ASM_WEAKEN_DECL
+  ASM_WEAKEN_DECL (asm_out_file, decl, name, IDENTIFIER_POINTER (target));
+#else
   ASM_OUTPUT_WEAK_ALIAS (asm_out_file, name, IDENTIFIER_POINTER (target));
+#endif
   TREE_ASM_WRITTEN (decl) = 1;
 #else
   warning ("alias definitions not supported in this configuration; ignored");
@@ -5232,6 +5276,7 @@ init_varasm_once ()
                mark_const_hash_entry);
   ggc_add_root (&const_str_htab, 1, sizeof const_str_htab,
                mark_const_str_htab);
+  ggc_add_root (&weak_decls, 1, sizeof weak_decls, mark_weak_decls);
 
   const_alias_set = new_alias_set ();
 }