W dniu 22.11.2018 o 09:51, Mateusz pisze: > W dniu 21.11.2018 o 23:39, Martin Storsjö pisze: >> On Wed, 21 Nov 2018, Mateusz wrote: >> >>> Problem is in libstdc++.a which uses fseeko64 from libmingwex. >>> >>> My proposition is: >>> we could build two libmingwex -- libmingwex for msvcrt and libmingwex10 for >>> msvcr100 and above, leave fseeko64 in libmingwex* and remove _fseeki64 and >>> _ftelli64 from libmingwex10. >>> For msvcrt spec file should be without changes >>> ... -lmoldname -lmingwex -lmsvcrt >>> for ucrtbase (and similar for msvcr120/110/100) >>> ... -lmoldname -lmingwex10 -lucrtbase >> >> In general, so far, when using ucrt, we rely on a number of redirections in >> headers, so that an object file built for an older crt version won't >> necessarily work with the newer one. The exception to this, so far, has been >> the main CRT startup files and libmingw32/libmingwex. (We haven't checked >> all of libmingwex exhaustively, but only the parts that have been pulled in >> by code built in this setup.) >> >> In your case, the issue is that libstdc++.a contains a whole lot of object >> files built targeting another crt version. >> >> I would very much prefer not to have two separate versions of libmingwex. >> Instead it's often possible to tweak what libmingwex does, and tweak the >> headers and actual functions/stubs exported by libmsvcrt.a and libucrtbase.a >> so that the same single build of libmingwex.a works with both. >> >> If the __pioinfo function is the only issue with a libstdc++.a built against >> libmsvcrt.a but linked against libucrtbase.a, it might be worthwhile to try >> to work around it. To do that, the first step would be to look up what it is >> used for and what the replacing functionality is in ucrtbase. After that, >> one can e.g. change the headers to redirect the __piofunction to use the new >> ucrtbase mechansim in general, and add a wrapper in libmsvcr*.a that >> provides this interface. See e.g. src_msvcrt_common in >> mingw-w64-crt/Makefile.am for a few cases of doing this so far. >> >> A different strategy would be to move the helpers that differ depending on >> crt version from libmingwex.a into libmsvcr*.a and libucrtbase.a instead, to >> allow different versions/sets of them that actually match the CRT they are >> to be used with. In this case, move the parts that you wanted to >> differentiate in libmingwex into libmsvcr*.a and libucrtbase.a. > > Thanks! I like the last approach -- we could remove _fseeki64 and _ftelli64 > from libmingwex.a and move these functions to libmsvcrt.a and libmsvcr80.a > (there are already in libmsvcr90.a and newer). > > I will make some tests and prepare new patch.
I've attached new patch -- mingw-w64-crt/Makefile.am is changed so you should use automake before testing. Now libmingwex.a is smaller (without _fseeki64 and _ftelli64 functions which are moved to libmsvcrt.a). I can build and execute x265 linked to msvcrt.dll, msvcr120.dll and ucrtbase.dll. In old file mingw-w64-crt/stdio/fseeko64.c was function mingw_dosmaperr that I don't know for what reason it was so I removed this function (there was only one string 'mingw_dosmaperr' in whole mingw-w64 folder). Regards, Mateusz
From 2c3234b7f75efce0c6fb0c872ebd79534948fbce Mon Sep 17 00:00:00 2001 From: Mateusz Brzostek <[email protected]> Date: Fri, 23 Nov 2018 19:16:43 +0100 Subject: [PATCH] move _fseeki64 and _ftelli64 functions from libmingwex to libmsvcrt Signed-off-by: Mateusz Brzostek <[email protected]> --- mingw-w64-crt/Makefile.am | 1 + mingw-w64-crt/stdio/fseeki64.c | 171 +++++++++++++++++++++++++++++++ mingw-w64-crt/stdio/fseeko64.c | 222 ----------------------------------------- mingw-w64-headers/crt/stdio.h | 17 +--- 4 files changed, 175 insertions(+), 236 deletions(-) create mode 100644 mingw-w64-crt/stdio/fseeki64.c diff --git a/mingw-w64-crt/Makefile.am b/mingw-w64-crt/Makefile.am index 079dc5a..f8b0623 100644 --- a/mingw-w64-crt/Makefile.am +++ b/mingw-w64-crt/Makefile.am @@ -210,6 +210,7 @@ src_msvcrt=\ secapi/vsprintf_s.c \ secapi/wmemcpy_s.c \ secapi/wmemmove_s.c \ + stdio/fseeki64.c \ stdio/mingw_lock.c src_ucrtbase=\ diff --git a/mingw-w64-crt/stdio/fseeki64.c b/mingw-w64-crt/stdio/fseeki64.c new file mode 100644 index 0000000..36d3274 --- /dev/null +++ b/mingw-w64-crt/stdio/fseeki64.c @@ -0,0 +1,171 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the mingw-w64 runtime package. + * No warranty is given; refer to the file DISCLAIMER.PD within this package. + */ +#include <stdio.h> +#include <io.h> +#include <errno.h> +#include <windows.h> +#include <internal.h> + +#define _IOYOURBUF 0x0100 +#define _IOSETVBUF 0x0400 +#define _IOFEOF 0x0800 +#define _IOFLRTN 0x1000 +#define _IOCTRLZ 0x2000 +#define _IOCOMMIT 0x4000 + +/* General use macros */ + +#define inuse(s) ((s)->_flag & (_IOREAD|_IOWRT|_IORW)) +#define mbuf(s) ((s)->_flag & _IOMYBUF) +#define nbuf(s) ((s)->_flag & _IONBF) +#define ybuf(s) ((s)->_flag & _IOYOURBUF) +#define bigbuf(s) ((s)->_flag & (_IOMYBUF|_IOYOURBUF)) +#define anybuf(s) ((s)->_flag & (_IOMYBUF|_IONBF|_IOYOURBUF)) + +#define _INTERNAL_BUFSIZ 4096 +#define _SMALL_BUFSIZ 512 + +#define FOPEN 0x01 /* file handle open */ +#define FEOFLAG 0x02 /* end of file has been encountered */ +#define FCRLF 0x04 /* CR-LF across read buffer (in text mode) */ +#define FPIPE 0x08 /* file handle refers to a pipe */ +#define FNOINHERIT 0x10 /* file handle opened _O_NOINHERIT */ +#define FAPPEND 0x20 /* file handle opened O_APPEND */ +#define FDEV 0x40 /* file handle refers to device */ +#define FTEXT 0x80 /* file handle is in text mode */ + +_CRTIMP __int64 __cdecl _lseeki64(int fh,__int64 pos,int mthd); +__int64 __cdecl _ftelli64(FILE *str); +int __cdecl _flush (FILE *str); + +int __cdecl _flush (FILE *str) +{ + FILE *stream; + int rc = 0; /* assume good return */ + __int64 nchar; + + stream = str; + if ((stream->_flag & (_IOREAD | _IOWRT)) == _IOWRT && bigbuf(stream) + && (nchar = (__int64) (stream->_ptr - stream->_base)) > 0ll) + { + if ( _write(_fileno(stream), stream->_base, nchar) == nchar) { + if (_IORW & stream->_flag) + stream->_flag &= ~_IOWRT; + } else { + stream->_flag |= _IOERR; + rc = EOF; + } + } + stream->_ptr = stream->_base; + stream->_cnt = 0ll; + return rc; +} + +int __cdecl _fseeki64(FILE *str,__int64 offset,int whence) +{ + FILE *stream; + /* Init stream pointer */ + stream = str; + errno=0; + if(!stream || ((whence != SEEK_SET) && (whence != SEEK_CUR) && (whence != SEEK_END))) + { + errno=EINVAL; + return -1; + } + /* Clear EOF flag */ + stream->_flag &= ~_IOEOF; + + if (whence == SEEK_CUR) { + offset += _ftelli64(stream); + whence = SEEK_SET; + } + /* Flush buffer as necessary */ + _flush(stream); + + /* If file opened for read/write, clear flags since we don't know + what the user is going to do next. If the file was opened for + read access only, decrease _bufsiz so that the next _filbuf + won't cost quite so much */ + + if (stream->_flag & _IORW) + stream->_flag &= ~(_IOWRT|_IOREAD); + else if ( (stream->_flag & _IOREAD) && (stream->_flag & _IOMYBUF) && + !(stream->_flag & _IOSETVBUF) ) + stream->_bufsiz = _SMALL_BUFSIZ; + + /* Seek to the desired locale and return. */ + + return (_lseeki64(_fileno(stream), offset, whence) == -1ll ? -1 : 0); +} + +__int64 __cdecl _ftelli64(FILE *str) +{ + FILE *stream; + size_t offset; + __int64 filepos; + register char *p; + char *max; + int fd; + size_t rdcnt = 0; + + errno=0; + stream = str; + fd = _fileno(stream); + if (stream->_cnt < 0ll) stream->_cnt = 0ll; + if ((filepos = _lseeki64(fd, 0ll, SEEK_CUR)) < 0L) + return -1ll; + + if (!bigbuf(stream)) /* _IONBF or no buffering designated */ + return (filepos - (__int64) stream->_cnt); + + offset = (size_t)(stream->_ptr - stream->_base); + + if (stream->_flag & (_IOWRT|_IOREAD)) + { + if (_osfile(fd) & FTEXT) + for (p = stream->_base; p < stream->_ptr; p++) + if (*p == '\n') /* adjust for '\r' */ + offset++; + } + else if (!(stream->_flag & _IORW)) { + errno=EINVAL; + return -1ll; + } + if (filepos == 0ll) + return ((__int64)offset); + + if (stream->_flag & _IOREAD) /* go to preceding sector */ + { + if (stream->_cnt == 0ll) /* filepos holds correct location */ + offset = 0ll; + else + { + rdcnt = ((size_t) stream->_cnt) + ((size_t) (size_t)(stream->_ptr - stream->_base)); + if (_osfile(fd) & FTEXT) { + if (_lseeki64(fd, 0ll, SEEK_END) == filepos) { + max = stream->_base + rdcnt; + for (p = stream->_base; p < max; p++) + if (*p == '\n') /* adjust for '\r' */ + rdcnt++; + if (stream->_flag & _IOCTRLZ) + ++rdcnt; + } else { + _lseeki64(fd, filepos, SEEK_SET); + if ( (rdcnt <= _SMALL_BUFSIZ) && (stream->_flag & _IOMYBUF) && + !(stream->_flag & _IOSETVBUF)) + rdcnt = _SMALL_BUFSIZ; + else + rdcnt = stream->_bufsiz; + if (_osfile(fd) & FCRLF) + ++rdcnt; + } + } /* end if FTEXT */ + } + filepos -= (__int64)rdcnt; + } /* end else stream->_cnt != 0 */ + return (filepos + (__int64)offset); +} + diff --git a/mingw-w64-crt/stdio/fseeko64.c b/mingw-w64-crt/stdio/fseeko64.c index 5905aa2..f195324 100644 --- a/mingw-w64-crt/stdio/fseeko64.c +++ b/mingw-w64-crt/stdio/fseeko64.c @@ -6,104 +6,8 @@ #include <stdio.h> #include <io.h> #include <errno.h> -#include <windows.h> #include <internal.h> -struct oserr_map { - unsigned long oscode; /* OS values */ - int errnocode; /* System V codes */ -}; - -typedef union doubleint { - __int64 bigint; - struct { - unsigned long lowerhalf; - long upperhalf; - } twoints; -} DINT; - -#define _IOYOURBUF 0x0100 -#define _IOSETVBUF 0x0400 -#define _IOFEOF 0x0800 -#define _IOFLRTN 0x1000 -#define _IOCTRLZ 0x2000 -#define _IOCOMMIT 0x4000 - -/* General use macros */ - -#define inuse(s) ((s)->_flag & (_IOREAD|_IOWRT|_IORW)) -#define mbuf(s) ((s)->_flag & _IOMYBUF) -#define nbuf(s) ((s)->_flag & _IONBF) -#define ybuf(s) ((s)->_flag & _IOYOURBUF) -#define bigbuf(s) ((s)->_flag & (_IOMYBUF|_IOYOURBUF)) -#define anybuf(s) ((s)->_flag & (_IOMYBUF|_IONBF|_IOYOURBUF)) - -#define _INTERNAL_BUFSIZ 4096 -#define _SMALL_BUFSIZ 512 - -#define FOPEN 0x01 /* file handle open */ -#define FEOFLAG 0x02 /* end of file has been encountered */ -#define FCRLF 0x04 /* CR-LF across read buffer (in text mode) */ -#define FPIPE 0x08 /* file handle refers to a pipe */ -#define FNOINHERIT 0x10 /* file handle opened _O_NOINHERIT */ -#define FAPPEND 0x20 /* file handle opened O_APPEND */ -#define FDEV 0x40 /* file handle refers to device */ -#define FTEXT 0x80 /* file handle is in text mode */ - -static struct oserr_map local_errtab[] = { - { ERROR_INVALID_FUNCTION, EINVAL }, { ERROR_FILE_NOT_FOUND, ENOENT }, - { ERROR_PATH_NOT_FOUND, ENOENT }, { ERROR_TOO_MANY_OPEN_FILES, EMFILE }, - { ERROR_ACCESS_DENIED, EACCES }, { ERROR_INVALID_HANDLE, EBADF }, - { ERROR_ARENA_TRASHED, ENOMEM }, { ERROR_NOT_ENOUGH_MEMORY, ENOMEM }, - { ERROR_INVALID_BLOCK, ENOMEM }, { ERROR_BAD_ENVIRONMENT, E2BIG }, - { ERROR_BAD_FORMAT, ENOEXEC }, { ERROR_INVALID_ACCESS, EINVAL }, - { ERROR_INVALID_DATA, EINVAL }, { ERROR_INVALID_DRIVE, ENOENT }, - { ERROR_CURRENT_DIRECTORY, EACCES }, { ERROR_NOT_SAME_DEVICE, EXDEV }, - { ERROR_NO_MORE_FILES, ENOENT }, { ERROR_LOCK_VIOLATION, EACCES }, - { ERROR_BAD_NETPATH, ENOENT }, { ERROR_NETWORK_ACCESS_DENIED, EACCES }, - { ERROR_BAD_NET_NAME, ENOENT }, { ERROR_FILE_EXISTS, EEXIST }, - { ERROR_CANNOT_MAKE, EACCES }, { ERROR_FAIL_I24, EACCES }, - { ERROR_INVALID_PARAMETER, EINVAL }, { ERROR_NO_PROC_SLOTS, EAGAIN }, - { ERROR_DRIVE_LOCKED, EACCES }, { ERROR_BROKEN_PIPE, EPIPE }, - { ERROR_DISK_FULL, ENOSPC }, { ERROR_INVALID_TARGET_HANDLE, EBADF }, - { ERROR_INVALID_HANDLE, EINVAL }, { ERROR_WAIT_NO_CHILDREN, ECHILD }, - { ERROR_CHILD_NOT_COMPLETE, ECHILD }, { ERROR_DIRECT_ACCESS_HANDLE, EBADF }, - { ERROR_NEGATIVE_SEEK, EINVAL }, { ERROR_SEEK_ON_DEVICE, EACCES }, - { ERROR_DIR_NOT_EMPTY, ENOTEMPTY }, { ERROR_NOT_LOCKED, EACCES }, - { ERROR_BAD_PATHNAME, ENOENT }, { ERROR_MAX_THRDS_REACHED, EAGAIN }, - { ERROR_LOCK_FAILED, EACCES }, { ERROR_ALREADY_EXISTS, EEXIST }, - { ERROR_FILENAME_EXCED_RANGE, ENOENT }, { ERROR_NESTING_NOT_ALLOWED, EAGAIN }, - { ERROR_NOT_ENOUGH_QUOTA, ENOMEM }, { 0, -1 } -}; - -_CRTIMP __int64 __cdecl _lseeki64(int fh,__int64 pos,int mthd); -__int64 __cdecl _ftelli64(FILE *str); -void mingw_dosmaperr (unsigned long oserrno); -int __cdecl _flush (FILE *str); - -int __cdecl _flush (FILE *str) -{ - FILE *stream; - int rc = 0; /* assume good return */ - __int64 nchar; - - stream = str; - if ((stream->_flag & (_IOREAD | _IOWRT)) == _IOWRT && bigbuf(stream) - && (nchar = (__int64) (stream->_ptr - stream->_base)) > 0ll) - { - if ( _write(_fileno(stream), stream->_base, nchar) == nchar) { - if (_IORW & stream->_flag) - stream->_flag &= ~_IOWRT; - } else { - stream->_flag |= _IOERR; - rc = EOF; - } - } - stream->_ptr = stream->_base; - stream->_cnt = 0ll; - return rc; -} - int fseeko64 (FILE* stream, _off64_t offset, int whence) { fpos_t pos; @@ -130,129 +34,3 @@ int fseeko64 (FILE* stream, _off64_t offset, int whence) return fsetpos (stream, &pos); } -int __cdecl _fseeki64(FILE *str,__int64 offset,int whence) -{ - FILE *stream; - /* Init stream pointer */ - stream = str; - errno=0; - if(!stream || ((whence != SEEK_SET) && (whence != SEEK_CUR) && (whence != SEEK_END))) - { - errno=EINVAL; - return -1; - } - /* Clear EOF flag */ - stream->_flag &= ~_IOEOF; - - if (whence == SEEK_CUR) { - offset += _ftelli64(stream); - whence = SEEK_SET; - } - /* Flush buffer as necessary */ - _flush(stream); - - /* If file opened for read/write, clear flags since we don't know - what the user is going to do next. If the file was opened for - read access only, decrease _bufsiz so that the next _filbuf - won't cost quite so much */ - - if (stream->_flag & _IORW) - stream->_flag &= ~(_IOWRT|_IOREAD); - else if ( (stream->_flag & _IOREAD) && (stream->_flag & _IOMYBUF) && - !(stream->_flag & _IOSETVBUF) ) - stream->_bufsiz = _SMALL_BUFSIZ; - - /* Seek to the desired locale and return. */ - - return (_lseeki64(_fileno(stream), offset, whence) == -1ll ? -1 : 0); -} - -__int64 __cdecl _ftelli64(FILE *str) -{ - FILE *stream; - size_t offset; - __int64 filepos; - register char *p; - char *max; - int fd; - size_t rdcnt = 0; - - errno=0; - stream = str; - fd = _fileno(stream); - if (stream->_cnt < 0ll) stream->_cnt = 0ll; - if ((filepos = _lseeki64(fd, 0ll, SEEK_CUR)) < 0L) - return -1ll; - - if (!bigbuf(stream)) /* _IONBF or no buffering designated */ - return (filepos - (__int64) stream->_cnt); - - offset = (size_t)(stream->_ptr - stream->_base); - - if (stream->_flag & (_IOWRT|_IOREAD)) - { - if (_osfile(fd) & FTEXT) - for (p = stream->_base; p < stream->_ptr; p++) - if (*p == '\n') /* adjust for '\r' */ - offset++; - } - else if (!(stream->_flag & _IORW)) { - errno=EINVAL; - return -1ll; - } - if (filepos == 0ll) - return ((__int64)offset); - - if (stream->_flag & _IOREAD) /* go to preceding sector */ - { - if (stream->_cnt == 0ll) /* filepos holds correct location */ - offset = 0ll; - else - { - rdcnt = ((size_t) stream->_cnt) + ((size_t) (size_t)(stream->_ptr - stream->_base)); - if (_osfile(fd) & FTEXT) { - if (_lseeki64(fd, 0ll, SEEK_END) == filepos) { - max = stream->_base + rdcnt; - for (p = stream->_base; p < max; p++) - if (*p == '\n') /* adjust for '\r' */ - rdcnt++; - if (stream->_flag & _IOCTRLZ) - ++rdcnt; - } else { - _lseeki64(fd, filepos, SEEK_SET); - if ( (rdcnt <= _SMALL_BUFSIZ) && (stream->_flag & _IOMYBUF) && - !(stream->_flag & _IOSETVBUF)) - rdcnt = _SMALL_BUFSIZ; - else - rdcnt = stream->_bufsiz; - if (_osfile(fd) & FCRLF) - ++rdcnt; - } - } /* end if FTEXT */ - } - filepos -= (__int64)rdcnt; - } /* end else stream->_cnt != 0 */ - return (filepos + (__int64)offset); -} - -void mingw_dosmaperr (unsigned long oserrno) -{ - size_t i; - - _doserrno = oserrno; /* set _doserrno */ - /* check the table for the OS error code */ - i = 0; - do { - if (oserrno == local_errtab[i].oscode) - { - errno = local_errtab[i].errnocode; - return; - } - } while (local_errtab[++i].errnocode != -1); - if (oserrno >= ERROR_WRITE_PROTECT && oserrno <= ERROR_SHARING_BUFFER_EXCEEDED) - errno = EACCES; - else if (oserrno >= ERROR_INVALID_STARTING_CODESEG && oserrno <= ERROR_INFLOOP_IN_RELOC_CHAIN) - errno = ENOEXEC; - else - errno = EINVAL; -} diff --git a/mingw-w64-headers/crt/stdio.h b/mingw-w64-headers/crt/stdio.h index c79d705..6a5813f 100644 --- a/mingw-w64-headers/crt/stdio.h +++ b/mingw-w64-headers/crt/stdio.h @@ -609,31 +609,20 @@ int vsnprintf (char *__stream, size_t __n, const char *__format, __builtin_va_li /* Shouldn't be any fseeko32 in glibc, 32bit to 64bit casting should be fine */ /* int fseeko32(FILE* stream, _off_t offset, int whence);*/ /* fseeko32 redirects to fseeko64 */ -#if __MSVCRT_VERSION__ >= 0x1400 +#if __MSVCRT_VERSION__ >= 0x900 // Mark these as _CRTIMP to avoid trying to link in the mingwex versions. _CRTIMP int __cdecl _fseeki64(FILE *_File,__int64 _Offset,int _Origin); _CRTIMP __int64 __cdecl _ftelli64(FILE *_File); - __mingw_static_ovr int fseeko(FILE *_File, _off_t _Offset, int _Origin) { - return fseek(_File, _Offset, _Origin); - } - __mingw_static_ovr int fseeko64(FILE *_File, _off64_t _Offset, int _Origin) { - return _fseeki64(_File, _Offset, _Origin); - } - __mingw_static_ovr _off_t ftello(FILE *_File) { - return ftell(_File); - } - __mingw_static_ovr _off64_t ftello64(FILE *_File) { - return _ftelli64(_File); - } #else __MINGW_EXTENSION int __cdecl _fseeki64(FILE *_File,__int64 _Offset,int _Origin); __MINGW_EXTENSION __int64 __cdecl _ftelli64(FILE *_File); +#endif + int fseeko64(FILE* stream, _off64_t offset, int whence); int fseeko(FILE* stream, _off_t offset, int whence); /* Returns truncated 64bit off_t */ _off_t ftello(FILE * stream); _off64_t ftello64(FILE * stream); -#endif #ifndef _FILE_OFFSET_BITS_SET_FSEEKO #define _FILE_OFFSET_BITS_SET_FSEEKO -- 2.7.4
_______________________________________________ Mingw-w64-public mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/mingw-w64-public
