diff -purN -x CYGWIN-PATCHES -x 'aclocal.m4*' -x autom4te.cache -x config.cache -x config.log -x config.status -x config.h -x config.h.in -x ABOUT-NLS -x Makefile.in.in -x Makevars.template -x '*SlackBuild*' -x '*.egg-info' -x '*.class' -x '*.pyc' -x '*.mo' -x '*.gmo' -x '*.orig' -x '*.rej' -x '*.spec' -x '*.temp' -x '*~' -x '*.stackdump' -x COPYING -x INSTALL -x compile -x config-ml.in -x config.guess -x config.sub -x depcomp -x elisp-comp -x install-sh -x libtool.m4 -x ltoptions.m4 -x ltsugar.m4 -x ltversion.m4 -x 'lt~obsolete.m4' -x ltmain.sh -x mdate-sh -x missing -x mkinstalldirs -x py-compile -x symlink-tree -x texinfo.tex -x ylwrap -x config.rpath -x configure -x omf.make -x xmldocs.make -x gnome-doc-utils.make -x gnome-doc-utils.m4 -x intltool.m4 -x intltool-extract -x intltool-extract.in -x intltool-merge -x intltool-merge.in -x intltool-update -x intltool-update.in origsrc/gcc-4.3.0/gcc/config/i386/cygming-crtbegin.c src/gcc-4.3.0/gcc/config/i386/cygming-crtbegin.c --- origsrc/gcc-4.3.0/gcc/config/i386/cygming-crtbegin.c 2007-07-05 08:07:34.000000000 +0100 +++ src/gcc-4.3.0/gcc/config/i386/cygming-crtbegin.c 2008-07-06 22:23:33.187500000 +0100 @@ -65,6 +65,12 @@ extern void _Jv_RegisterClasses (const v # define EH_FRAME_SECTION_CONST #endif +/* We need to indirect through a variable, as gcc assumes + that a function label used as a constant is never zero. */ +void (*register_frame_info_ptr) (const void *, struct object *) = __register_frame_info; +void *(*deregister_frame_info_ptr) (const void *) = __deregister_frame_info; +void (*jv_registerclasses_ptr) (const void *) = _Jv_RegisterClasses; + /* Stick a label at the beginning of the frame unwind info so we can register/deregister it with the exception handling library code. */ #if DWARF2_UNWIND_INFO @@ -93,15 +99,30 @@ __gcc_register_frame (void) /* Weak undefined symbols won't be pulled in from dlls; hence we first test if the dll is already loaded and, if so, get the symbol's address at run-time. If the dll is not loaded, - fallback to weak linkage to static archive. */ + fallback to weak linkage to static archive. Fallback also + if the DLL is loaded but does not export the routine. */ - void (*register_frame_fn) (const void *, struct object *); + void (*register_frame_fn) (const void *, struct object *) = 0; HANDLE h = GetModuleHandle (LIBGCC_SONAME); if (h) register_frame_fn = (void (*) (const void *, struct object *)) GetProcAddress (h, "__register_frame_info"); - else - register_frame_fn = __register_frame_info; + /* Can't use + + if (!register_frame_fn) + register_frame_fn = register_frame_info_ptr; + + directly, as gcc infers that the address of a function cannot + be zero, but in the case of an unlinked weak definition it can. + It would clearly be undefined code to use the address of an + unlinked weak function in a function call context, but I don't + know whether gcc is right to infer it's always non-zero when + being taken as a pointer-to-function constant. */ + if (!register_frame_fn) + register_frame_fn = register_frame_info_ptr; + + /* We use weak references so as to not pull in all the EH machinery + unless it's actually required by something else in the final link. */ if (register_frame_fn) register_frame_fn (__EH_FRAME_BEGIN__, &obj); #endif @@ -109,13 +130,13 @@ __gcc_register_frame (void) #if TARGET_USE_JCR_SECTION if (__JCR_LIST__[0]) { - void (*register_class_fn) (const void *); + void (*register_class_fn) (const void *) = 0; HANDLE h = GetModuleHandle (LIBGCJ_SONAME); if (h) register_class_fn = (void (*) (const void *)) GetProcAddress (h, "_Jv_RegisterClasses"); - else - register_class_fn = _Jv_RegisterClasses; + if (!register_class_fn) + register_class_fn = jv_registerclasses_ptr; if (register_class_fn) register_class_fn (__JCR_LIST__); @@ -127,13 +148,13 @@ void __gcc_deregister_frame (void) { #if DWARF2_UNWIND_INFO - void * (*deregister_frame_fn) (const void *); + void * (*deregister_frame_fn) (const void *) = 0; HANDLE h = GetModuleHandle (LIBGCC_SONAME); if (h) deregister_frame_fn = (void* (*) (const void *)) GetProcAddress (h, "__deregister_frame_info"); - else - deregister_frame_fn = __deregister_frame_info; + if (!deregister_frame_fn) + deregister_frame_fn = deregister_frame_info_ptr; if (deregister_frame_fn) deregister_frame_fn (__EH_FRAME_BEGIN__); #endif