From 0dd43f75a03f2e93f40f428f3f18a36b71db2dd0 Mon Sep 17 00:00:00 2001 From: cgf Date: Sat, 3 Jul 2004 16:07:45 +0000 Subject: [PATCH] 2004-07-04 Aaron W. LaFramboise * 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. --- bfd/ChangeLog | 5 ++ bfd/cofflink.c | 29 ++++++++++- binutils/ChangeLog | 4 ++ binutils/doc/binutils.texi | 3 +- gas/ChangeLog | 6 +++ gas/config/obj-coff.c | 121 ++++++++++++++++++++++++++++++--------------- gas/config/tc-i386.c | 6 +++ gas/doc/as.texinfo | 27 ++++++++-- ld/ChangeLog | 4 ++ ld/ld.texinfo | 18 +++++++ 10 files changed, 174 insertions(+), 49 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index e8e452f976..198494653e 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,8 @@ +2004-07-03 Aaron W. LaFramboise + + * cofflink.c (_bfd_coff_generic_relocate_section): Resolve PE weak + externals properly. + 2004-07-02 Martin Schwidefsky * config.bfd: Add want64 to configuration target s390-*-linux*. diff --git a/bfd/cofflink.c b/bfd/cofflink.c index 1af86abaec..af6dd3d699 100644 --- a/bfd/cofflink.c +++ b/bfd/cofflink.c @@ -2923,16 +2923,41 @@ _bfd_coff_generic_relocate_section (bfd *output_bfd, 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; val = (h->root.u.def.value + sec->output_section->vma + sec->output_offset); - } + } else if (h->root.type == bfd_link_hash_undefweak) - val = 0; + { + 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) { diff --git a/binutils/ChangeLog b/binutils/ChangeLog index 6cb1f691a4..8ea599b12c 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,7 @@ +2004-07-03 Aaron W. LaFramboise + + * doc/binutils.texi (nm): Clarify weak symbol description. + 2004-06-24 Ben Elliston * readelf.c (get_segment_type): Display "GNU_STACK", not just diff --git a/binutils/doc/binutils.texi b/binutils/doc/binutils.texi index 2e78720298..c27c627094 100644 --- a/binutils/doc/binutils.texi +++ b/binutils/doc/binutils.texi @@ -748,7 +748,8 @@ The symbol is a weak symbol that has not been specifically tagged as a 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. +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 diff --git a/gas/ChangeLog b/gas/ChangeLog index 50a3ac42de..f02d2a816d 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,9 @@ +2004-07-03 Aaron W. LaFramboise + + * config/obj-coff.c (obj_coff_weak): New .weak syntax for PE weak + externals. + * doc/as.texinfo (Weak): Document PE weak symbols. + 2004-07-03 Richard Sandiford * config/tc-mips.c (HAVE_IN_PLACE_ADDENDS): New macro. diff --git a/gas/config/obj-coff.c b/gas/config/obj-coff.c index 8ead485253..0239b76f88 100644 --- a/gas/config/obj-coff.c +++ b/gas/config/obj-coff.c @@ -212,47 +212,6 @@ obj_coff_bss (ignore) 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)); @@ -1135,6 +1094,86 @@ obj_coff_val (ignore) 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 () { diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c index 823435f110..cc95843662 100644 --- a/gas/config/tc-i386.c +++ b/gas/config/tc-i386.c @@ -5280,6 +5280,12 @@ tc_gen_reloc (section, fixp) *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 diff --git a/gas/doc/as.texinfo b/gas/doc/as.texinfo index 056fa6db35..29605b3f1e 100644 --- a/gas/doc/as.texinfo +++ b/gas/doc/as.texinfo @@ -3400,8 +3400,8 @@ respectively, with @code{.val} and @code{.type}. @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. +@code{.size}, @code{.tag}, and @code{.weak} can generate auxiliary symbol +table information for COFF. @end ifset @ifset SOM @@ -3823,9 +3823,9 @@ Some machine configurations provide additional directives. * 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 +* Weak:: @code{.weak @var{names}} * Word:: @code{.word @var{expressions}} * Deprecated:: Deprecated Directives @end menu @@ -5808,14 +5808,31 @@ parent whose addend is the value of the child symbol. As a special case the 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 + +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}} diff --git a/ld/ChangeLog b/ld/ChangeLog index 8aad6330be..c957555ab9 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,7 @@ +2004-07-03 Aaron W. LaFramboise + + * ld.texinfo (WIN32): Document PE weak symbols. + 2004-07-02 Kaz Kojima * emulparams/shlelf32_linux.sh (COMMONPAGESIZE): Set to 4KB. diff --git a/ld/ld.texinfo b/ld/ld.texinfo index c6002da1f9..2b77260b60 100644 --- a/ld/ld.texinfo +++ b/ld/ld.texinfo @@ -5292,6 +5292,24 @@ to handle the other symbols, then the both the new names @emph{and} 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 -- 2.11.0