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]

PATCH mingw32 pe Handle weak symbols (updated)


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


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