This is the mail archive of the binutils@sources.redhat.com 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: [PING] Windows PECOFF weak symbol fixes for *-mingw32 and *-cygwin


Thanks for taking the time to complete a detailed review.  I've
addressed your comments below, and attached a revised patch.

Nick Clifton wrote:

>    * The arm-wince-pe, arm-epoc-pe and mcore-pe targets do not build 
> after applying this patch.   This is because USE_UNIQUE is only defined 
> for the i386 port in obj-coff.h but the code in weak_uniqify() uses 
> any_external_name regardless of whether USE_UNIQUE is defined or not.

Since this code really should apply to all PE targets, I moved the
definiton so its defined for all targets.

>    * If this problem is fixed (by defining USE_UNIQUE for all TE_PE 
> targets) then there is still a problem in that new linker testsuite 
> failures are introduced for those targets.

I think these failures come from incorrect weak symbol relocations and
similar things in the target CPU code.  This has probably always been
broken, independent of my changes.  As I don't really know anything
about non-i386 targets, I think the best thing to do here is to XFAIL
these tests, since they really should work, and could be fixed pretty
easily.  I've filed a bug about this also, PR gas/517.

I've also changed the testsuites to report UNSUPPORTED rather than
simply return for targets that supposedly don't support weak symbols, as
quite a few of them probably should, and it might be helpful to
maintainers to have that reminder in the logs.

>    * The new code does not follow the GNU Coding conventions.  In 
> particular functions should be declared with their return type on one 
> line followed by the function name on the next line.

I fixed the return types.

>    * The patch to bfd/coff-i386.c creates a local variable called 
> 'howto' but does not use it.

I removed the nascent howto variable.

>    * The change to the documentation in gas/doc/as.texinfo removes the 
> fact that supporting non-alias weak symbols for PE is a GNU extension.

I beleive this is correct.

It is no longer an extension.  That is, when a gas input file specifies
an object file that is not an alias, the output object files are
conforming and compatible PECOFF files, where before this particular
patch, they were not.  In other words, with this patch, it is no longer
possible to cause gas to emit non-conforming weak symbols.

I decided that the small discussion I had previously included was now
irrelevent, partly because of this, and partly because the new syntax is
not as expressive as the old syntax, as it is not able to create
non-searched weak symbols.  I don't think this is a problem, since
bfd/ld doesn't support them, and Microsoft's assembler has actually
never supported them (only Intel's assembler does).  No existing product
documentation describes them.  In addition, theres some evidence that
they haven't been used in the Microsoft world in at least a decade.

(Theres also a third sort of PECOFF weak symbol that I do not beleive
any assemblers in existance support, so I don't think lack of a complete
implementation is evidence of a problem.)

With this patch, .weak should "just work" and do the right thing, and no
additional considerations should be necessary.

>    * The change to ld-undefined/weak-undef.exp ought to make use of the 
> newly defined is_pecoff_format proc.

I slightly reorganized the target tests in this file to fix this.


I tested this revised patch on all of native i686-pc-mingw32, cross
arm-wince-pe, cross arm-epoc-pe, and cross mcore-unknown-pe.  The latter
three have two new XFAILs, as expected, and no new FAILs.


Aaron W. LaFramboise

2004-11-05  Aaron W. LaFramboise <aaron98wiridge9@aaronwl.com>

bfd
	* coff-i386.c (coff_i386_reloc): Fix weak symbols.
	* cofflink.c (_bfd_coff_link_input_bfd): Don't process
	C_NT_WEAK aux entries.
	(_bfd_coff_generic_relocate_section): Handle undefined
	aliases.

binutils
	* doc/binutils.texi (nm): Update.

gas
	* symbols.c (any_external_name): Define.
	(resolve_symbol_value): Do not convert weak symbols.
	(S_SET_EXTERNAL): Support any_external_name.
	(S_SET_NAME): Qualify parameter const.
	(symbol_equated_reloc_p): Don't equate weaks when relocating.
	* symbols.h (S_SET_NAME): Qualfiy parameter const.
	* tc.h (any_external_name): Declare.
	* config/obj-coff.c ("coff/pe.h"): Include for BFD
	assemblers also.
	(weak_is_altname): Declare and define.
	(weak_name2altname): Same.
	(weak_altname2name): Same.
	(weak_uniquify): Same.
	(weak_altprefix): Define.
	(obj_coff_weak): Change .weak syntax and handling.
	(coff_frob_symbol): Fix PE weak symbol alternates.
	* config/obj-coff.h (USE_UNIQUE): Define.
	* config/tc-i386.c (md_apply_fix3): Assume weak symbols
	are in another segment.
	(tc_gen_reloc): Remove broken addend hack.
	doc/as.texinfo: Update.

include
	coff/pe.h (IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY): Define.
	(IMAGE_WEAK_EXTERN_SEARCH_LIBRARY): Same.
	(IMAGE_WEAK_EXTERN_SEARCH_ALIAS): Same.

ld
	* testsuite/ld-scripts/weak.exp: Enable test on PE,
	XFAIL non-i386 PE.
	* testsuite/ld-undefined/weak-undef.exp: Enable test on PE,
	XFAIL non-i386 PE.
	* testsuite/lib/ld-lib.exp (is_pecoff_format): New.

Index: src/bfd/coff-i386.c
===================================================================
RCS file: /cvs/src/src/bfd/coff-i386.c,v
retrieving revision 1.20
diff -c -3 -p -r1.20 coff-i386.c
*** src/bfd/coff-i386.c	22 Jun 2004 05:35:37 -0000	1.20
--- src/bfd/coff-i386.c	5 Nov 2004 08:25:31 -0000
*************** coff_i386_reloc (abfd, reloc_entry, symb
*** 122,127 ****
--- 122,129 ----
  	  else
  	    diff = -reloc_entry->addend;
  	}
+       else if (symbol->flags & BSF_WEAK)
+ 	diff = reloc_entry->addend - symbol->value;
        else
  #endif
  	diff = reloc_entry->addend;
Index: src/bfd/cofflink.c
===================================================================
RCS file: /cvs/src/src/bfd/cofflink.c,v
retrieving revision 1.50
diff -c -3 -p -r1.50 cofflink.c
*** src/bfd/cofflink.c	21 Oct 2004 15:28:19 -0000	1.50
--- src/bfd/cofflink.c	5 Nov 2004 08:25:36 -0000
*************** _bfd_coff_link_input_bfd (struct coff_fi
*** 1976,1982 ****
  		      auxp->x_file.x_n.x_offset = STRING_SIZE_SIZE + indx;
  		    }
  		}
! 	      else if (isymp->n_sclass != C_STAT || isymp->n_type != T_NULL)
  		{
  		  unsigned long indx;
  
--- 1976,1983 ----
  		      auxp->x_file.x_n.x_offset = STRING_SIZE_SIZE + indx;
  		    }
  		}
! 	      else if ((isymp->n_sclass != C_STAT || isymp->n_type != T_NULL)
! 		&& isymp->n_sclass != C_NT_WEAK)
  		{
  		  unsigned long indx;
  
*************** _bfd_coff_generic_relocate_section (bfd 
*** 2948,2956 ****
  		    input_bfd->tdata.coff_obj_data->sym_hashes[
  		    h->aux->x_sym.x_tagndx.l];
  
! 		  sec = h2->root.u.def.section;
! 		  val = h2->root.u.def.value + sec->output_section->vma
! 		    + sec->output_offset;
  		}
  	      else
                  /* This is a GNU extension. */
--- 2949,2965 ----
  		    input_bfd->tdata.coff_obj_data->sym_hashes[
  		    h->aux->x_sym.x_tagndx.l];
  
! 		  if (!h2 || h2->root.type == bfd_link_hash_undefined)
! 		    {
! 		      sec = bfd_abs_section_ptr;
! 		      val = 0;
! 		    }
! 		  else
! 		    {
! 		      sec = h2->root.u.def.section;
! 		      val = h2->root.u.def.value
! 			+ sec->output_section->vma + sec->output_offset;
! 		    }
  		}
  	      else
                  /* This is a GNU extension. */
Index: src/binutils/doc/binutils.texi
===================================================================
RCS file: /cvs/src/src/binutils/doc/binutils.texi,v
retrieving revision 1.60
diff -c -3 -p -r1.60 binutils.texi
*** src/binutils/doc/binutils.texi	3 Nov 2004 10:44:45 -0000	1.60
--- src/binutils/doc/binutils.texi	5 Nov 2004 08:25:45 -0000
*************** weak object symbol.  When a weak defined
*** 749,755 ****
  defined symbol, the normal defined symbol is used with no error.
  When a weak undefined symbol is linked and the symbol is not defined,
  the value of the symbol is determined in a system-specific manner without
! error.  Uppercase indicates that a default value has been specified.
  
  @item -
  The symbol is a stabs symbol in an a.out object file.  In this case, the
--- 749,756 ----
  defined symbol, the normal defined symbol is used with no error.
  When a weak undefined symbol is linked and the symbol is not defined,
  the value of the symbol is determined in a system-specific manner without
! error.  On some systems, uppercase indicates that a default value has been 
! specified.
  
  @item -
  The symbol is a stabs symbol in an a.out object file.  In this case, the
Index: src/gas/symbols.c
===================================================================
RCS file: /cvs/src/src/gas/symbols.c,v
retrieving revision 1.51
diff -c -3 -p -r1.51 symbols.c
*** src/gas/symbols.c	3 Nov 2004 01:54:24 -0000	1.51
--- src/gas/symbols.c	5 Nov 2004 08:25:50 -0000
*************** static void report_op_error (symbolS *, 
*** 77,82 ****
--- 77,89 ----
     set, and you are certain that this symbol won't be wanted in the
     output file, you can call symbol_create.  */
  
+ #ifdef USE_UNIQUE
+ /* The name of any external symbol is used to make weak symbol names
+  * unique.  USE_UNIQUE is defined in a target or object header if this
+  * is needed. */
+ const char *any_external_name;
+ #endif
+ 
  symbolS *
  symbol_new (const char *name, segT segment, valueT valu, fragS *frag)
  {
*************** resolve_symbol_value (symbolS *symp)
*** 989,995 ****
  	     relocation to detect this case, and convert the
  	     relocation to be against the symbol to which this symbol
  	     is equated.  */
! 	  if (! S_IS_DEFINED (add_symbol) || S_IS_COMMON (add_symbol))
  	    {
  	      if (finalize_syms)
  		{
--- 996,1006 ----
  	     relocation to detect this case, and convert the
  	     relocation to be against the symbol to which this symbol
  	     is equated.  */
! 	  if (! S_IS_DEFINED (add_symbol)
! #if defined(BFD_ASSEMBLER) || defined(S_IS_WEAK)
! 	   || S_IS_WEAK (add_symbol)
! #endif
! 	   || S_IS_COMMON (add_symbol))
  	    {
  	      if (finalize_syms)
  		{
*************** S_SET_EXTERNAL (symbolS *s)
*** 1905,1910 ****
--- 1916,1926 ----
      }
    s->bsym->flags |= BSF_GLOBAL;
    s->bsym->flags &= ~(BSF_LOCAL | BSF_WEAK);
+ 
+ #ifdef USE_UNIQUE
+   if (! any_external_name && S_GET_NAME(s)[0] != '.' )
+     any_external_name = S_GET_NAME (s);
+ #endif
  }
  
  void
*************** S_SET_THREAD_LOCAL (symbolS *s)
*** 1949,1955 ****
  }
  
  void
! S_SET_NAME (symbolS *s, char *name)
  {
    if (LOCAL_SYMBOL_CHECK (s))
      {
--- 1965,1971 ----
  }
  
  void
! S_SET_NAME (symbolS *s, const char *name)
  {
    if (LOCAL_SYMBOL_CHECK (s))
      {
*************** symbol_equated_reloc_p (symbolS *s)
*** 2225,2230 ****
--- 2241,2249 ----
       resolve_symbol_value to flag expression syms that have been
       equated.  */
    return (s->sy_value.X_op == O_symbol
+ #if defined(BFD_ASSEMBLER) || defined(S_IS_WEAK)
+ 	  && ! S_IS_WEAK (s)
+ #endif
  	  && ((s->sy_resolved && s->sy_value.X_op_symbol != NULL)
  	      || ! S_IS_DEFINED (s)
  	      || S_IS_COMMON (s)));
Index: src/gas/symbols.h
===================================================================
RCS file: /cvs/src/src/gas/symbols.h,v
retrieving revision 1.15
diff -c -3 -p -r1.15 symbols.h
*** src/gas/symbols.h	30 Nov 2003 19:07:12 -0000	1.15
--- src/gas/symbols.h	5 Nov 2004 08:25:50 -0000
*************** extern const char *S_GET_NAME (symbolS *
*** 105,111 ****
  extern segT S_GET_SEGMENT (symbolS *);
  extern void S_SET_SEGMENT (symbolS *, segT);
  extern void S_SET_EXTERNAL (symbolS *);
! extern void S_SET_NAME (symbolS *, char *);
  extern void S_CLEAR_EXTERNAL (symbolS *);
  extern void S_SET_WEAK (symbolS *);
  extern void S_SET_THREAD_LOCAL (symbolS *);
--- 105,111 ----
  extern segT S_GET_SEGMENT (symbolS *);
  extern void S_SET_SEGMENT (symbolS *, segT);
  extern void S_SET_EXTERNAL (symbolS *);
! extern void S_SET_NAME (symbolS *, const char *);
  extern void S_CLEAR_EXTERNAL (symbolS *);
  extern void S_SET_WEAK (symbolS *);
  extern void S_SET_THREAD_LOCAL (symbolS *);
Index: src/gas/tc.h
===================================================================
RCS file: /cvs/src/src/gas/tc.h,v
retrieving revision 1.8
diff -c -3 -p -r1.8 tc.h
*** src/gas/tc.h	3 Nov 2004 01:54:24 -0000	1.8
--- src/gas/tc.h	5 Nov 2004 08:25:50 -0000
*************** void    tc_headers_hook (object_headers 
*** 108,110 ****
--- 108,118 ----
  #endif
  
  #endif /* BFD_ASSEMBLER */
+ 
+ #ifdef USE_UNIQUE
+ /* The name of any external symbol is used to make weak symbol names
+  * unique.  USE_UNIQUE is defined in a target or object header if this
+  * is needed. */
+ extern const char *any_external_name;
+ #endif
+ 
Index: src/gas/config/obj-coff.c
===================================================================
RCS file: /cvs/src/src/gas/config/obj-coff.c,v
retrieving revision 1.73
diff -c -3 -p -r1.73 obj-coff.c
*** src/gas/config/obj-coff.c	27 Jul 2004 11:37:08 -0000	1.73
--- src/gas/config/obj-coff.c	5 Nov 2004 11:15:18 -0000
***************
*** 26,31 ****
--- 26,35 ----
  #include "obstack.h"
  #include "subsegs.h"
  
+ #ifdef TE_PE
+ #include "coff/pe.h"
+ #endif
+ 
  /* I think this is probably always correct.  */
  #ifndef KEEP_RELOC_INFO
  #define KEEP_RELOC_INFO
*************** static void obj_coff_ident PARAMS ((int)
*** 78,83 ****
--- 82,99 ----
  #ifdef BFD_ASSEMBLER
  static void obj_coff_loc PARAMS((int));
  #endif
+ 
+ #ifdef TE_PE
+ 
+ static int weak_is_altname PARAMS ((const char *));
+ static const char *weak_name2altname PARAMS ((const char *));
+ static const char *weak_altname2name PARAMS ((const char *));
+ static const char *weak_uniquify PARAMS ((const char *));
+ 
+ /* PE weak alternate symbols begin with this string */
+ static const char weak_altprefix[] = ".weak.";
+ 
+ #endif /* TE_PE */
  
  /* stack stuff */
  
*************** obj_coff_weak (ignore)
*** 1104,1109 ****
--- 1120,1128 ----
    char *name;
    int c;
    symbolS *symbolP;
+ #ifdef TE_PE
+   symbolS *alternateP;
+ #endif
  
    do
      {
*************** obj_coff_weak (ignore)
*** 1115,1120 ****
--- 1134,1140 ----
  	  ignore_rest_of_line ();
  	  return;
  	}
+       c = 0;
        symbolP = symbol_find_or_make (name);
        *input_line_pointer = c;
        SKIP_WHITESPACE ();
*************** obj_coff_weak (ignore)
*** 1126,1165 ****
  #ifdef TE_PE
        /* See _Microsoft Portable Executable and Common Object
         * File Format Specification_, section 5.5.3.
!        * Note that weak symbols without aux records are a GNU
!        * extension.
!        */
        S_SET_STORAGE_CLASS (symbolP, C_NT_WEAK);
  
!       if (c == '=')
! 	{
! 	  symbolS *alternateP;
! 	  long characteristics = 2;
! 	  ++input_line_pointer;
! 	  if (*input_line_pointer == '=')
! 	    {
! 	      characteristics = 1;
! 	      ++input_line_pointer;
! 	    }
! 
! 	  SKIP_WHITESPACE();
! 	  name = input_line_pointer;
! 	  c = get_symbol_end();
! 	  if (*name == 0)
! 	    {
! 	      as_warn (_("alternate name missing in .weak directive"));
! 	      ignore_rest_of_line ();
! 	      return;
! 	    }
! 	  alternateP = symbol_find_or_make (name);
! 	  *input_line_pointer = c;
  
! 	  S_SET_NUMBER_AUXILIARY (symbolP, 1);
! 	  SA_SET_SYM_TAGNDX (symbolP, alternateP);
! 	  SA_SET_SYM_FSIZE (symbolP, characteristics);
! 	}
! #else  /* TE_PE */
!       S_SET_STORAGE_CLASS (symbolP, C_WEAKEXT);
  #endif  /* TE_PE */
  
        if (c == ',')
--- 1146,1163 ----
  #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_LIBRARY);
  
!       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  /* TE_PE */
  
        if (c == ',')
*************** obj_coff_weak (ignore)
*** 1176,1181 ****
--- 1174,1243 ----
    demand_empty_rest_of_line ();
  }
  
+ #ifdef TE_PE
+ 
+ /* Return nonzero if name begins with weak alternate symbol prefix */
+ static int
+ weak_is_altname (name)
+   const char *name;
+ {
+   return ! strncmp (name, weak_altprefix, sizeof(weak_altprefix) - 1);
+ }
+ 
+ /* Return the name of the alternate symbol name corresponding to a 
+  * weak symbol's name. */
+ static const char *
+ weak_name2altname (name)
+   const char *name;
+ {
+   char *alt_name;
+   alt_name = xmalloc (sizeof (weak_altprefix)
+     + strlen (name));
+   strcpy (alt_name, weak_altprefix);
+   strcat (alt_name, name);
+   return alt_name;
+ }
+ 
+ /* Return the name of the weak symbol corresponding to an 
+  * alterate symbol. */
+ static const char *
+ weak_altname2name (name)
+   const char *name;
+ {
+   char *weak_name, *dot;
+ 
+   assert (weak_is_altname (name));
+ 
+   weak_name = xstrdup (name + 6);
+   if ((dot = strchr (weak_name, '.')))
+     *dot = 0;
+   return weak_name;
+ }
+ 
+ /* Make a weak symbol name unique by appending the name of an external 
+  * symbol.
+  */
+ static const char *
+ weak_uniquify (name)
+   const char *name;
+ {
+   char *ret;
+   const char *unique = any_external_name ? any_external_name : "";
+ 
+   assert (weak_is_altname (name));
+ 
+   if (strchr (name + sizeof(weak_altprefix), '.'))
+     return name;
+ 
+   ret = xmalloc (strlen (name) + strlen (unique) + 2);
+   strcpy (ret, name);
+   strcat (ret, ".");
+   strcat (ret, unique);
+   return ret;
+ }
+ 
+ #endif  /* TE_PE */
+ 
  void
  coff_obj_read_begin_hook ()
  {
*************** coff_frob_symbol (symp, punt)
*** 1214,1228 ****
    if (!block_stack)
      block_stack = stack_init (512, sizeof (symbolS*));
  
-   if (S_IS_WEAK (symp))
-     {
  #ifdef TE_PE
!       S_SET_STORAGE_CLASS (symp, C_NT_WEAK);
! #else
!       S_SET_STORAGE_CLASS (symp, C_WEAKEXT);
! #endif
      }
  
    if (!S_IS_DEFINED (symp)
        && !S_IS_WEAK (symp)
        && S_GET_STORAGE_CLASS (symp) != C_STAT)
--- 1276,1347 ----
    if (!block_stack)
      block_stack = stack_init (512, sizeof (symbolS*));
  
  #ifdef TE_PE
! 
!   if (S_GET_STORAGE_CLASS (symp) == C_NT_WEAK && ! S_IS_WEAK (symp)
!     && weak_is_altname (S_GET_NAME (symp)))
!     {
! 
!       /* 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)));
!       assert (weakp);
!       assert (S_GET_NUMBER_AUXILIARY (weakp) == 1);
! 
!       if (symbol_equated_p (weakp))
! 	{
! 	  /* The weak symbol has an alternate specified; symp is unneeded. */
! 	  S_SET_STORAGE_CLASS (weakp, C_NT_WEAK);
! 	  SA_SET_SYM_TAGNDX (weakp,
! 	    symbol_get_value_expression (weakp)->X_add_symbol);
! 
! 	  S_CLEAR_EXTERNAL (symp);
! 	  *punt = 1;
! 	  return;
! 	}
!       else
! 	{
! 	  /* The weak symbol has been assigned an alternate value.
!            * Copy this value to symp, and set symp as weakp's alternate. */
! 	  if (S_GET_STORAGE_CLASS (weakp) != C_NT_WEAK)
! 	    {
! 	      S_SET_STORAGE_CLASS (symp, S_GET_STORAGE_CLASS (weakp));
! 	      S_SET_STORAGE_CLASS (weakp, C_NT_WEAK);
! 	    }
! 	  if (S_IS_DEFINED (weakp))
! 	    {
! 	      /* This is a defined weak symbol.  Copy value information
! 	       * from the weak symbol itself to the alternate symbol.
! 	       */
! 	      symbol_set_value_expression (symp,
! 		symbol_get_value_expression (weakp));
! 	      symbol_set_frag (symp, symbol_get_frag (weakp));
! 	      S_SET_SEGMENT (symp, S_GET_SEGMENT (weakp));
! 	    }
! 	  else
! 	    {
! 	      /* This is an undefined weak symbol.  Define the alternate
! 	       * symbol to zero.
! 	       */
! 	      S_SET_VALUE (symp, 0);
! 	      S_SET_SEGMENT (symp, absolute_section);
! 	    }
! 
! 	  S_SET_NAME (symp, weak_uniquify (S_GET_NAME (symp)));
! 	  S_SET_STORAGE_CLASS (symp, C_EXT);
! 
! 	  S_SET_VALUE (weakp, 0);
! 	  S_SET_SEGMENT (weakp, undefined_section);
! 	}
      }
  
+ #else /* TE_PE */
+ 
+   if (S_IS_WEAK (symp))
+     S_SET_STORAGE_CLASS (symp, C_WEAKEXT);
+ 
+ #endif /* TE_PE */
+ 
    if (!S_IS_DEFINED (symp)
        && !S_IS_WEAK (symp)
        && S_GET_STORAGE_CLASS (symp) != C_STAT)
*************** symbol_dump ()
*** 1722,1731 ****
  #include "libbfd.h"
  #include "libcoff.h"
  
- #ifdef TE_PE
- #include "coff/pe.h"
- #endif
- 
  /* The NOP_OPCODE is for the alignment fill value.  Fill with nop so
     that we can stick sections together without causing trouble.  */
  #ifndef NOP_OPCODE
--- 1841,1846 ----
Index: src/gas/config/obj-coff.h
===================================================================
RCS file: /cvs/src/src/gas/config/obj-coff.h,v
retrieving revision 1.20
diff -c -3 -p -r1.20 obj-coff.h
*** src/gas/config/obj-coff.h	20 Nov 2003 00:01:54 -0000	1.20
--- src/gas/config/obj-coff.h	5 Nov 2004 08:26:01 -0000
***************
*** 180,185 ****
--- 180,190 ----
  #endif
  #endif
  
+ #ifdef TE_PE
+ /* PE weak symbols need USE_UNIQUE */
+ #define USE_UNIQUE 1
+ #endif
+ 
  /* Targets may also set this.  Also, if BFD_ASSEMBLER is defined, this
     will already have been defined.  */
  #undef SYMBOLS_NEED_BACKPOINTERS
Index: src/gas/config/tc-i386.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-i386.c,v
retrieving revision 1.159
diff -c -3 -p -r1.159 tc-i386.c
*** src/gas/config/tc-i386.c	4 Nov 2004 09:16:03 -0000	1.159
--- src/gas/config/tc-i386.c	5 Nov 2004 08:26:11 -0000
*************** md_apply_fix3 (fixP, valP, seg)
*** 4803,4809 ****
  #if defined (OBJ_COFF) && defined (TE_PE)
        /* For some reason, the PE format does not store a section
  	 address offset for a PC relative symbol.  */
!       if (S_GET_SEGMENT (fixP->fx_addsy) != seg)
  	value += md_pcrel_from (fixP);
  #endif
      }
--- 4803,4814 ----
  #if defined (OBJ_COFF) && defined (TE_PE)
        /* For some reason, the PE format does not store a section
  	 address offset for a PC relative symbol.  */
!       if (S_GET_SEGMENT (fixP->fx_addsy) != seg
! #if defined(BFD_ASSEMBLER) || defined(S_IS_WEAK)
! 	|| S_IS_WEAK (fixP->fx_addsy)
! #endif
! 	)
! 
  	value += md_pcrel_from (fixP);
  #endif
      }
*************** tc_gen_reloc (section, fixp)
*** 5377,5388 ****
    *rel->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
  
    rel->address = fixp->fx_frag->fr_address + fixp->fx_where;
- 
- #ifdef TE_PE
-   if (S_IS_WEAK (fixp->fx_addsy))
-     rel->addend = rel->address - (*rel->sym_ptr_ptr)->value + 4;
-   else
- #endif
    if (!use_rela_relocations)
      {
        /* HACK: Since i386 ELF uses Rel instead of Rela, encode the
--- 5382,5387 ----
Index: src/gas/doc/as.texinfo
===================================================================
RCS file: /cvs/src/src/gas/doc/as.texinfo,v
retrieving revision 1.110
diff -c -3 -p -r1.110 as.texinfo
*** src/gas/doc/as.texinfo	4 Nov 2004 21:52:55 -0000	1.110
--- src/gas/doc/as.texinfo	5 Nov 2004 08:26:24 -0000
*************** parent name of @code{0} is treated as re
*** 5872,5895 ****
  This directive sets the weak attribute on the comma separated list of symbol
  @code{names}.  If the symbols do not already exist, they will be created.
  
! Weak symbols are supported in COFF as a GNU extension.  This directive
! sets the weak attribute on the comma separated list of symbol
  @code{names}.  If the symbols do not already exist, they will be created.
  
! @smallexample
! @code{.weak @var{name} [ < = | == > @var{alternate}] [, ...]}
! @end smallexample
! 
! On the PE target, weak aliases are supported natively.  Weak aliases
! (usually called "weak externals" in PE) are created when an alternate
! name is specified.  When a weak symbol is linked and the symbol is not
! defined, the weak symbol becomes an alias for the alternate symbol.  If
! one equal sign is used, the linker searches for defined symbols within
! other objects and libraries.  This is the usual mode, historically
! called "lazy externals."  Otherwise, when two equal signs are used,
! the linker searches for defined symbols only within other objects.
! 
! Non-alias weak symbols are supported on PE as a GNU extension.
  
  @node Word
  @section @code{.word @var{expressions}}
--- 5872,5884 ----
  This directive sets the weak attribute on the comma separated list of symbol
  @code{names}.  If the symbols do not already exist, they will be created.
  
! On COFF targets other than PE, weak symbols are a GNU extension.  This 
! directive sets the weak attribute on the comma separated list of symbol
  @code{names}.  If the symbols do not already exist, they will be created.
  
! On the PE target, weak symbols are supported natively as weak aliases.
! When a weak symbol is created that is not an alias, GAS creates an 
! alternate symbol to hold the default value.
  
  @node Word
  @section @code{.word @var{expressions}}
Index: src/include/coff/pe.h
===================================================================
RCS file: /cvs/src/src/include/coff/pe.h,v
retrieving revision 1.11
diff -c -3 -p -r1.11 pe.h
*** src/include/coff/pe.h	17 Jul 2003 14:37:17 -0000	1.11
--- src/include/coff/pe.h	5 Nov 2004 08:26:34 -0000
*************** typedef struct 
*** 310,313 ****
--- 310,318 ----
  #define IMPORT_NAME_NOPREFIX	2
  #define IMPORT_NAME_UNDECORATE	3
  
+ /* Weak external characteristics */
+ #define IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY	1
+ #define IMAGE_WEAK_EXTERN_SEARCH_LIBRARY	2
+ #define IMAGE_WEAK_EXTERN_SEARCH_ALIAS		3
+ 
  #endif /* _PE_H */
Index: src/ld/testsuite/ld-scripts/weak.exp
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-scripts/weak.exp,v
retrieving revision 1.6
diff -c -3 -p -r1.6 weak.exp
*** src/ld/testsuite/ld-scripts/weak.exp	7 May 2002 11:08:56 -0000	1.6
--- src/ld/testsuite/ld-scripts/weak.exp	5 Nov 2004 08:26:38 -0000
*************** set testname "weak symbols"
*** 21,30 ****
  
  # This test only works for ELF targets.  It ought to work for some
  # a.out targets, but it doesn't.
! if ![is_elf_format] {
      return
  }
  
  
  if {! [ld_assemble $as $srcdir/$subdir/weak1.s tmpdir/weak1.o]
      || ! [ld_assemble $as $srcdir/$subdir/weak2.s tmpdir/weak2.o]} then {
--- 21,35 ----
  
  # This test only works for ELF targets.  It ought to work for some
  # a.out targets, but it doesn't.
! if {! [is_elf_format] && ! [is_pecoff_format]} {
!     unsupported $testname
      return
  }
  
+ # Weak symbols are broken for non-i386 PE targets.
+ if {! [istarget i?86-*-*]} {
+     setup_xfail *-*-pe* 517
+ }
  
  if {! [ld_assemble $as $srcdir/$subdir/weak1.s tmpdir/weak1.o]
      || ! [ld_assemble $as $srcdir/$subdir/weak2.s tmpdir/weak2.o]} then {
Index: src/ld/testsuite/ld-undefined/weak-undef.exp
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-undefined/weak-undef.exp,v
retrieving revision 1.3
diff -c -3 -p -r1.3 weak-undef.exp
*** src/ld/testsuite/ld-undefined/weak-undef.exp	30 Jul 2002 07:41:15 -0000	1.3
--- src/ld/testsuite/ld-undefined/weak-undef.exp	5 Nov 2004 08:26:40 -0000
***************
*** 1,5 ****
  # Test handling of weak undefined symbols
! #   Copyright 2001
  #   Free Software Foundation, Inc.
  #
  # This file is free software; you can redistribute it and/or modify
--- 1,5 ----
  # Test handling of weak undefined symbols
! #   Copyright 2001, 2004
  #   Free Software Foundation, Inc.
  #
  # This file is free software; you can redistribute it and/or modify
*************** if { ![istarget *-*-sysv4*] \
*** 29,44 ****
       && ![istarget *-*-linux*] \
       && ![istarget *-*-irix5*] \
       && ![istarget *-*-irix6*] \
!      && ![istarget *-*-solaris2*] } then {
      return
  }
  
! if { [istarget *-*-linux*aout*] \
!      || [istarget *-*-linux*oldld*] } {
!     return
  }
  
! if {! [ld_assemble $as $srcdir/$subdir/weak-undef.s tmpdir/weak-undef.o]} then {
      # It's OK if .weak doesn't work on this target.
      unresolved $testname
      return
--- 29,49 ----
       && ![istarget *-*-linux*] \
       && ![istarget *-*-irix5*] \
       && ![istarget *-*-irix6*] \
!      && ![istarget *-*-solaris2*] \
!      && ![is_pecoff_format]
!      || [istarget *-*-linux*aout] \
!      || [istarget *-*-linux*oldld*]} {
! 
!     unsupported $testname
      return
  }
  
! # Weak symbols are broken for non-i386 PE targets.
! if {! [istarget i?86-*-*]} {
!     setup_xfail *-*-pe* 517
  }
  
! if {! [ld_assemble $as $srcdir/$subdir/weak-undef.s tmpdir/weak-undef.o]} {
      # It's OK if .weak doesn't work on this target.
      unresolved $testname
      return
Index: src/ld/testsuite/lib/ld-lib.exp
===================================================================
RCS file: /cvs/src/src/ld/testsuite/lib/ld-lib.exp,v
retrieving revision 1.27
diff -c -3 -p -r1.27 ld-lib.exp
*** src/ld/testsuite/lib/ld-lib.exp	12 May 2004 03:08:09 -0000	1.27
--- src/ld/testsuite/lib/ld-lib.exp	5 Nov 2004 08:26:42 -0000
*************** proc is_elf64 { binary_file } {
*** 417,422 ****
--- 417,436 ----
  }
  
  #
+ # is_pecoff_format
+ #	true if the object format is known to be PECOFF
+ #
+ proc is_pecoff_format {} {
+     if { ![istarget *-*-mingw32*] \
+ 	 && ![istarget *-*-cygwin*] \
+ 	 && ![istarget *-*-pe*] } {
+ 	return 0
+     }
+ 
+     return 1
+ }
+ 
+ #
  # simple_diff
  #	compares two files line-by-line
  #	returns differences if exist

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