summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDanny Smith <dannysmith@users.sourceforge.net>2003-01-26 22:37:50 +0000
committerDanny Smith <dannysmith@users.sourceforge.net>2003-01-26 22:37:50 +0000
commit76e82d4c4926f1b4b1efdd43b7ce868547d06acd (patch)
tree489fccec6f77031bdde85fa40f72ad324aae86b8
parent53eef40e64e7d2375140e5fc181212dc80e54f17 (diff)
downloadgdb-76e82d4c4926f1b4b1efdd43b7ce868547d06acd.tar.gz
Merge from mingw trunk (changes since 2002-12-10).
-rw-r--r--winsup/mingw/ChangeLog57
-rw-r--r--winsup/mingw/Makefile.in8
-rw-r--r--winsup/mingw/crt1.c7
-rw-r--r--winsup/mingw/dllcrt1.c201
-rw-r--r--winsup/mingw/include/_mingw.h6
-rw-r--r--winsup/mingw/include/ctype.h5
-rw-r--r--winsup/mingw/include/malloc.h93
-rw-r--r--winsup/mingw/include/math.h2
-rw-r--r--winsup/mingw/include/stdlib.h15
-rw-r--r--winsup/mingw/include/wctype.h2
-rw-r--r--winsup/mingw/mingwex/math/llround.c24
-rw-r--r--winsup/mingw/mingwex/mingw-fseek.c88
-rw-r--r--winsup/mingw/pseudo-reloc-list.c3
-rw-r--r--winsup/mingw/pseudo-reloc.c46
14 files changed, 542 insertions, 15 deletions
diff --git a/winsup/mingw/ChangeLog b/winsup/mingw/ChangeLog
index 9585ed3bb1d..541ede07961 100644
--- a/winsup/mingw/ChangeLog
+++ b/winsup/mingw/ChangeLog
@@ -1,3 +1,60 @@
+2003-01-27 Danny Smith <dannysmith@users.sourceforge.net>
+
+ Merge from mingw trunk (changes since 2002-12-10).
+
+ 2003-01-26 Danny Smith <dannysmith@users.sourceforge.net>
+
+ * include/math.h (tgamma): Correct typo in comment.
+
+ 2003-01-26 Danny Smith <dannysmith@users.sourceforge.net>
+
+ * mingwex/mingw-fseek.c (INLINE): Remove define.
+ (__mingw_is_win9x): Remove static inline function.
+ (_mingw_fwrite): Use _osver instead of __mingw_is_win9x.
+
+ 2003-01-11 Danny Smith <dannysmith@users.sourceforge.net>
+
+ * mingwex/math/llround.c: Correct function name and
+ change return value to long long.
+
+ 2003-01-07 Danny Smith <dannysmith@users.sourceforge.net>
+
+ * include/ctype.h (__isascii): Don't cast arg to unsigned.
+ (iswascii): Likewise. Correct mask.
+ * include/wctype.h (iswascii): Don't cast arg to unsigned.
+ Correct mask
+
+ 2003-01-03 Danny Smith <dannysmith@users.sourceforge.net>
+
+ * include/stdlib.h (_osver, _winver, _winmajor,
+ _winminor): Declare as direct imports from dll if
+ __DECLSPEC_SUPPORTED.
+
+ 2003-01-01 Danny Smith <dannysmith@users.sourceforge.net>
+
+ * pseudo-reloc.c (do_pseudo_reloc): Make static.
+ * pseudo-reloc-list.c: New file.
+ * crt1.c (_pei386_runtime_relocator): Declare.
+ (__mingw_CRTStartup): Call it.
+ * dllcrt1.c (_pei386_runtime_relocator): Declare.
+ (DllMainCRTStartup): Call it.
+ * Makefile.in: Add pseudo-reloc.o pseude-reloc-list.o to
+ libmingw32.a.
+
+ 2003-01-01 Egor Duda <deo@logos-m.ru>
+
+ * pseudo-reloc.c: New file.
+
+ 2002-12-20 Earnie Boyd <earnie@users.sf.net>
+
+ * include/_mingw.h: Increment version to 2.4.
+ Makefile.in: Ditto.
+
+ 2002-12-12 Earnie Boyd <earnie@users.sf.net>
+
+ * include/malloc.h (_alloca): Add definition.
+ (alloca): Ditto.
+
2002-12-10 Danny Smith <dannysmith@users.sourceforge.net>
* include/_mingw.h (__HAVE_STD_CXX): Define to 0 for
diff --git a/winsup/mingw/Makefile.in b/winsup/mingw/Makefile.in
index f2e5d253da5..5b3a0f960e3 100644
--- a/winsup/mingw/Makefile.in
+++ b/winsup/mingw/Makefile.in
@@ -18,7 +18,7 @@
# This makefile requires GNU make.
PACKAGE = mingw-runtime
-VERSION = 2.3
+VERSION = 2.4
CYGRELEASE = 1
VPATH = @srcdir@
@@ -150,7 +150,8 @@ FLAGS_TO_PASS:=\
CRT0S = crt1.o dllcrt1.o crt2.o dllcrt2.o CRT_noglob.o crtmt.o crtst.o \
CRT_fp8.o CRT_fp10.o txtmode.o binmode.o
MINGW_OBJS = CRTglob.o CRTfmode.o CRTinit.o dllmain.o gccmain.o \
- main.o crtst.o mthr_stub.o CRT_fp10.o txtmode.o
+ main.o crtst.o mthr_stub.o CRT_fp10.o txtmode.o \
+ pseudo-reloc.o pseudo-reloc-list.o
MOLD_OBJS = ctype_old.o string_old.o
LIBS = libcrtdll.a libmsvcrt.a libmsvcrt20.a libmsvcrt40.a libmingw32.a \
@@ -164,7 +165,8 @@ crt1.c crtdll.def crtmt.c crtst.c ctype_old.c dllcrt1.c dllmain.c \
gccmain.c init.c install-sh jamfile main.c mkinstalldirs moldname-crtdll.def \
moldname-msvcrt.def moldname.def moldname.def.in msvcrt.def msvcrt20.def \
msvcrt40.def mthr.c mthr_init.c mthr_stub.c readme.txt string_old.c \
-CRT_fp8.c CRT_fp10.c test_headers.c txtmode.c binmode.c
+CRT_fp8.c CRT_fp10.c test_headers.c txtmode.c binmode.c pseudo-reloc.c \
+pseudo-reloc-list.c
all_dlls_host = @all_dlls_host@
install_dlls_host = @install_dlls_host@
diff --git a/winsup/mingw/crt1.c b/winsup/mingw/crt1.c
index ef4623f515f..e589b4c1447 100644
--- a/winsup/mingw/crt1.c
+++ b/winsup/mingw/crt1.c
@@ -47,6 +47,9 @@
* a-good-idea use of include. */
#include "init.c"
+
+extern void _pei386_runtime_relocator (void);
+
extern int main (int, char **, char **);
/*
@@ -203,6 +206,10 @@ __mingw_CRTStartup ()
*/
_mingw32_init_fmode ();
+
+ /* Adust references to dllimported data that have non-zero offsets. */
+ _pei386_runtime_relocator ();
+
/*
* Call the main function. If the user does not supply one
* the one in the 'libmingw32.a' library will be linked in, and
diff --git a/winsup/mingw/dllcrt1.c b/winsup/mingw/dllcrt1.c
new file mode 100644
index 00000000000..3a5e79ecd51
--- /dev/null
+++ b/winsup/mingw/dllcrt1.c
@@ -0,0 +1,201 @@
+/*
+ * dllcrt1.c
+ *
+ * Initialization code for DLLs.
+ *
+ * This file is part of the Mingw32 package.
+ *
+ * Contributors:
+ * Created by Colin Peters <colin@bird.fu.is.saga-u.ac.jp>
+ * DLL support adapted from Gunther Ebert <gunther.ebert@ixos-leipzig.de>
+ * Maintained by Mumit Khan <khan@xraylith.wisc.EDU>
+ *
+ * THIS SOFTWARE IS NOT COPYRIGHTED
+ *
+ * This source code is offered for use in the public domain. You may
+ * use, modify or distribute it freely.
+ *
+ * This code is distributed in the hope that it will be useful but
+ * WITHOUT ANY WARRANTY. ALL WARRENTIES, EXPRESS OR IMPLIED ARE HEREBY
+ * DISCLAMED. This includes but is not limited to warrenties of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $Revision$
+ * $Author$
+ * $Date$
+ *
+ */
+#include <stdlib.h>
+#include <stdio.h>
+#include <io.h>
+#include <process.h>
+#include <errno.h>
+#include <windows.h>
+
+/* Unlike normal crt1, I don't initialize the FPU, because the process
+ * should have done that already. I also don't set the file handle modes,
+ * because that would be rude. */
+
+#ifdef __GNUC__
+extern void __main ();
+extern void __do_global_dtors ();
+#endif
+
+typedef void (* p_atexit_fn )(void);
+static p_atexit_fn* first_atexit;
+static p_atexit_fn* next_atexit;
+
+static void
+__dll_exit (void);
+
+/* This is based on the function in the Wine project's exit.c */
+p_atexit_fn __dllonexit (p_atexit_fn, p_atexit_fn**, p_atexit_fn**);
+
+
+extern BOOL WINAPI DllMain (HANDLE, DWORD, LPVOID);
+
+extern void _pei386_runtime_relocator (void);
+
+BOOL WINAPI
+DllMainCRTStartup (HANDLE hDll, DWORD dwReason, LPVOID lpReserved)
+{
+ BOOL bRet;
+
+ if (dwReason == DLL_PROCESS_ATTACH)
+ {
+
+#ifdef DEBUG
+ printf ("%s: DLL_PROCESS_ATTACH (%d)\n", __FUNCTION__);
+#endif
+
+ /* Initialize private atexit table for this dll.
+ 32 is min size required by ANSI */
+
+ first_atexit = (p_atexit_fn*) malloc (32 * sizeof (p_atexit_fn));
+ if (first_atexit == NULL ) /* can't allocate memory */
+ {
+ errno=ENOMEM;
+ return FALSE;
+ }
+ *first_atexit = NULL;
+ next_atexit = first_atexit;
+
+ /* Adust references to dllinported data (from other DLL's)
+ that have non-zero offsets. */
+ _pei386_runtime_relocator ();
+
+#ifdef __GNUC__
+ /* From libgcc.a, __main calls global class constructors,
+ __do_global_ctors, which registers __do_global_dtors
+ as the first entry of the private atexit table we
+ have just initialised */
+ __main ();
+
+#endif
+ }
+
+ /*
+ * Call the user-supplied DllMain subroutine.
+ * This has to come after initialization of atexit table and
+ * registration of global constructors.
+ * NOTE: DllMain is optional, so libmingw32.a includes a stub
+ * which will be used if the user does not supply one.
+ */
+
+ bRet = DllMain (hDll, dwReason, lpReserved);
+ /* Handle case where DllMain returns FALSE on attachment attempt. */
+
+ if ( (dwReason == DLL_PROCESS_ATTACH) && !bRet)
+ {
+#ifdef DEBUG
+ printf ("%s: DLL_PROCESS_ATTACH failed, cleaning up\n", __FUNCTION__);
+#endif
+
+ __dll_exit (); /* Cleanup now. This will set first_atexit to NULL so we
+ know we've cleaned up */
+ }
+
+ if (dwReason == DLL_PROCESS_DETACH)
+ {
+#ifdef DEBUG
+ printf ("%s: DLL_PROCESS_DETACH (%d)\n", __FUNCTION__);
+#endif
+ /* If not attached, return FALSE. Cleanup already done above
+ if failed attachment attempt. */
+ if (! first_atexit )
+ bRet = FALSE;
+ else
+ /*
+ * We used to call __do_global_dtors () here. This is
+ * no longer necessary since __do_global_dtors is now
+ * registered at start (last out) of private atexit table.
+ */
+ __dll_exit ();
+ }
+ return bRet;
+}
+
+static
+void
+__dll_exit(void)
+/* Run LIFO terminators registered in private atexit table */
+{
+ if ( first_atexit )
+ {
+ p_atexit_fn* __last = next_atexit - 1;
+ while ( __last >= first_atexit )
+ {
+ if ( *__last != NULL )
+ {
+#ifdef DEBUG
+ printf ("%s: Calling exit function 0x%x from 0x%x\n",
+ __FUNCTION__, (unsigned)(*__last),(unsigned)__last);
+#endif
+ (**__last) ();
+ }
+ __last--;
+ }
+ free ( first_atexit ) ;
+ first_atexit = NULL ;
+ }
+ /*
+ Make sure output buffers opened by DllMain or
+ atexit-registered functions are flushed before detaching,
+ otherwise we can have problems with redirected output.
+ */
+ fflush (NULL);
+}
+
+/*
+ * The atexit exported from msvcrt.dll causes problems in DLLs.
+ * Here, we override the exported version of atexit with one that passes the
+ * private table initialised in DllMainCRTStartup to __dllonexit.
+ * That means we have to hide the mscvrt.dll atexit because the
+ * atexit defined here gets __dllonexit from the same lib.
+ */
+
+int
+atexit (p_atexit_fn pfn )
+{
+#ifdef DEBUG
+ printf ("%s: registering exit function 0x%x at 0x%x\n",
+ __FUNCTION__, (unsigned)pfn, (unsigned)next_atexit);
+#endif
+ return (__dllonexit (pfn, &first_atexit, &next_atexit)
+ == NULL ? -1 : 0 );
+}
+
+/*
+ * Likewise for non-ANSI function _onexit that may be called by
+ * code in the dll.
+ */
+
+_onexit_t
+_onexit (_onexit_t pfn )
+{
+#ifdef DEBUG
+ printf ("%s: registering exit function 0x%x at 0x%x\n",
+ __FUNCTION__, (unsigned)pfn, (unsigned)next_atexit);
+#endif
+ return ((_onexit_t) __dllonexit ((p_atexit_fn)pfn, &first_atexit, &next_atexit));
+}
diff --git a/winsup/mingw/include/_mingw.h b/winsup/mingw/include/_mingw.h
index 595655c8708..53a6a23f5af 100644
--- a/winsup/mingw/include/_mingw.h
+++ b/winsup/mingw/include/_mingw.h
@@ -57,7 +57,7 @@
# define __MINGW_IMPORT extern __attribute__((dllimport))
# endif
# define __DECLSPEC_SUPPORTED
-# else
+# else /* __declspec */
# undef __DECLSPEC_SUPPORTED
# undef __MINGW_IMPORT
# endif
@@ -65,9 +65,9 @@
# define __int64 long long
#endif /* __GNUC__ */
-#define __MINGW32_VERSION 2.3
+#define __MINGW32_VERSION 2.4
#define __MINGW32_MAJOR_VERSION 2
-#define __MINGW32_MINOR_VERSION 3
+#define __MINGW32_MINOR_VERSION 4
/* ISO C++. */
#ifndef __HAVE_STD_CXX
diff --git a/winsup/mingw/include/ctype.h b/winsup/mingw/include/ctype.h
index ead9f8fe81b..ae38c35ac42 100644
--- a/winsup/mingw/include/ctype.h
+++ b/winsup/mingw/include/ctype.h
@@ -218,7 +218,7 @@ int isleadbyte (int);
#define __WCTYPE_INLINES_DEFINED
extern __inline__ int iswalnum(wint_t __wc) {return (iswctype(__wc,_ALPHA|_DIGIT));}
extern __inline__ int iswalpha(wint_t __wc) {return (iswctype(__wc,_ALPHA));}
-extern __inline__ int iswascii(wint_t __wc) {return (((unsigned)__wc & 0x7F) ==0);}
+extern __inline__ int iswascii(wint_t __wc) {return ((__wc & ~0x7F) == 0);}
extern __inline__ int iswcntrl(wint_t __wc) {return (iswctype(__wc,_CONTROL));}
extern __inline__ int iswdigit(wint_t __wc) {return (iswctype(__wc,_DIGIT));}
extern __inline__ int iswgraph(wint_t __wc) {return (iswctype(__wc,_PUNCT|_ALPHA|_DIGIT));}
@@ -243,8 +243,7 @@ int __iscsymf (int); /* Valid first character in C symbol */
int __iscsym (int); /* Valid character in C symbol (after first) */
#ifndef __NO_CTYPE_INLINES
-extern __inline__ int __isascii(int __c)
- {return (((unsigned)__c & ~0x7F) == 0);}
+extern __inline__ int __isascii(int __c) {return ((__c & ~0x7F) == 0);}
extern __inline__ int __toascii(int __c) {return (__c & 0x7F);}
extern __inline__ int __iscsymf(int __c) {return (__CSTD isalpha(__c) || (__c == '_'));}
extern __inline__ int __iscsym(int __c) {return (__CSTD isalnum(__c) || (__c == '_'));}
diff --git a/winsup/mingw/include/malloc.h b/winsup/mingw/include/malloc.h
new file mode 100644
index 00000000000..097a5e1c1f4
--- /dev/null
+++ b/winsup/mingw/include/malloc.h
@@ -0,0 +1,93 @@
+/*
+ * malloc.h
+ *
+ * Support for programs which want to use malloc.h to get memory management
+ * functions. Unless you absolutely need some of these functions and they are
+ * not in the ANSI headers you should use the ANSI standard header files
+ * instead.
+ *
+ * This file is part of the Mingw32 package.
+ *
+ * Contributors:
+ * Created by Colin Peters <colin@bird.fu.is.saga-u.ac.jp>
+ *
+ * THIS SOFTWARE IS NOT COPYRIGHTED
+ *
+ * This source code is offered for use in the public domain. You may
+ * use, modify or distribute it freely.
+ *
+ * This code is distributed in the hope that it will be useful but
+ * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
+ * DISCLAIMED. This includes but is not limited to warranties of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $Revision$
+ * $Author$
+ * $Date$
+ *
+ */
+
+#ifndef __STRICT_ANSI__
+
+#ifndef _MALLOC_H_
+#define _MALLOC_H_
+
+/* All the headers include this file. */
+#include <_mingw.h>
+
+#include <stdlib.h>
+
+#ifndef RC_INVOKED
+
+/*
+ * The structure used to walk through the heap with _heapwalk.
+ */
+typedef struct _heapinfo
+{
+ int* _pentry;
+ size_t _size;
+ int _useflag;
+} _HEAPINFO;
+
+/* Values for _heapinfo.useflag */
+#define _USEDENTRY 0
+#define _FREEENTRY 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ The _heap* memory allocation functions are supported on NT
+ but not W9x. On latter, they always set errno to ENOSYS.
+*/
+int _heapwalk (_HEAPINFO*);
+#ifdef __GNUC__
+#define _alloca(x) __builtin_alloca((x))
+#endif
+
+#ifndef _NO_OLDNAMES
+int heapwalk (_HEAPINFO*);
+#ifdef __GNUC__
+#define alloca(x) __builtin_alloca((x))
+#endif
+#endif /* Not _NO_OLDNAMES */
+
+int _heapchk (void); /* Verify heap integrety. */
+int _heapmin (void); /* Return unused heap to the OS. */
+int _heapset (unsigned int);
+
+size_t _msize (void*);
+size_t _get_sbh_threshold (void);
+int _set_sbh_threshold (size_t);
+void * _expand (void*, size_t);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* RC_INVOKED */
+
+#endif /* Not _MALLOC_H_ */
+
+#endif /* Not __STRICT_ANSI__ */
+
diff --git a/winsup/mingw/include/math.h b/winsup/mingw/include/math.h
index bba364da1b8..377828973a1 100644
--- a/winsup/mingw/include/math.h
+++ b/winsup/mingw/include/math.h
@@ -536,7 +536,7 @@ extern double lgamma (double);
extern float lgammaf (float);
extern long double lgammal (long double);
-/* 77.12.8.4 The tgamma functions */
+/* 7.12.8.4 The tgamma functions */
extern double tgamma (double);
extern float tgammaf (float);
extern long double tgammal (long double);
diff --git a/winsup/mingw/include/stdlib.h b/winsup/mingw/include/stdlib.h
index 577ee11a1bb..58a8904c4df 100644
--- a/winsup/mingw/include/stdlib.h
+++ b/winsup/mingw/include/stdlib.h
@@ -224,10 +224,17 @@ extern unsigned int* __p__winver(void);
extern unsigned int* __p__winmajor(void);
extern unsigned int* __p__winminor(void);
-#define _osver (*__p__osver())
-#define _winver (*__p__winver())
-#define _winmajor (*__p__winmajor())
-#define _winminor (*__p__winminor())
+#ifndef __DECLSPEC_SUPPORTED
+# define _osver (*__p__osver())
+# define _winver (*__p__winver())
+# define _winmajor (*__p__winmajor())
+# define _winminor (*__p__winminor())
+#else
+__MINGW_IMPORT unsigned int _osver;
+__MINGW_IMPORT unsigned int _winver;
+__MINGW_IMPORT unsigned int _winmajor;
+__MINGW_IMPORT unsigned int _winminor;
+#endif __DECLSPEC_SUPPORTED
#else
/* Not msvcrtxx.dll, thus crtdll.dll */
diff --git a/winsup/mingw/include/wctype.h b/winsup/mingw/include/wctype.h
index 1c5b1adcb60..78168642567 100644
--- a/winsup/mingw/include/wctype.h
+++ b/winsup/mingw/include/wctype.h
@@ -108,7 +108,7 @@ extern unsigned short** _imp___ctype;
#define __WCTYPE_INLINES_DEFINED
extern __inline__ int iswalnum(wint_t __wc) {return (iswctype(__wc,_ALPHA|_DIGIT));}
extern __inline__ int iswalpha(wint_t __wc) {return (iswctype(__wc,_ALPHA));}
-extern __inline__ int iswascii(wint_t __wc) {return (((unsigned)__wc & 0x7F) ==0);}
+extern __inline__ int iswascii(wint_t __wc) {return ((__wc & ~0x7F) == 0);}
extern __inline__ int iswcntrl(wint_t __wc) {return (iswctype(__wc,_CONTROL));}
extern __inline__ int iswdigit(wint_t __wc) {return (iswctype(__wc,_DIGIT));}
extern __inline__ int iswgraph(wint_t __wc) {return (iswctype(__wc,_PUNCT|_ALPHA|_DIGIT));}
diff --git a/winsup/mingw/mingwex/math/llround.c b/winsup/mingw/mingwex/math/llround.c
new file mode 100644
index 00000000000..f8fafc48d25
--- /dev/null
+++ b/winsup/mingw/mingwex/math/llround.c
@@ -0,0 +1,24 @@
+#include <fenv.h>
+#include <math.h>
+
+long long
+llround (double x) {
+ long long retval;
+ unsigned short saved_cw, _cw;
+ __asm__ (
+ "fnstcw %0;" : "=m" (saved_cw)
+ ); /* save control word */
+ _cw = ~(FE_TONEAREST | FE_DOWNWARD | FE_UPWARD | FE_TOWARDZERO)
+ | (x > 0.0 ? FE_UPWARD : FE_DOWNWARD); /* round away from zero */
+ __asm__ (
+ "fldcw %0;" : : "m" (_cw)
+ ); /* load the rounding control */
+ __asm__ __volatile__ (
+ "fistpll %0" : "=m" (retval) : "t" (x) : "st"
+ );
+ __asm__ (
+ "fldcw %0;" : : "m" (saved_cw)
+ ); /* restore control word */
+ return retval;
+}
+
diff --git a/winsup/mingw/mingwex/mingw-fseek.c b/winsup/mingw/mingwex/mingw-fseek.c
new file mode 100644
index 00000000000..1ea011fa6d0
--- /dev/null
+++ b/winsup/mingw/mingwex/mingw-fseek.c
@@ -0,0 +1,88 @@
+/*
+ * Workaround for limitations on win9x where a file contents are
+ * not zero'd out if you seek past the end and then write.
+ * Copied from ming local-patch to binutils/bfd/libbfd.c written by
+ * Mumit Khan <khan@xraylith.wisc.edu>
+ */
+
+#include <windows.h>
+#include <stdio.h>
+#include <io.h>
+#include <stdlib.h>
+
+#define ZEROBLOCKSIZE 512
+static int __mingw_fseek_called;
+
+/* The fseek in Win9x runtime does not zero out the file if seeking past
+ the end; if you don't want random stuff from your disk included in your
+ output DLL/executable, use this version instead. On WinNT/Win2k, it
+ just calls runtime fseek().
+
+ CHECK/FIXME: Does this work for both text and binary modes?? */
+
+
+int
+__mingw_fseek (FILE *fp, long offset, int whence)
+{
+# undef fseek
+ __mingw_fseek_called = 1;
+ return fseek (fp, offset, whence);
+}
+
+int
+__mingw_fwrite (const void *buffer, size_t size, size_t count, FILE *fp)
+{
+# undef fwrite
+ if ((_osver & 0x8000) && __mingw_fseek_called)
+ {
+ DWORD actual_length, current_position;
+ __mingw_fseek_called = 0;
+ fflush (fp);
+ actual_length = GetFileSize ((HANDLE) _get_osfhandle (fileno (fp)),
+ NULL);
+ current_position = SetFilePointer ((HANDLE) _get_osfhandle (fileno (fp)),
+ 0, 0, FILE_CURRENT);
+#ifdef DEBUG
+ printf ("__mingw_fwrite: current %ld, actual %ld\n",
+ current_position, actual_length);
+#endif /* DEBUG */
+ if (current_position > actual_length)
+ {
+ static char __mingw_zeros[ZEROBLOCKSIZE];
+ long numleft;
+
+ SetFilePointer ((HANDLE) _get_osfhandle (fileno (fp)),
+ 0, 0, FILE_END);
+ numleft = current_position - actual_length;
+
+#ifdef DEBUG
+ printf ("__mingw_fwrite: Seeking %ld bytes past end\n", numleft);
+#endif /* DEBUG */
+ while (numleft > 0)
+ {
+ DWORD nzeros = (numleft > ZEROBLOCKSIZE)
+ ? ZEROBLOCKSIZE : numleft;
+ DWORD written;
+ if (! WriteFile ((HANDLE) _get_osfhandle (fileno (fp)),
+ __mingw_zeros, nzeros, &written, NULL))
+ {
+ /* Best we can hope for, or at least DJ says so. */
+ SetFilePointer ((HANDLE) _get_osfhandle (fileno (fp)),
+ 0, 0, FILE_BEGIN);
+ return -1;
+ }
+ if (written < nzeros)
+ {
+ /* Likewise. */
+ SetFilePointer ((HANDLE) _get_osfhandle (fileno (fp)),
+ 0, 0, FILE_BEGIN);
+ return -1;
+ }
+
+ numleft -= written;
+ }
+ FlushFileBuffers ((HANDLE) _get_osfhandle (fileno (fp)));
+ }
+ }
+ return fwrite (buffer, size, count, fp);
+}
diff --git a/winsup/mingw/pseudo-reloc-list.c b/winsup/mingw/pseudo-reloc-list.c
new file mode 100644
index 00000000000..87a2be247a0
--- /dev/null
+++ b/winsup/mingw/pseudo-reloc-list.c
@@ -0,0 +1,3 @@
+/* Define here in .bss in case not defined by linker script. */
+char __RUNTIME_PSEUDO_RELOC_LIST_END__ = 0;
+char __RUNTIME_PSEUDO_RELOC_LIST__ = 0;
diff --git a/winsup/mingw/pseudo-reloc.c b/winsup/mingw/pseudo-reloc.c
new file mode 100644
index 00000000000..9fe607d2cb8
--- /dev/null
+++ b/winsup/mingw/pseudo-reloc.c
@@ -0,0 +1,46 @@
+/* pseudo-reloc.c
+
+ Written by Egor Duda <deo@logos-m.ru>
+ THIS SOFTWARE IS NOT COPYRIGHTED
+
+ This source code is offered for use in the public domain. You may
+ use, modify or distribute it freely.
+
+ This code is distributed in the hope that it will be useful but
+ WITHOUT ANY WARRANTY. ALL WARRENTIES, EXPRESS OR IMPLIED ARE HEREBY
+ DISCLAMED. This includes but is not limited to warrenties of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+*/
+
+#include <windows.h>
+
+extern char __RUNTIME_PSEUDO_RELOC_LIST__;
+extern char __RUNTIME_PSEUDO_RELOC_LIST_END__;
+extern char _image_base__;
+
+typedef struct
+ {
+ DWORD addend;
+ DWORD target;
+ }
+runtime_pseudo_reloc;
+
+static void
+do_pseudo_reloc (void* start, void* end, void* base)
+{
+ DWORD reloc_target;
+ runtime_pseudo_reloc* r;
+ for (r = (runtime_pseudo_reloc*) start; r < (runtime_pseudo_reloc*) end; r++)
+ {
+ reloc_target = (DWORD) base + r->target;
+ *((DWORD*) reloc_target) += r->addend;
+ }
+}
+
+void
+_pei386_runtime_relocator ()
+{
+ do_pseudo_reloc (&__RUNTIME_PSEUDO_RELOC_LIST__,
+ &__RUNTIME_PSEUDO_RELOC_LIST_END__,
+ &_image_base__);
+}