aboutsummaryrefslogtreecommitdiff
path: root/gas
diff options
context:
space:
mode:
authorChristopher Faylor <me+cygwin@cgf.cx>2004-07-03 16:07:51 +0000
committerChristopher Faylor <me+cygwin@cgf.cx>2004-07-03 16:07:51 +0000
commitc87db184a7dd1e5542b807ae6d29db02b8ea0f5e (patch)
tree7b731760ae09b88e4dcdc976bc50a97c2d8478d5 /gas
parent3b91255ea0fa465d5c79abc774e6c7aec13ca513 (diff)
downloadbinutils-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/ChangeLog6
-rw-r--r--gas/config/obj-coff.c121
-rw-r--r--gas/config/tc-i386.c6
-rw-r--r--gas/doc/as.texinfo27
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}}