This is the mail archive of the mailing list for the binutils project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[RFC] ELF-alike Weak symbols for PE targets: rationale, design and implementation.

    Hello everyone,

  Back in the previous thread[*] about weak symbols on windows, I said I'd
make a proposal about how to proceed.  As the best proposals are those which
show some code, I've added a draft patch; this is not a submission nor for
review, it is just what I've hacked up to illustrate the principles of
operation.  It has commented out code and stuff that is hard-coded when it
should be a backend variable and stuff that is probably in the wrong place,
but it works well enough for the purpose; please save any code-review comments
for when I actually submit.

  Apologies in advance for the length and verbosity of this post; I just want
to make sure that everything is clearly explained and avoid perpetuating the
ambiguities and minor technical inaccuracies which have arisen in previous
discussions.  By making everything explicit I hope to avoid hidden assumptions
and ensure that we can be confident we're all talking about the same thing!

]----------------------[ Main proposal document ]----------------------[


  The motivation for this feature is two-fold:

- Cygwin's purpose is to emulate Linux and its features and operating
environment as closely as is practicable on the Windows platform.  Since weak
symbols are a feature used in Linux programs, and we to the greatest extent
possible want Linux programs to simply compile and run under Cygwin with
little or no modification needed, supporting ELF weak-symbol semantics aligns
with the fundamental intent of Cygwin.

- COMDAT sections are adequate to support vague linkage in statically-linked
applications, but aren't representable in executable image formats, and so
can't fully support the C++ semantics that allow not just the overriding but
the full replacement of user-level operators new and delete[**], as tested by
e.g. g++.old-deja/g++.brendan/new3.C in the g++ testsuite.


  So, the intention of this feature is to extend and enhance Cygwin's
"Linuxness", and by doing so provide a solid base on which to add a further
new feature - dynamic runtime symbol resolution in Windows DLLs.  I am myself
guilty of having somewhat conflated these two features in my past description
of the situation (mainly because I've been learning how this works as I go
along), so it behooves me to clarify this:

- Weak symbols are *only* relevant at final link-time.
- To allow function replacement I want to add support for dynamic symbols.
- Fully implementing that for all symbols in all libraries and executables is
liable to impose noticeable overheads of space and runtime.
- So I only want to provide a limited degree support for dynamic symbols, just
in order to serve the purposes of language compliance for the compiler,
runtime and environment.

  From these points, I concluded that a simple and effective solution would be
to implement dynamic runtime (re-)resolution only for weak symbols, as it
makes a convenient marker to indicate the subset of symbols that might need
dynamic resolution and is supported for the purpose of allowing function
replacement by the libstdc++ source code.  The advantage of using weak symbols
for this annotation is that the same mechanism will then also be able to be
employed to support allowing DLLs to import from EXEs without needing to be
explicitly linked against the named executable at final link time.

    Relationship between PE and COFF

  It is relevant to note at this point that PE is a specialisation of the COFF
object file format.  The COFF specification does not define weak symbols, but
they are implemented as a GNU extension to the format within binutils, with
basically the same semantics as ELF.

  To distinguish between the two types of weak symbol, I use the terms "pe
weak" to refer to the "weak external" symbols of class C_NT_WEAK defined by
Microsoft in the PE specification, and "COFF weak" or "ELF-(a)like weak" to
refer to symbols of class C_WEAKEXT implementing the gABI semantics.

    The requirements for Cygwin:

  Weak symbols must work with DLLs as well as when an entire application is
statically linked.  They must work as both exports and imports in both DLLs
and EXEs.

  I want it to pass the following tests in the G++ testsuite, which currently
fail when using a libstdc++ DLL.  (At least some will pass with static linking.)

FAIL: g++.dg/abi/rtti3.C scan-assembler .weak[ \\t]_?_ZTSPP1A
FAIL: g++.dg/abi/thunk4.C scan-assembler .weak[ \\t]_?_ZThn._N7Derived3FooEv
FAIL: g++.dg/eh/weak1.C execution test
FAIL: g++.dg/template/spec35.C scan-assembler
FAIL: g++.old-deja/g++.abi/cxa_vec.C execution test
FAIL: g++.old-deja/g++.brendan/new3.C execution test

  I do not propose to implement ELF symbol visibility for now, and probably
not at all.

  The final requirement is that the implementation must do nothing to harm the

  These are my overall requirements for the behaviour of the compiler and
language runtime.  They do not *necessarily* imply that weak symbols have to
be used, but that is the design I propose with which to implement these

    The design:

  The main design decision to be made here is the trade-off between between
adding extended functionality above what the native tools provide and breaking
compatibility with those tools.  For MinGW of course, there is no trade-off;
nothing less than complete interoperability is the goal.  On Cygwin however we
have a somewhat freer hand; Cygwin objects can't, on the whole, link with the
MSVC runtime, so they aren't any /use/ outside the standard operating
environment anyway.  Given that, I decided that it's a reasonable compromise
to say that since we want to do things that can't be done by the native tools,
we don't have to worry so much if that necessitates using constructs that the
native tools don't understand.

  For these reasons, I decided to implement ELF-alike weak symbols by
extending the COFF (GNU extension) support for C_WEAKEXT symbols to PE
targets.  In fact, the effects on interoperability of this will be quite
limited.  "dumpbin" will happily parse objects containing these symbols,
describing them as "UNKNOWN SYMBOL CLASS".  The librarian "lib" will happily
include them in archives and extract them at the command-line.  The only real
issue is that the linker won't know what to do with them, but since the final
point is to implement functionality that "link" could never manage anyway -
images with unresolved symbols for example - I don't think it matters.  Any
object modules not using weak symbols will remain entirely compatible with the
standard MS tools.

  In the attached patch, I add a command-line option "-mweak-style=[pe|elf]"
to the assembler.  This switch decides whether it emits standard MS weak
externals or COFF weak symbols in the generated objects.  It's fairly
straightforward, modulo the usual sort of twiddling to ensure that relocs are
emitted even for a reference that could be resolved within the current object
file, and to compensate for the quirks of bfd_install_relocation - for which,
much thanks to Vincent R., whose painful experiences making weak support work
on m68k-unknown-netbsd have been invaluable.

  The other side of the patch is the BFD and LD support for processing these
symbols at link time.  This basically already works, thanks to the COFF
support, but required minor tweaking to account for the different behaviour of
PC-relative relocs on PE platforms compared to standard COFF.  (Yep, I know
there's a missing check for flavour of weak in there that would affect
C_NT_WEAK if I don't fix it in the final patch, I won't forget!)

  In this draft implementation, I added a bool to the PE backend data that
determines the type of symbols it emits, analogously to the option for the
assembler.  It's only constant at the moment, but if I put it in the final
patch then I'll add PE backend APIs to get/set it similarly to the long
section names control.

  There is a question in my mind as to whether I really need it at all; we
could just infer the flavour of weak symbol to use by looking at which, if any
are present in the input BFDs.  We'd still need some kind of default to help
us decide what to do in the case of foreign symbols, and I'd need to do
something slightly different in coff_write_symbols where it unconditionally
resets the storage class; I'd welcome input on this decision, but I think I
lean toward keeping the bool and requiring the BFD client (such as LD) to
enable extended weak support when needed; or perhaps to allow the client to
specify a flavour if it cares, and to accept both if it doesn't.

  There's also a patch to LD, to allow it understand weak definitions when
building an import lib.  Weak symbols aren't supposed to cause anything to be
pulled in from a static archive lib, but this is a funny situation because the
archive lib in question is an import lib, so really this represents pulling in
a symbol from a DSO, given that we can't leave it undefined and let it be
resolved at runtime; until the dynamic resolution support is added, letting
weak symbols in DLLs be exported in import libraries will be needed to allow
COFF weaks to work enough to replace weak externals in libstdc++, within the
bounds of the existing limitation that you won't be able to interpose them.

]----------------------------[ Appendices ]----------------------------[

  The ELF and gABI definitions of weak symbols' semantics

  The only formal specification I have seen for the behaviour of weak symbols
is in these paragraphs quoted from the aforementioned documents:

    Weak symbols resemble global symbols, but their definitions have lower

Global and weak symbols differ in two major ways.

    * When the link editor combines several relocatable object files, it does
not allow multiple definitions of STB_GLOBAL symbols with the same name. On
the other hand, if a defined global symbol exists, the appearance of a weak
symbol with the same name will not cause an error. The link editor honors the
global definition and ignores the weak ones. Similarly, if a common symbol
exists (that is, a symbol whose st_shndx field holds SHN_COMMON), the
appearance of a weak symbol with the same name will not cause an error. The
link editor honors the common definition and ignores the weak ones.

    * When the link editor searches archive libraries [see ``Archive File'' in
Chapter 7], it extracts archive members that contain definitions of undefined
global symbols. The member's definition may be either a global or a weak
symbol. The link editor does not extract archive members to resolve undefined
weak symbols. Unresolved weak symbols have a zero value.

NOTE: The behavior of weak symbols in areas not specified by this document is
implementation defined. Weak symbols are intended primarily for use in system
software. Applications using weak symbols are unreliable since changes in the
runtime environment might cause the execution to fail. "

  Current state of play on Windows

  PE targets (which are based on COFF) support a variant of weak symbol,
termed "weak externals" in the specification.  These are more like aliases
than ELF weak symbols, and support (AFAICT) only one simple model of
operation: an object can contain an undefined reference to a symbol, and
provide another symbol as a default value to be filled in for that reference
if there is no other (strong) definition available at final link time.

  The way this works in win32 differs from ELF, as it requires having the weak
definition in the same module as the reference; in that case, a strong
definition can override it, otherwise the reloc is resolved to the default
symbol within the same module.  A weak definition in one object file cannot be
used to fill in the default in another.  If you do not supply a default within
the same object file, the default is set to *ABS* zero.

  (If you link a no-default weak reference from one file against an ordinary
defaulted weak reference, which one wins depends which comes first in the link
order.  So if the no-default one is first, you get a reference to absolute
zero; if the with-default one is first, you get a mixed-up reloc with the
value of the default sym, but pointing into the section of the non-defaulted
one - result, random runtime jump-into-space failure, because the code that
resolves NT_WEAK assumes that a default always comes from the same object as
the reference.  So resolving weak references against external objects is
certainly not currently supported in the code, and nothing in the MS
documentation suggests it need be.)

]-----------------------------[ Footnote ]-----------------------------[

[**] - Although the spec says ([replacement.functions])

    "Such replacement occurs prior to program startup"

which means that we don't have to concern ourselves with any information that
isn't available at final link time, that doesn't help us with replacing
invocations from within shared libraries (in particular libstdc++ itself),
since DLLs on Windows must be fully-resolved at link-time and cannot have
undefined references.

]-------------------------------[ ENDS ]-------------------------------[

  I think that covers pretty much everything related to the weak symbols side
of this project.  I haven't gone into detail about the process of dynamic
resolution that I want to implement built on top of this, because it's
orthogonal.  We've discussed it on the Cygwin mailing list in the past[+] and
it seemed like a practical proposal to all concerned, but I'll flesh it more
fully out when the time comes.

[*] -
[+] -

? abfd
? ld/autom4te.cache
Index: bfd/coff-i386.c
RCS file: /cvs/src/src/bfd/coff-i386.c,v
retrieving revision 1.29
diff -p -u -r1.29 coff-i386.c
--- bfd/coff-i386.c	18 Jul 2008 11:30:22 -0000	1.29
+++ bfd/coff-i386.c	7 Apr 2009 06:21:18 -0000
@@ -132,6 +132,14 @@ coff_i386_reloc (abfd, reloc_entry, symb
 	diff = reloc_entry->addend;
+#ifdef COFF_WITH_PE
+      if (symbol->flags & BSF_WEAK)
+	{
+	  diff += /*reloc_entry->addend*/ - symbol->value;
+	  if (!reloc_entry->howto->pc_relative)
+	    diff -= reloc_entry->addend;
+	}
 #ifdef COFF_WITH_PE
Index: bfd/coffgen.c
RCS file: /cvs/src/src/bfd/coffgen.c,v
retrieving revision 1.70
diff -p -u -r1.70 coffgen.c
--- bfd/coffgen.c	14 Mar 2009 09:34:27 -0000	1.70
+++ bfd/coffgen.c	7 Apr 2009 06:21:19 -0000
@@ -1028,7 +1028,8 @@ coff_write_alien_symbol (bfd *abfd,
   if (symbol->flags & BSF_LOCAL)
     native->u.syment.n_sclass = C_STAT;
   else if (symbol->flags & BSF_WEAK)
-    native->u.syment.n_sclass = obj_pe (abfd) ? C_NT_WEAK : C_WEAKEXT;
+    native->u.syment.n_sclass = obj_pe (abfd) && (pe_data (abfd)->elf_alike_weaks == 0)
     native->u.syment.n_sclass = C_EXT;
   native->u.syment.n_numaux = 0;
@@ -1172,7 +1173,8 @@ coff_write_symbols (bfd *abfd)
 		 weak (which is also classified as global), set it C_EXT.  */
 	      if (symbol->flags & BSF_WEAK)
-		*n_sclass = obj_pe (abfd) ? C_NT_WEAK : C_WEAKEXT;
+		*n_sclass = obj_pe (abfd) && (pe_data (abfd)->elf_alike_weaks == 0)
 	      else if (symbol->flags & BSF_LOCAL && class != COFF_SYMBOL_LOCAL)
 		*n_sclass = C_STAT;
 	      else if (symbol->flags & BSF_GLOBAL
Index: bfd/libcoff-in.h
RCS file: /cvs/src/src/bfd/libcoff-in.h,v
retrieving revision 1.36
diff -p -u -r1.36 libcoff-in.h
--- bfd/libcoff-in.h	14 Mar 2009 09:32:33 -0000	1.36
+++ bfd/libcoff-in.h	7 Apr 2009 06:21:19 -0000
@@ -119,6 +119,7 @@ typedef struct pe_tdata
   flagword real_flags;
   int target_subsystem;
   bfd_boolean force_minimum_alignment;
+  bfd_boolean elf_alike_weaks;
 } pe_data_type;
 #define pe_data(bfd)		((bfd)->tdata.pe_obj_data)
Index: bfd/libcoff.h
RCS file: /cvs/src/src/bfd/libcoff.h,v
retrieving revision 1.52
diff -p -u -r1.52 libcoff.h
--- bfd/libcoff.h	14 Mar 2009 09:32:33 -0000	1.52
+++ bfd/libcoff.h	7 Apr 2009 06:21:19 -0000
@@ -123,6 +123,7 @@ typedef struct pe_tdata
   flagword real_flags;
   int target_subsystem;
   bfd_boolean force_minimum_alignment;
+  bfd_boolean elf_alike_weaks;
 } pe_data_type;
 #define pe_data(bfd)		((bfd)->tdata.pe_obj_data)
Index: gas/config/obj-coff.c
RCS file: /cvs/src/src/gas/config/obj-coff.c,v
retrieving revision 1.94
diff -p -u -r1.94 obj-coff.c
--- gas/config/obj-coff.c	4 Oct 2007 17:05:37 -0000	1.94
+++ gas/config/obj-coff.c	7 Apr 2009 06:21:19 -0000
@@ -1069,34 +1069,40 @@ weak_uniquify (const char * name)
 pecoff_obj_set_weak_hook (symbolS *symbolP)
-  symbolS *alternateP;
+  if (pe_weak_style == weak_style_pe)
+    {
+      symbolS *alternateP;
-  /* See _Microsoft Portable Executable and Common Object
-     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.  */
-  alternateP = symbol_find_or_make (weak_name2altname (S_GET_NAME (symbolP)));
-  S_SET_EXTERNAL (alternateP);
+      /* See _Microsoft Portable Executable and Common Object
+	 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);
+      alternateP = symbol_find_or_make (weak_name2altname (S_GET_NAME (symbolP)));
+      S_SET_EXTERNAL (alternateP);
+      S_SET_STORAGE_CLASS (alternateP, C_NT_WEAK);
-  SA_SET_SYM_TAGNDX (symbolP, alternateP);
+      SA_SET_SYM_TAGNDX (symbolP, alternateP);
+    }
 pecoff_obj_clear_weak_hook (symbolS *symbolP)
-  symbolS *alternateP;
+  if (pe_weak_style == weak_style_pe)
+    {
+      symbolS *alternateP;
-  S_SET_STORAGE_CLASS (symbolP, 0);
-  SA_SET_SYM_FSIZE (symbolP, 0);
+      S_SET_STORAGE_CLASS (symbolP, 0);
+      SA_SET_SYM_FSIZE (symbolP, 0);
-  alternateP = symbol_find (weak_name2altname (S_GET_NAME (symbolP)));
-  S_CLEAR_EXTERNAL (alternateP);
+      alternateP = symbol_find (weak_name2altname (S_GET_NAME (symbolP)));
+      S_CLEAR_EXTERNAL (alternateP);
+    }
 #endif  /* TE_PE */
@@ -1238,6 +1244,8 @@ coff_frob_symbol (symbolS *symp, int *pu
 	  S_SET_SEGMENT (weakp, undefined_section);
+  if (S_IS_WEAK (symp) && (pe_weak_style == weak_style_elf))
 #else /* TE_PE */
   if (S_IS_WEAK (symp))
Index: gas/config/tc-i386.c
RCS file: /cvs/src/src/gas/config/tc-i386.c,v
retrieving revision 1.370
diff -p -u -r1.370 tc-i386.c
--- gas/config/tc-i386.c	26 Mar 2009 02:41:12 -0000	1.370
+++ gas/config/tc-i386.c	7 Apr 2009 06:21:21 -0000
@@ -470,6 +470,9 @@ static unsigned int no_cond_jump_promoti
 /* Encode SSE instructions with VEX prefix.  */
 static unsigned int sse2avx;
+/* Style of weak symbols to emit: PE native or ELF-alike (GNU extension).  */
+enum pe_weak_style_t pe_weak_style = weak_style_elf;
 /* Pre-defined "_GLOBAL_OFFSET_TABLE_".  */
 static symbolS *GOT_symbol;
@@ -7365,6 +7368,11 @@ md_estimate_size_before_relax (fragP, se
 	  && (S_IS_EXTERNAL (fragP->fr_symbol)
 	      || S_IS_WEAK (fragP->fr_symbol)))
+#if defined (TE_PE) || defined (TE_PEP)
+      || (pe_weak_style == weak_style_elf
+	  && (S_IS_EXTERNAL (fragP->fr_symbol)
+	      && S_IS_WEAK (fragP->fr_symbol)))
       /* Symbol is undefined in this segment, or we need to keep a
@@ -7718,6 +7726,15 @@ md_apply_fix (fixP, valP, seg)
   *valP = value;
 #endif /* !defined (TE_Mach)  */
+#if defined(TE_PE) || defined (TE_PEP)
+  /* Do not fix frags referencing an ELF-alike weak symbol.  */
+  if (pe_weak_style == weak_style_elf && fixP->fx_addsy && S_IS_WEAK (fixP->fx_addsy))
+    {
+      memset (p, 0, fixP->fx_size);
+      fixP->fx_addnumber = value;       /* Remember value for emit_reloc.  */
+      return;
+    }
   /* Are we finished with this relocation now?  */
   if (fixP->fx_addsy == NULL)
     fixP->fx_done = 1;
@@ -7952,6 +7969,7 @@ const char *md_shortopts = "qn";
 struct option md_longopts[] =
@@ -7969,6 +7987,9 @@ struct option md_longopts[] =
   {"mold-gcc", no_argument, NULL, OPTION_MOLD_GCC},
   {"msse2avx", no_argument, NULL, OPTION_MSSE2AVX},
   {"msse-check", required_argument, NULL, OPTION_MSSE_CHECK},
+#if defined (TE_PE)
+  {"mweak-style", required_argument, NULL, OPTION_WEAK_STYLE},
   {NULL, no_argument, NULL, 0}
 size_t md_longopts_size = sizeof (md_longopts);
@@ -8173,6 +8194,17 @@ md_parse_option (int c, char *arg)
 	as_fatal (_("Invalid -msse-check= option: `%s'"), arg);
+#if defined (TE_PE)
+      if (strcasecmp (arg, "pe") == 0)
+	pe_weak_style = weak_style_pe;
+      else if (strcasecmp (arg, "elf") == 0)
+	pe_weak_style = weak_style_elf;
+      else
+	as_fatal (_("Invalid -mweak-style= option: `%s'"), arg);
+      break;
       return 0;
@@ -8240,6 +8272,11 @@ md_show_usage (stream)
   -mnaked-reg             don't require `%%' prefix for registers\n"));
   fprintf (stream, _("\
   -mold-gcc               support old (<= 2.8.1) versions of gcc\n"));
+#if defined(TE_PE)
+  fprintf (stream, _("\
+  -mweak-style=[pe|elf]   style of weak symbols to emit in PE objects:\n\
+                           native pe (default) or ELF-like (GNU extension).\n"));
 #if ((defined (OBJ_MAYBE_COFF) && defined (OBJ_MAYBE_AOUT)) \
@@ -8599,6 +8636,18 @@ tc_gen_reloc (section, fixp)
       if (fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
 	rel->address = fixp->fx_offset;
+#if defined (TE_PE) || defined (TE_PEP)
+    /* PR gas/3041 Adjust addend in order to force bfd_install_relocation()
+       to put the symbol offset into frags referencing a weak symbol.  */
+      if (1/*!fixp->fx_pcrel*/
+	  && fixp->fx_addsy
+	  && S_IS_WEAK (fixp->fx_addsy)
+	  && (! bfd_is_und_section (S_GET_SEGMENT (fixp->fx_addsy))
+	      || fixp->fx_pcrel))
+	rel->addend = /*fixp->fx_pcrel ? 0 :*/ fixp->fx_addnumber
+		    - (S_GET_VALUE (fixp->fx_addsy) * 1);
+      else
       rel->addend = 0;
   /* Use the rela in 64bit mode.  */
Index: gas/config/tc-i386.h
RCS file: /cvs/src/src/gas/config/tc-i386.h,v
retrieving revision 1.102
diff -p -u -r1.102 tc-i386.h
--- gas/config/tc-i386.h	9 Mar 2009 18:33:42 -0000	1.102
+++ gas/config/tc-i386.h	7 Apr 2009 06:21:21 -0000
@@ -140,6 +140,13 @@ extern int tc_i386_fix_adjustable (struc
   (OUTPUT_FLAVOR == bfd_target_elf_flavour)
+/* Defer resolving all weak symbols until final link.  */
+#define TC_FORCE_RELOCATION(FIX)			         \
+  ((1/*!(FIX)->fx_pcrel*/					 \
+      && (FIX)->fx_addsy && S_IS_WEAK ((FIX)->fx_addsy)          \
+      && ! bfd_is_und_section (S_GET_SEGMENT ((FIX)->fx_addsy))) \
+    ? TRUE : generic_force_reloc (FIX))
 /* This expression evaluates to true if the relocation is for a local
    object for which we still want to do the relocation at runtime.
    False if we are willing to perform this relocation while building
@@ -279,6 +286,14 @@ extern bfd_vma x86_64_section_letter (in
 #define TC_DWARF2_EMIT_OFFSET  tc_pe_dwarf2_emit_offset
 void tc_pe_dwarf2_emit_offset (symbolS *, unsigned int);
+enum pe_weak_style_t
+  {
+    weak_style_pe = 0,
+    weak_style_elf,
+  };
+extern enum pe_weak_style_t pe_weak_style;
 #endif /* TE_PE */
 #endif /* TC_I386 */
Index: ld/
RCS file: /cvs/src/src/ld/,v
retrieving revision 1.47
diff -p -u -r1.47
--- ld/	17 Mar 2009 05:32:59 -0000	1.47
+++ ld/	7 Apr 2009 06:21:24 -0000
@@ -144,7 +144,8 @@ i[3-7]86-pc-interix*)
-  HOSTING_LIBS="$HOSTING_LIBS"' -lcygwin -L/usr/lib/w32api -luser32 -lkernel32 -ladvapi32 -lshell32 `if [ -f ../gcc/libgcc.a ] ; then echo ../gcc/libgcc.a ; else ${CC} -print-libgcc-file-name; fi`'
+  HOSTING_LIBS='`if [ -f ../gcc/libgcc.a ]; then libgcc=../gcc/libgcc.a; else libgcc=\`${CC} -print-libgcc-file-name\`; fi; if [ -f ../gcc/libgcc_eh.a ]; then libgcc="$$libgcc ../gcc/libgcc_eh.a"; else libgcc_eh=\`${CC} -print-file-name=libgcc_eh.a\`; if [ x"$$libgcc_eh" != xlibgcc_eh.a ]; then libgcc="$$libgcc $$libgcc_eh"; fi; fi; if [ -f ../gcc/libunwind.a ]; then libgcc="$$libgcc ../gcc/libunwind.a"; else libunwind=\`${CC} -print-file-name=libunwind.a\`; if [ x"$$libunwind" != xlibunwind.a ]; then libgcc="$$libgcc $$libunwind"; fi; fi; echo $$libgcc `'
+  HOSTING_LIBS="$HOSTING_LIBS"' -lcygwin -L/usr/lib/w32api -luser32 -lkernel32 -ladvapi32 -lshell32 '"$HOSTING_LIBS"
Index: ld/pe-dll.c
RCS file: /cvs/src/src/ld/pe-dll.c,v
retrieving revision 1.117
diff -p -u -r1.117 pe-dll.c
--- ld/pe-dll.c	18 Feb 2009 18:23:07 -0000	1.117
+++ ld/pe-dll.c	7 Apr 2009 06:21:24 -0000
@@ -852,7 +852,8 @@ process_def_file (bfd *abfd ATTRIBUTE_UN
       if (blhe
 	  && (blhe->type == bfd_link_hash_defined
-	      || (blhe->type == bfd_link_hash_common)))
+	      || (blhe->type == bfd_link_hash_common)
+	      || (blhe->type == bfd_link_hash_defweak)))
 	  if (!pe_def_file->exports[i].flag_noname)
@@ -861,7 +862,7 @@ process_def_file (bfd *abfd ATTRIBUTE_UN
 	  /* Only fill in the sections. The actual offsets are computed
 	     in fill_exported_offsets() after common symbols are laid
 	     out.  */
-	  if (blhe->type == bfd_link_hash_defined)
+	  if (blhe->type != bfd_link_hash_common)
 	    exported_symbol_sections[i] = blhe->u.def.section;
 	    exported_symbol_sections[i] = blhe->u.c.p->section;

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]