diff options
author | Christopher Faylor <me+cygwin@cgf.cx> | 2004-07-03 16:07:51 +0000 |
---|---|---|
committer | Christopher Faylor <me+cygwin@cgf.cx> | 2004-07-03 16:07:51 +0000 |
commit | c87db184a7dd1e5542b807ae6d29db02b8ea0f5e (patch) | |
tree | 7b731760ae09b88e4dcdc976bc50a97c2d8478d5 /gas | |
parent | 3b91255ea0fa465d5c79abc774e6c7aec13ca513 (diff) | |
download | binutils-c87db184a7dd1e5542b807ae6d29db02b8ea0f5e.zip binutils-c87db184a7dd1e5542b807ae6d29db02b8ea0f5e.tar.gz binutils-c87db184a7dd1e5542b807ae6d29db02b8ea0f5e.tar.bz2 |
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.
Diffstat (limited to 'gas')
-rw-r--r-- | gas/ChangeLog | 6 | ||||
-rw-r--r-- | gas/config/obj-coff.c | 121 | ||||
-rw-r--r-- | gas/config/tc-i386.c | 6 | ||||
-rw-r--r-- | gas/doc/as.texinfo | 27 |
4 files changed, 114 insertions, 46 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog index 50a3ac4..f02d2a8 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,9 @@ +2004-07-03 Aaron W. LaFramboise <aaron98wiridge9@aaronwl.com> + + * 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 <rsandifo@redhat.com> * 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 8ead485..0239b76 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 823435f..cc95843 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 056fa6d..29605b3 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}} |