From 977cdf5aa7f4f2183060c150041405abbc2410a9 Mon Sep 17 00:00:00 2001 From: Nick Clifton Date: Mon, 8 Nov 2004 08:12:53 +0000 Subject: [PATCH] Fix support for PECOFF weak symbols --- bfd/ChangeLog | 8 + bfd/coff-i386.c | 26 +-- binutils/ChangeLog | 4 + binutils/doc/binutils.texi | 4 +- gas/ChangeLog | 24 +++ gas/config/obj-coff.c | 196 +++++++++++++++++------ gas/config/obj-coff.h | 11 +- gas/config/tc-i386.c | 15 +- gas/doc/as.texinfo | 21 +-- gas/symbols.c | 21 ++- gas/symbols.h | 4 +- gas/tc.h | 8 +- include/coff/ChangeLog | 6 + include/coff/pe.h | 7 +- ld/ChangeLog | 8 + ld/testsuite/ld-scripts/weak.exp | 13 +- ld/testsuite/ld-undefined/weak-undef.exp | 10 +- ld/testsuite/lib/ld-lib.exp | 16 +- 18 files changed, 305 insertions(+), 97 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 849761eda71..dbd2d536d26 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,11 @@ +2004-11-08 Aaron W. LaFramboise + + * coff-i386.c (coff_i386_reloc): Fix weak symbols. + * cofflink.c (_bfd_coff_link_input_bfd): Don't process + C_NT_WEAK aux entries. + (_bfd_coff_generic_relocate_section): Handle undefined + aliases. + 2004-11-07 Andreas Schwab * elf32-m68k.c (elf_m68k_adjust_dynamic_symbol): Use diff --git a/bfd/coff-i386.c b/bfd/coff-i386.c index 65700b6038b..bdd40831519 100644 --- a/bfd/coff-i386.c +++ b/bfd/coff-i386.c @@ -4,21 +4,21 @@ Free Software Foundation, Inc. Written by Cygnus Support. -This file is part of BFD, the Binary File Descriptor library. + This file is part of BFD, the Binary File Descriptor library. -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "bfd.h" #include "sysdep.h" @@ -119,6 +119,8 @@ coff_i386_reloc (abfd, reloc_entry, symbol, data, input_section, output_bfd, here. */ if (howto->pc_relative && howto->pcrel_offset) diff = -(1 << howto->size); + else if (symbol->flags & BSF_WEAK) + diff = reloc_entry->addend - symbol->value; else diff = -reloc_entry->addend; } diff --git a/binutils/ChangeLog b/binutils/ChangeLog index 74bca2b63aa..96ba1e042f2 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,7 @@ +2004-11-08 Aaron W. LaFramboise + + * doc/binutils.texi (nm): Update description of weak symbols. + 2004-11-03 Nick Clifton * readelf.c (do_debug_ranges): New variable. diff --git a/binutils/doc/binutils.texi b/binutils/doc/binutils.texi index 683dd6126f8..f56c8e76f07 100644 --- a/binutils/doc/binutils.texi +++ b/binutils/doc/binutils.texi @@ -749,7 +749,9 @@ 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. +error. On some systems, 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 184a5799ca5..d5efcc7dcb1 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,27 @@ +2004-11-08 Aaron W. LaFramboise + + * symbols.c (any_external_name): Define. + (resolve_symbol_value): Do not convert weak symbols. + (S_SET_EXTERNAL): Support any_external_name. + (S_SET_NAME): Qualify parameter const. + (symbol_equated_reloc_p): Don't equate weaks when relocating. + * symbols.h (S_SET_NAME): Qualfiy parameter const. + * tc.h (any_external_name): Declare. + * config/obj-coff.c ("coff/pe.h"): Include for BFD + assemblers also. + (weak_is_altname): Declare and define. + (weak_name2altname): Same. + (weak_altname2name): Same. + (weak_uniquify): Same. + (weak_altprefix): Define. + (obj_coff_weak): Change .weak syntax and handling. + (coff_frob_symbol): Fix PE weak symbol alternates. + * config/obj-coff.h (USE_UNIQUE): Define. + * config/tc-i386.c (md_apply_fix3): Assume weak symbols + are in another segment. + (tc_gen_reloc): Remove broken addend hack. + doc/as.texinfo: Update. + 2004-11-05 Sterling Augustine * config/tc-xtensa.c (total_frag_text_expansion): New. diff --git a/gas/config/obj-coff.c b/gas/config/obj-coff.c index 1451d9da08b..96aac42b060 100644 --- a/gas/config/obj-coff.c +++ b/gas/config/obj-coff.c @@ -26,6 +26,10 @@ #include "obstack.h" #include "subsegs.h" +#ifdef TE_PE +#include "coff/pe.h" +#endif + /* I think this is probably always correct. */ #ifndef KEEP_RELOC_INFO #define KEEP_RELOC_INFO @@ -41,6 +45,10 @@ /* This is used to hold the symbol built by a sequence of pseudo-ops from .def and .endef. */ static symbolS *def_symbol_in_progress; +#ifdef TE_PE +/* PE weak alternate symbols begin with this string. */ +static const char weak_altprefix[] = ".weak."; +#endif /* TE_PE */ typedef struct { @@ -1096,14 +1104,84 @@ obj_coff_val (ignore) demand_empty_rest_of_line (); } +#ifdef TE_PE + +/* Return nonzero if name begins with weak alternate symbol prefix. */ + +static int +weak_is_altname (const char * name) +{ + return ! strncmp (name, weak_altprefix, sizeof (weak_altprefix) - 1); +} + +/* Return the name of the alternate symbol + name corresponding to a weak symbol's name. */ + +static const char * +weak_name2altname (const char * name) +{ + char *alt_name; + + alt_name = xmalloc (sizeof (weak_altprefix) + strlen (name)); + strcpy (alt_name, weak_altprefix); + return strcat (alt_name, name); +} + +/* Return the name of the weak symbol corresponding to an + alterate symbol. */ + +static const char * +weak_altname2name (const char * name) +{ + char * weak_name; + char * dot; + + assert (weak_is_altname (name)); + + weak_name = xstrdup (name + 6); + if ((dot = strchr (weak_name, '.'))) + *dot = 0; + return weak_name; +} + +/* Make a weak symbol name unique by + appending the name of an external symbol. */ + +static const char * +weak_uniquify (const char * name) +{ + char *ret; + const char * unique = ""; + +#ifdef USE_UNIQUE + if (an_external_name != NULL) + unique = an_external_name; +#endif + assert (weak_is_altname (name)); + + if (strchr (name + sizeof (weak_altprefix), '.')) + return name; + + ret = xmalloc (strlen (name) + strlen (unique) + 2); + strcpy (ret, name); + strcat (ret, "."); + strcat (ret, unique); + return ret; +} + +#endif /* TE_PE */ + /* Handle .weak. This is a GNU extension in formats other than PE. */ + static void -obj_coff_weak (ignore) - int ignore ATTRIBUTE_UNUSED; +obj_coff_weak (int ignore ATTRIBUTE_UNUSED) { char *name; int c; symbolS *symbolP; +#ifdef TE_PE + symbolS *alternateP; +#endif do { @@ -1115,6 +1193,7 @@ obj_coff_weak (ignore) ignore_rest_of_line (); return; } + c = 0; symbolP = symbol_find_or_make (name); *input_line_pointer = c; SKIP_WHITESPACE (); @@ -1125,42 +1204,20 @@ obj_coff_weak (ignore) #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. - */ + File Format Specification_, section 5.5.3. + Create a symbol representing the alternate value. + coff_frob_symbol will set the value of this symbol from + the value of the weak symbol itself. */ S_SET_STORAGE_CLASS (symbolP, C_NT_WEAK); + S_SET_NUMBER_AUXILIARY (symbolP, 1); + SA_SET_SYM_FSIZE (symbolP, IMAGE_WEAK_EXTERN_SEARCH_LIBRARY); - 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; + alternateP = symbol_find_or_make (weak_name2altname (name)); + S_SET_EXTERNAL (alternateP); + S_SET_STORAGE_CLASS (alternateP, C_NT_WEAK); - 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 */ + SA_SET_SYM_TAGNDX (symbolP, alternateP); +#endif if (c == ',') { @@ -1214,14 +1271,67 @@ coff_frob_symbol (symp, punt) if (!block_stack) block_stack = stack_init (512, sizeof (symbolS*)); - if (S_IS_WEAK (symp)) - { #ifdef TE_PE - S_SET_STORAGE_CLASS (symp, C_NT_WEAK); -#else - S_SET_STORAGE_CLASS (symp, C_WEAKEXT); -#endif + if (S_GET_STORAGE_CLASS (symp) == C_NT_WEAK + && ! S_IS_WEAK (symp) + && weak_is_altname (S_GET_NAME (symp))) + { + /* This is a weak alternate symbol. All processing of + PECOFFweak symbols is done here, through the alternate. */ + symbolS *weakp = symbol_find (weak_altname2name (S_GET_NAME (symp))); + + assert (weakp); + assert (S_GET_NUMBER_AUXILIARY (weakp) == 1); + + if (symbol_equated_p (weakp)) + { + /* The weak symbol has an alternate specified; symp is unneeded. */ + S_SET_STORAGE_CLASS (weakp, C_NT_WEAK); + SA_SET_SYM_TAGNDX (weakp, + symbol_get_value_expression (weakp)->X_add_symbol); + + S_CLEAR_EXTERNAL (symp); + *punt = 1; + return; + } + else + { + /* The weak symbol has been assigned an alternate value. + Copy this value to symp, and set symp as weakp's alternate. */ + if (S_GET_STORAGE_CLASS (weakp) != C_NT_WEAK) + { + S_SET_STORAGE_CLASS (symp, S_GET_STORAGE_CLASS (weakp)); + S_SET_STORAGE_CLASS (weakp, C_NT_WEAK); + } + + if (S_IS_DEFINED (weakp)) + { + /* This is a defined weak symbol. Copy value information + from the weak symbol itself to the alternate symbol. */ + symbol_set_value_expression (symp, + symbol_get_value_expression (weakp)); + symbol_set_frag (symp, symbol_get_frag (weakp)); + S_SET_SEGMENT (symp, S_GET_SEGMENT (weakp)); + } + else + { + /* This is an undefined weak symbol. + Define the alternate symbol to zero. */ + S_SET_VALUE (symp, 0); + S_SET_SEGMENT (symp, absolute_section); + } + + S_SET_NAME (symp, weak_uniquify (S_GET_NAME (symp))); + S_SET_STORAGE_CLASS (symp, C_EXT); + + S_SET_VALUE (weakp, 0); + S_SET_SEGMENT (weakp, undefined_section); + } } +#else /* TE_PE */ + if (S_IS_WEAK (symp)) + S_SET_STORAGE_CLASS (symp, C_WEAKEXT); +#endif /* TE_PE */ if (!S_IS_DEFINED (symp) && !S_IS_WEAK (symp) @@ -1722,10 +1832,6 @@ symbol_dump () #include "libbfd.h" #include "libcoff.h" -#ifdef TE_PE -#include "coff/pe.h" -#endif - /* The NOP_OPCODE is for the alignment fill value. Fill with nop so that we can stick sections together without causing trouble. */ #ifndef NOP_OPCODE diff --git a/gas/config/obj-coff.h b/gas/config/obj-coff.h index 520055268c2..90d7e99946a 100644 --- a/gas/config/obj-coff.h +++ b/gas/config/obj-coff.h @@ -1,6 +1,6 @@ /* coff object file format Copyright 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2002, 2003 + 1999, 2000, 2002, 2003, 2004 Free Software Foundation, Inc. This file is part of GAS. @@ -180,14 +180,19 @@ #endif #endif +#ifdef TE_PE +/* PE weak symbols need USE_UNIQUE. */ +#define USE_UNIQUE 1 +#endif + /* Targets may also set this. Also, if BFD_ASSEMBLER is defined, this will already have been defined. */ -#undef SYMBOLS_NEED_BACKPOINTERS +#undef SYMBOLS_NEED_BACKPOINTERS #define SYMBOLS_NEED_BACKPOINTERS 1 #ifndef OBJ_COFF_MAX_AUXENTRIES #define OBJ_COFF_MAX_AUXENTRIES 1 -#endif /* OBJ_COFF_MAX_AUXENTRIES */ +#endif extern void coff_obj_symbol_new_hook PARAMS ((symbolS *)); #define obj_symbol_new_hook coff_obj_symbol_new_hook diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c index 606d16b5213..aa2ec54e047 100644 --- a/gas/config/tc-i386.c +++ b/gas/config/tc-i386.c @@ -4801,9 +4801,13 @@ md_apply_fix3 (fixP, valP, seg) } #endif #if defined (OBJ_COFF) && defined (TE_PE) - /* For some reason, the PE format does not store a section - address offset for a PC relative symbol. */ - if (S_GET_SEGMENT (fixP->fx_addsy) != seg) + /* For some reason, the PE format does not store a + section address offset for a PC relative symbol. */ + if (S_GET_SEGMENT (fixP->fx_addsy) != seg +#if defined(BFD_ASSEMBLER) || defined(S_IS_WEAK) + || S_IS_WEAK (fixP->fx_addsy) +#endif + ) value += md_pcrel_from (fixP); #endif } @@ -5378,11 +5382,6 @@ tc_gen_reloc (section, fixp) 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 a73edd77fdd..3d4a5ab4adf 100644 --- a/gas/doc/as.texinfo +++ b/gas/doc/as.texinfo @@ -5872,24 +5872,13 @@ parent name of @code{0} is treated as refering the @code{*ABS*} section. 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 +On COFF targets other than PE, weak symbols are 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. +On the PE target, weak symbols are supported natively as weak aliases. +When a weak symbol is created that is not an alias, GAS creates an +alternate symbol to hold the default value. @node Word @section @code{.word @var{expressions}} diff --git a/gas/symbols.c b/gas/symbols.c index 045241600b8..135c7ef04b9 100644 --- a/gas/symbols.c +++ b/gas/symbols.c @@ -59,6 +59,11 @@ symbolS abs_symbol; #define LOCAL_LABEL_CHAR '\002' struct obstack notes; +#ifdef USE_UNIQUE +/* The name of an external symbol which is + used to make weak PE symbol names unique. */ +const char * an_external_name; +#endif static char *save_symbol_name (const char *); static void fb_label_init (void); @@ -989,7 +994,11 @@ resolve_symbol_value (symbolS *symp) relocation to detect this case, and convert the relocation to be against the symbol to which this symbol is equated. */ - if (! S_IS_DEFINED (add_symbol) || S_IS_COMMON (add_symbol)) + if (! S_IS_DEFINED (add_symbol) +#if defined(BFD_ASSEMBLER) || defined(S_IS_WEAK) + || S_IS_WEAK (add_symbol) +#endif + || S_IS_COMMON (add_symbol)) { if (finalize_syms) { @@ -1905,6 +1914,11 @@ S_SET_EXTERNAL (symbolS *s) } s->bsym->flags |= BSF_GLOBAL; s->bsym->flags &= ~(BSF_LOCAL | BSF_WEAK); + +#ifdef USE_UNIQUE + if (! an_external_name && S_GET_NAME(s)[0] != '.') + an_external_name = S_GET_NAME (s); +#endif } void @@ -1949,7 +1963,7 @@ S_SET_THREAD_LOCAL (symbolS *s) } void -S_SET_NAME (symbolS *s, char *name) +S_SET_NAME (symbolS *s, const char *name) { if (LOCAL_SYMBOL_CHECK (s)) { @@ -2225,6 +2239,9 @@ symbol_equated_reloc_p (symbolS *s) resolve_symbol_value to flag expression syms that have been equated. */ return (s->sy_value.X_op == O_symbol +#if defined(BFD_ASSEMBLER) || defined(S_IS_WEAK) + && ! S_IS_WEAK (s) +#endif && ((s->sy_resolved && s->sy_value.X_op_symbol != NULL) || ! S_IS_DEFINED (s) || S_IS_COMMON (s))); diff --git a/gas/symbols.h b/gas/symbols.h index 15dc2639bf8..b95ec248a25 100644 --- a/gas/symbols.h +++ b/gas/symbols.h @@ -1,6 +1,6 @@ /* symbols.h - Copyright 1987, 1990, 1992, 1993, 1994, 1995, 1997, 1999, 2000, 2001, - 2002, 2003 Free Software Foundation, Inc. + 2002, 2003, 2004 Free Software Foundation, Inc. This file is part of GAS, the GNU Assembler. @@ -105,7 +105,7 @@ extern const char *S_GET_NAME (symbolS *); extern segT S_GET_SEGMENT (symbolS *); extern void S_SET_SEGMENT (symbolS *, segT); extern void S_SET_EXTERNAL (symbolS *); -extern void S_SET_NAME (symbolS *, char *); +extern void S_SET_NAME (symbolS *, const char *); extern void S_CLEAR_EXTERNAL (symbolS *); extern void S_SET_WEAK (symbolS *); extern void S_SET_THREAD_LOCAL (symbolS *); diff --git a/gas/tc.h b/gas/tc.h index 2f77c5f583d..6a0662633dd 100644 --- a/gas/tc.h +++ b/gas/tc.h @@ -1,6 +1,6 @@ /* tc.h - target cpu dependent - Copyright 1987, 1990, 1991, 1992, 1993, 1994, 1995, 2000, 2001, 2003 + Copyright 1987, 1990, 1991, 1992, 1993, 1994, 1995, 2000, 2001, 2003, 2004 Free Software Foundation, Inc. This file is part of GAS, the GNU Assembler. @@ -59,6 +59,12 @@ extern int md_short_jump_size; extern int md_long_jump_size; #endif +#ifdef USE_UNIQUE +/* The name of an external symbol which is + used to make weak PE symbol names unique. */ +extern const char * an_external_name; +#endif + #ifndef md_create_long_jump void md_create_long_jump (char *, addressT, addressT, fragS *, symbolS *); #endif diff --git a/include/coff/ChangeLog b/include/coff/ChangeLog index 290a5070ab4..d107734e924 100644 --- a/include/coff/ChangeLog +++ b/include/coff/ChangeLog @@ -1,3 +1,9 @@ +2004-11-08 Aaron W. LaFramboise + + * pe.h (IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY): Define. + (IMAGE_WEAK_EXTERN_SEARCH_LIBRARY): Same. + (IMAGE_WEAK_EXTERN_SEARCH_ALIAS): Same. + 2004-08-13 Mark Kettenis * symconst.h (langMax): Fix typo in comment. diff --git a/include/coff/pe.h b/include/coff/pe.h index 363d307379b..46128dd82c6 100644 --- a/include/coff/pe.h +++ b/include/coff/pe.h @@ -1,6 +1,6 @@ /* pe.h - PE COFF header information - Copyright 2000, 2001, 2003 Free Software Foundation, Inc. + Copyright 2000, 2001, 2003, 2004 Free Software Foundation, Inc. This file is part of BFD, the Binary File Descriptor library. @@ -310,4 +310,9 @@ typedef struct #define IMPORT_NAME_NOPREFIX 2 #define IMPORT_NAME_UNDECORATE 3 +/* Weak external characteristics. */ +#define IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY 1 +#define IMAGE_WEAK_EXTERN_SEARCH_LIBRARY 2 +#define IMAGE_WEAK_EXTERN_SEARCH_ALIAS 3 + #endif /* _PE_H */ diff --git a/ld/ChangeLog b/ld/ChangeLog index b15f0670f71..99d27eefba3 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,11 @@ +2004-11-08 Aaron W. LaFramboise + + * testsuite/ld-scripts/weak.exp: Enable test on PE, + XFAIL non-i386 PE. + * testsuite/ld-undefined/weak-undef.exp: Enable test on PE, + XFAIL non-i386 PE. + * testsuite/lib/ld-lib.exp (is_pecoff_format): New. + 2004-11-04 Daniel Jacobowitz * Makefile.am (ALL_EMULATIONS): Remove earmelf_oabi.o. diff --git a/ld/testsuite/ld-scripts/weak.exp b/ld/testsuite/ld-scripts/weak.exp index 3167ea45fed..8a8072f6fd5 100644 --- a/ld/testsuite/ld-scripts/weak.exp +++ b/ld/testsuite/ld-scripts/weak.exp @@ -1,6 +1,6 @@ # Test weak symbols. # By Ian Lance Taylor, Cygnus Solutions. -# Copyright 2001 +# Copyright 2001, 2004 # Free Software Foundation, Inc. # # This file is free software; you can redistribute it and/or modify @@ -19,12 +19,17 @@ set testname "weak symbols" -# This test only works for ELF targets. It ought to work for some -# a.out targets, but it doesn't. -if ![is_elf_format] { +# This test only works for ELF targets. +# It ought to work for some a.out targets, but it doesn't. +if {! [is_elf_format] && ! [is_pecoff_format]} { + unsupported $testname return } +# Weak symbols are broken for non-i386 PE targets. +if {! [istarget i?86-*-*]} { + setup_xfail *-*-pe* +} if {! [ld_assemble $as $srcdir/$subdir/weak1.s tmpdir/weak1.o] || ! [ld_assemble $as $srcdir/$subdir/weak2.s tmpdir/weak2.o]} then { diff --git a/ld/testsuite/ld-undefined/weak-undef.exp b/ld/testsuite/ld-undefined/weak-undef.exp index fe21a8fc031..e635458f056 100644 --- a/ld/testsuite/ld-undefined/weak-undef.exp +++ b/ld/testsuite/ld-undefined/weak-undef.exp @@ -1,5 +1,5 @@ # Test handling of weak undefined symbols -# Copyright 2001 +# Copyright 2001, 2004 # Free Software Foundation, Inc. # # This file is free software; you can redistribute it and/or modify @@ -29,15 +29,23 @@ if { ![istarget *-*-sysv4*] \ && ![istarget *-*-linux*] \ && ![istarget *-*-irix5*] \ && ![istarget *-*-irix6*] \ + && ![is_pecoff_format] \ && ![istarget *-*-solaris2*] } then { + unsupported $testname return } if { [istarget *-*-linux*aout*] \ || [istarget *-*-linux*oldld*] } { + unsupported $testname return } +# Weak symbols are broken for non-i386 PE targets. +if {! [istarget i?86-*-*]} { + setup_xfail *-*-pe* +} + if {! [ld_assemble $as $srcdir/$subdir/weak-undef.s tmpdir/weak-undef.o]} then { # It's OK if .weak doesn't work on this target. unresolved $testname diff --git a/ld/testsuite/lib/ld-lib.exp b/ld/testsuite/lib/ld-lib.exp index 3758937f2cd..b4e3f33ce51 100644 --- a/ld/testsuite/lib/ld-lib.exp +++ b/ld/testsuite/lib/ld-lib.exp @@ -1,5 +1,5 @@ # Support routines for LD testsuite. -# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 +# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 # Free Software Foundation, Inc. # # This file is free software; you can redistribute it and/or modify @@ -416,6 +416,20 @@ proc is_elf64 { binary_file } { return 0 } +# +# is_pecoff_format +# true if the object format is known to be PECOFF +# +proc is_pecoff_format {} { + if { ![istarget *-*-mingw32*] \ + && ![istarget *-*-cygwin*] \ + && ![istarget *-*-pe*] } { + return 0 + } + + return 1 +} + # # simple_diff # compares two files line-by-line -- 2.39.2