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