PATCH mingw32 pe Handle weak symbols (updated)

Aaron W. LaFramboise aaron98wiridge9@aaronwl.com
Sat Jul 3 09:47:00 GMT 2004


I'm resubmitting this patch for weak symbols under PE.  It has an
important bug fix regarding relocations to weak symbols in the same
section that I missed the first time around.  I have also completed the
copyright assignment procedure so there should be no further barriers on
that front.

2004-07-04  Aaron W. LaFramboise <aaron98wiridge9@aaronwl.com>

	* bfd/cofflink.c (_bfd_coff_generic_relocate_section): Resolve
	PE weak externals properly.
	* src/gas/config/obj-coff.c (obj_coff_weak): New .weak syntax for
	PE weak externals.
	* binutils/doc/binutils.texi (nm): Clarify weak symbol description.
	* gas/config/tc-i386.c (tc_gen_reloc): Use addend for weak
	symbols in TE_PE.
	* gas/doc/as.texinfo (Weak): Document PE weak symbols.
	* ld/ld.texinfo (WIN32): Document PE weak symbols.

Index: bfd/cofflink.c
===================================================================
RCS file: /cvs/src/src/bfd/cofflink.c,v
retrieving revision 1.45
diff -c -3 -p -r1.45 cofflink.c
*** bfd/cofflink.c	28 Jun 2004 13:57:58 -0000	1.45
--- bfd/cofflink.c	3 Jul 2004 09:27:04 -0000
*************** _bfd_coff_generic_relocate_section (bfd
*** 2923,2928 ****
--- 2923,2929 ----
  	  if (h->root.type == bfd_link_hash_defined
  	      || h->root.type == bfd_link_hash_defweak)
  	    {
+ 	      /* Defined weak symbols are a GNU extension. */
  	      asection *sec;

  	      sec = h->root.u.def.section;
*************** _bfd_coff_generic_relocate_section (bfd
*** 2932,2938 ****
  	      }

  	  else if (h->root.type == bfd_link_hash_undefweak)
! 	    val = 0;

  	  else if (! info->relocatable)
  	    {
--- 2933,2963 ----
  	      }

  	  else if (h->root.type == bfd_link_hash_undefweak)
! 	    {
!               if (h->class == C_NT_WEAK && h->numaux == 1)
! 		{
! 		  /* 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.
! 		   * FIXME: All weak externals are treated as having
! 		   * characteristics IMAGE_WEAK_EXTERN_SEARCH_LIBRARY (2).
! 		   * There are no known uses of the other two types of
! 		   * weak externals.
! 		   */
! 		  asection *sec;
! 		  struct coff_link_hash_entry *h2 =
! 		    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. */
! 		val = 0;
! 	    }

  	  else if (! info->relocatable)
  	    {
Index: binutils/doc/binutils.texi
===================================================================
RCS file: /cvs/src/src/binutils/doc/binutils.texi,v
retrieving revision 1.52
diff -c -3 -p -r1.52 binutils.texi
*** binutils/doc/binutils.texi	23 Dec 2003 13:01:11 -0000	1.52
--- binutils/doc/binutils.texi	3 Jul 2004 09:27:31 -0000
*************** The symbol is a weak symbol that has not
*** 748,754 ****
  weak object symbol.  When a weak defined symbol is linked with a normal
  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 weak symbol becomes zero with no error.

  @item -
  The symbol is a stabs symbol in an a.out object file.  In this case, the
--- 748,755 ----
  weak object symbol.  When a weak defined symbol is linked with a normal
  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
Index: gas/config/obj-coff.c
===================================================================
RCS file: /cvs/src/src/gas/config/obj-coff.c,v
retrieving revision 1.70
diff -c -3 -p -r1.70 obj-coff.c
*** gas/config/obj-coff.c	15 Jun 2004 01:16:35 -0000	1.70
--- gas/config/obj-coff.c	3 Jul 2004 09:27:46 -0000
*************** obj_coff_bss (ignore)
*** 212,258 ****
      s_lcomm (0);
  }

- /* Handle .weak.  This is a GNU extension.  */
-
- static void
- obj_coff_weak (ignore)
-      int ignore ATTRIBUTE_UNUSED;
- {
-   char *name;
-   int c;
-   symbolS *symbolP;
-
-   do
-     {
-       name = input_line_pointer;
-       c = get_symbol_end ();
-       symbolP = symbol_find_or_make (name);
-       *input_line_pointer = c;
-       SKIP_WHITESPACE ();
-
- #if defined BFD_ASSEMBLER || defined S_SET_WEAK
-       S_SET_WEAK (symbolP);
- #endif
-
- #ifdef TE_PE
-       S_SET_STORAGE_CLASS (symbolP, C_NT_WEAK);
- #else
-       S_SET_STORAGE_CLASS (symbolP, C_WEAKEXT);
- #endif
-
-       if (c == ',')
- 	{
- 	  input_line_pointer++;
- 	  SKIP_WHITESPACE ();
- 	  if (*input_line_pointer == '\n')
- 	    c = '\n';
- 	}
-     }
-   while (c == ',');
-
-   demand_empty_rest_of_line ();
- }
-
  #ifdef BFD_ASSEMBLER

  static segT fetch_coff_debug_section PARAMS ((void));
--- 212,217 ----
*************** obj_coff_val (ignore)
*** 1135,1140 ****
--- 1094,1178 ----
    demand_empty_rest_of_line ();
  }

+ /* Handle .weak.  This is a GNU extension in formats other than PE. */
+ static void
+ obj_coff_weak (ignore)
+      int ignore ATTRIBUTE_UNUSED;
+ {
+   char *name;
+   int c;
+   symbolS *symbolP;
+
+   do
+     {
+       name = input_line_pointer;
+       c = get_symbol_end ();
+       if (*name == 0)
+ 	{
+ 	  as_warn (_("badly formed .weak directive ignored"));
+ 	  ignore_rest_of_line ();
+ 	  return;
+ 	}
+       symbolP = symbol_find_or_make (name);
+       *input_line_pointer = c;
+       SKIP_WHITESPACE ();
+
+ #if defined BFD_ASSEMBLER || defined S_SET_WEAK
+       S_SET_WEAK (symbolP);
+ #endif
+
+ #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 == ',')
+ 	{
+ 	  input_line_pointer++;
+ 	  SKIP_WHITESPACE ();
+ 	  if (*input_line_pointer == '\n')
+ 	    c = '\n';
+ 	}
+
+     }
+   while (c == ',');
+
+   demand_empty_rest_of_line ();
+ }
+
  void
  coff_obj_read_begin_hook ()
  {
Index: gas/config/tc-i386.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-i386.c,v
retrieving revision 1.152
diff -c -3 -p -r1.152 tc-i386.c
*** gas/config/tc-i386.c	18 Jun 2004 14:09:40 -0000	1.152
--- gas/config/tc-i386.c	3 Jul 2004 09:27:57 -0000
*************** tc_gen_reloc (section, fixp)
*** 5280,5285 ****
--- 5280,5291 ----
    *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
Index: gas/doc/as.texinfo
===================================================================
RCS file: /cvs/src/src/gas/doc/as.texinfo,v
retrieving revision 1.100
diff -c -3 -p -r1.100 as.texinfo
*** gas/doc/as.texinfo	11 May 2004 15:53:47 -0000	1.100
--- gas/doc/as.texinfo	3 Jul 2004 09:28:12 -0000
*************** respectively, with @code{.val} and @code
*** 3400,3407 ****

  @cindex auxiliary attributes, COFF symbols
  The @command{@value{AS}} directives @code{.dim}, @code{.line},
@code{.scl},
! @code{.size}, and @code{.tag} can generate auxiliary symbol table
! information for COFF.
  @end ifset

  @ifset SOM
--- 3400,3407 ----

  @cindex auxiliary attributes, COFF symbols
  The @command{@value{AS}} directives @code{.dim}, @code{.line},
@code{.scl},
! @code{.size}, @code{.tag}, and @code{.weak} can generate auxiliary symbol
! table information for COFF.
  @end ifset

  @ifset SOM
*************** Some machine configurations provide addi
*** 3823,3831 ****
  * Version::                     @code{.version "@var{string}"}
  * VTableEntry::                 @code{.vtable_entry @var{table},
@var{offset}}
  * VTableInherit::               @code{.vtable_inherit @var{child},
@var{parent}}
- * Weak::                        @code{.weak @var{names}}
  @end ifset

  * Word::                        @code{.word @var{expressions}}
  * Deprecated::                  Deprecated Directives
  @end menu
--- 3823,3831 ----
  * Version::                     @code{.version "@var{string}"}
  * VTableEntry::                 @code{.vtable_entry @var{table},
@var{offset}}
  * VTableInherit::               @code{.vtable_inherit @var{child},
@var{parent}}
  @end ifset

+ * Weak::                        @code{.weak @var{names}}
  * Word::                        @code{.word @var{expressions}}
  * Deprecated::                  Deprecated Directives
  @end menu
*************** parent whose addend is the value of the
*** 5808,5821 ****
  parent name of @code{0} is treated as refering the @code{*ABS*} section.
  @end ifset

- @ifset ELF
  @node Weak
  @section @code{.weak @var{names}}

  @cindex @code{weak} directive
  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.
! @end ifset

  @node Word
  @section @code{.word @var{expressions}}
--- 5808,5838 ----
  parent name of @code{0} is treated as refering the @code{*ABS*} section.
  @end ifset

  @node Weak
  @section @code{.weak @var{names}}

  @cindex @code{weak} directive
  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}}
Index: ld/ld.texinfo
===================================================================
RCS file: /cvs/src/src/ld/ld.texinfo,v
retrieving revision 1.117
diff -c -3 -p -r1.117 ld.texinfo
*** ld/ld.texinfo	23 May 2004 09:30:31 -0000	1.117
--- ld/ld.texinfo	3 Jul 2004 09:28:53 -0000
*************** to handle the other symbols, then the bo
*** 5292,5297 ****
--- 5292,5315 ----
  the original names for the renamed symbols will be exported.
  In effect, you'd be aliasing those symbols, not renaming them,
  which is probably not what you wanted.
+
+ @cindex weak externals
+ @item weak externals
+ The Windows object format, PE, specifies a form of weak symbols called
+ weak externals.  When a weak symbol is linked and the symbol is not
+ defined, the weak symbol becomes an alias for some other symbol.  There
+ are three variants of weak externals:
+ @itemize
+ @item Definition is searched for in objects and libraries, historically
+ called lazy externals.
+ @item Definition is searched for only in other objects, not in
libraries.
+ This form is not presently implemented.
+ @item No search; the symbol is an alias.  This form is not presently
+ implemented.
+ @end itemize
+ As a GNU extension, weak symbols that do not specify an alternate symbol
+ are supported.  If the symbol is undefined when linking, the symbol
+ uses a default value.
  @end table

  @ifclear GENERIC



More information about the Binutils mailing list