This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


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

Fixes for regressions involving weak symbols



Many assemblers will complain when we emit multiple .weak directives for
the same symbol (gnu-as ignores the multiple .weak directives).  This patch
avoids the problem by removing a symbol off the pending weak declarations list
when we provide a definition for a function or variable.

It fixes a variety of regressions on Solaris & SCO when using the system
assembler.

Mon Jun  7 20:34:20 1999  Robert Lipe <robertlipe@usa.net>
                          Jeffrey A Law  (law@cygnus.com)

        * varasm.c (assemble_start_function): Remove the function
        from the pending weak decls list when we define a function.
        (assemble_variable): Similarly for variables.
        (weak_finish): Ignore items on the list with a NULL name.
        (remove_from_ending_weak_list); New function to "remove" an item
        from the pending weak declarations list.

Index: varasm.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/varasm.c,v
retrieving revision 1.59.4.2
diff -c -3 -p -r1.59.4.2 varasm.c
*** varasm.c	1999/05/27 02:02:12	1.59.4.2
--- varasm.c	1999/06/08 02:41:26
*************** static void mark_constants		PROTO((rtx))
*** 141,146 ****
--- 141,147 ----
  static int output_addressed_constants	PROTO((tree));
  static void output_after_function_constants PROTO((void));
  static void output_constructor		PROTO((tree, int));
+ static void remove_from_pending_weak_list	PROTO ((char *));
  #ifdef ASM_OUTPUT_BSS
  static void asm_output_bss		PROTO((FILE *, tree, char *, int, int));
  #endif
*************** assemble_start_function (decl, fnname)
*** 1012,1018 ****
  
  #ifdef ASM_WEAKEN_LABEL
        if (DECL_WEAK (decl))
! 	ASM_WEAKEN_LABEL (asm_out_file, fnname);
        else
  #endif
        ASM_GLOBALIZE_LABEL (asm_out_file, fnname);
--- 1013,1025 ----
  
  #ifdef ASM_WEAKEN_LABEL
        if (DECL_WEAK (decl))
! 	{
! 	  ASM_WEAKEN_LABEL (asm_out_file, fnname);
! 	  /* Remove this function from the pending weak list so that
! 	     we do not emit multiple .weak directives for it.  */
! 	  remove_from_pending_weak_list
! 	    (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)));
! 	}
        else
  #endif
        ASM_GLOBALIZE_LABEL (asm_out_file, fnname);
*************** assemble_variable (decl, top_level, at_e
*** 1445,1452 ****
    if (TREE_PUBLIC (decl) && DECL_NAME (decl))
      {
  #ifdef ASM_WEAKEN_LABEL
!       if (DECL_WEAK (decl))
! 	ASM_WEAKEN_LABEL (asm_out_file, name);
        else
  #endif
        ASM_GLOBALIZE_LABEL (asm_out_file, name);
--- 1452,1465 ----
    if (TREE_PUBLIC (decl) && DECL_NAME (decl))
      {
  #ifdef ASM_WEAKEN_LABEL
!       if (DECL_WEAK (decl)) 
! 	{
! 	  ASM_WEAKEN_LABEL (asm_out_file, name);
! 	   /* Remove this variable from the pending weak list so that
! 	      we do not emit multiple .weak directives for it.  */
! 	  remove_from_pending_weak_list
! 	    (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)));
! 	}
        else
  #endif
        ASM_GLOBALIZE_LABEL (asm_out_file, name);
*************** weak_finish ()
*** 4350,4359 ****
      {
        struct weak_syms *t;
        for (t = weak_decls; t; t = t->next)
  	{
! 	  ASM_WEAKEN_LABEL (asm_out_file, t->name);
! 	  if (t->value)
! 	    ASM_OUTPUT_DEF (asm_out_file, t->name, t->value);
  	}
      }
  #endif
--- 4363,4395 ----
      {
        struct weak_syms *t;
        for (t = weak_decls; t; t = t->next)
+ 	{
+ 	  if (t->name)
+ 	    {
+ 	      ASM_WEAKEN_LABEL (asm_out_file, t->name);
+ 	      if (t->value)
+ 		ASM_OUTPUT_DEF (asm_out_file, t->name, t->value);
+ 	    }
+ 	}
+     }
+ #endif
+ }
+ 
+ /* Remove NAME from the pending list of weak symbols.  This prevents
+    the compiler from emitting multiple .weak directives which confuses
+    some assemblers.  */
+ static void
+ remove_from_pending_weak_list (name)
+      char *name;
+ {
+ #ifdef HANDLE_PRAGMA_WEAK
+   if (HANDLE_PRAGMA_WEAK)
+     {
+       struct weak_syms *t;
+       for (t = weak_decls; t; t = t->next)
  	{
! 	  if (strcmp (name, t->name) == 0)
! 	    t->name = NULL;
  	}
      }
  #endif
*************** assemble_alias (decl, target)
*** 4375,4381 ****
      {
  #ifdef ASM_WEAKEN_LABEL
        if (DECL_WEAK (decl))
! 	ASM_WEAKEN_LABEL (asm_out_file, name);
        else
  #endif
  	ASM_GLOBALIZE_LABEL (asm_out_file, name);
--- 4411,4423 ----
      {
  #ifdef ASM_WEAKEN_LABEL
        if (DECL_WEAK (decl))
!  	{
! 	  ASM_WEAKEN_LABEL (asm_out_file, name);
! 	  /* Remove this function from the pending weak list so that
! 	     we do not emit multiple .weak directives for it.  */
! 	  remove_from_pending_weak_list
! 	    (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)));
! 	}
        else
  #endif
  	ASM_GLOBALIZE_LABEL (asm_out_file, name);



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