public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* [PING] Windows PECOFF weak symbol fixes for *-mingw32 and *-cygwin
@ 2004-11-03  4:35 Aaron W. LaFramboise
  2004-11-03 15:52 ` Nick Clifton
  0 siblings, 1 reply; 6+ messages in thread
From: Aaron W. LaFramboise @ 2004-11-03  4:35 UTC (permalink / raw)
  To: binutils

Can someone please look at
<http://sources.redhat.com/ml/binutils/2004-10/msg00305.html>?  It
reworks my initial weak symbol implementation and fixes a few problems I
found with it.  I'm quite happy about this revised implementation.

Note that it was never reviewed, depite the replies to the thread, which
were actually intended for another thread.

This patch is fairly important for the Windows targets, so I'd
appreciate anyone who could take a look at this.

Aaron W. LaFramboise

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PING] Windows PECOFF weak symbol fixes for *-mingw32 and *-cygwin
  2004-11-03  4:35 [PING] Windows PECOFF weak symbol fixes for *-mingw32 and *-cygwin Aaron W. LaFramboise
@ 2004-11-03 15:52 ` Nick Clifton
  2004-11-05  2:04   ` Aaron W. LaFramboise
  2004-11-05 11:32   ` Aaron W. LaFramboise
  0 siblings, 2 replies; 6+ messages in thread
From: Nick Clifton @ 2004-11-03 15:52 UTC (permalink / raw)
  To: Aaron W. LaFramboise; +Cc: binutils

Hi Aaron,

> Can someone please look at
> <http://sources.redhat.com/ml/binutils/2004-10/msg00305.html>?  It
> reworks my initial weak symbol implementation and fixes a few problems I
> found with it.  I'm quite happy about this revised implementation.

Sorry - it was my fault that I forgot to review this patch.

I am afraid that there are several problems with it however:

   * 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.

   * 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.

   * 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.

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

   * 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.

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

Otherwise the patch seems reasonable.  So if you would care to fix the 
above problems and resubmit it, I will try my best not to forget it this 
time.

Cheers
   Nick


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PING] Windows PECOFF weak symbol fixes for *-mingw32 and *-cygwin
  2004-11-03 15:52 ` Nick Clifton
@ 2004-11-05  2:04   ` Aaron W. LaFramboise
  2004-11-05 10:04     ` Nick Clifton
  2004-11-05 11:32   ` Aaron W. LaFramboise
  1 sibling, 1 reply; 6+ messages in thread
From: Aaron W. LaFramboise @ 2004-11-05  2:04 UTC (permalink / raw)
  To: Nick Clifton; +Cc: binutils

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 

Are there simulators for these targets?  When running make check for
each of these targets, there are UNTESTED testcases, presumably because
they need a simulator:

WARNING: Assuming target board is the local machine (which is probably
wrong).
You may need to set your DEJAGNU environment variable.

binutils:
UNTESTED: strip
UNTESTED: strip with saving a symbol
UNTESTED: simple objcopy of executable
UNTESTED: run objcopy of executable
UNTESTED: run stripped executable
UNTESTED: run stripped executable with saving a symbol
ld:
UNTESTED: NOCROSSREFS 1
UNTESTED: NOCROSSREFS 2
UNTESTED: S-records
UNTESTED: S-records with constructors
UNTESTED: undefined
UNTESTED: undefined function
UNTESTED: undefined line

I don't know anything about cross-testing with dejagnu, though, so maybe
I'm doing something wrong.

Aaron W. LaFramboise

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PING] Windows PECOFF weak symbol fixes for *-mingw32 and *-cygwin
  2004-11-05  2:04   ` Aaron W. LaFramboise
@ 2004-11-05 10:04     ` Nick Clifton
  0 siblings, 0 replies; 6+ messages in thread
From: Nick Clifton @ 2004-11-05 10:04 UTC (permalink / raw)
  To: Aaron W. LaFramboise; +Cc: binutils

Hi Aaron,

>>   * 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 
> 
> 
> Are there simulators for these targets?  

Yes and no ....

> When running make check for
> each of these targets, there are UNTESTED testcases, presumably because
> they need a simulator:

And a compiler as well.  If you are just building binutils and not GCC 
then these tests will be marked as UNTESTED.  In fact this is probably 
the cause of these messages since very few linker tests actually attempt 
to execute any code.

The simulators in the sim/ directory are not sophisticated enough to 
emulate a full PE execution environment, and in particular they cannot 
handle the loading of DLLs.  But they are sufficient to run simple test 
programs, such as might be generated by the binutils testsuite.

Cheers
   Nick

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PING] Windows PECOFF weak symbol fixes for *-mingw32 and *-cygwin
  2004-11-03 15:52 ` Nick Clifton
  2004-11-05  2:04   ` Aaron W. LaFramboise
@ 2004-11-05 11:32   ` Aaron W. LaFramboise
  2004-11-08  8:14     ` Nick Clifton
  1 sibling, 1 reply; 6+ messages in thread
From: Aaron W. LaFramboise @ 2004-11-05 11:32 UTC (permalink / raw)
  To: Nick Clifton; +Cc: binutils

[-- Attachment #1: Type: text/plain, Size: 3540 bytes --]

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


[-- Attachment #2: binutils-head-20041105-weak.patch --]
[-- Type: text/plain, Size: 26119 bytes --]

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 */
  \f
  /* 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

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PING] Windows PECOFF weak symbol fixes for *-mingw32 and *-cygwin
  2004-11-05 11:32   ` Aaron W. LaFramboise
@ 2004-11-08  8:14     ` Nick Clifton
  0 siblings, 0 replies; 6+ messages in thread
From: Nick Clifton @ 2004-11-08  8:14 UTC (permalink / raw)
  To: Aaron W. LaFramboise; +Cc: binutils

Hi Aaron,

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

Thanks very much.

 > 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.

Approved and applied.

Cheers
   Nick

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2004-11-08  8:14 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-11-03  4:35 [PING] Windows PECOFF weak symbol fixes for *-mingw32 and *-cygwin Aaron W. LaFramboise
2004-11-03 15:52 ` Nick Clifton
2004-11-05  2:04   ` Aaron W. LaFramboise
2004-11-05 10:04     ` Nick Clifton
2004-11-05 11:32   ` Aaron W. LaFramboise
2004-11-08  8:14     ` Nick Clifton

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).