aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authornaruse <naruse@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2016-04-23 18:46:26 +0000
committernaruse <naruse@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2016-04-23 18:46:26 +0000
commit9afc312b4fef21da91fde083f85533ffd5a9d95f (patch)
treeadf6869823bc0f1ed578d4dcaefadbfbb293d003
parentd4557cf6a66eea35b667975b52ca78bdfc815002 (diff)
downloadruby-9afc312b4fef21da91fde083f85533ffd5a9d95f.tar.gz
Support MSVC14 and 15 [Bug #11118]
Search _pioinfo which is not exported after MSVC14. [Bug #12014] [GH-884] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@54737 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rwxr-xr-xwin32/mkexports.rb1
-rw-r--r--win32/win32.c57
2 files changed, 57 insertions, 1 deletions
diff --git a/win32/mkexports.rb b/win32/mkexports.rb
index c3514f13ab..d26acbb107 100755
--- a/win32/mkexports.rb
+++ b/win32/mkexports.rb
@@ -114,6 +114,7 @@ class Exports::Mswin < Exports
when /OBJECT/, /LIBRARY/
next if /^[[:xdigit:]]+ 0+ UNDEF / =~ l
next unless /External/ =~ l
+ next if /(?:_local_stdio_printf_options|v(f|sn?)printf_l)\Z/ =~ l
next unless l.sub!(/.*?\s(\(\)\s+)?External\s+\|\s+/, '')
is_data = !$1
if noprefix or /^[@_]/ =~ l
diff --git a/win32/win32.c b/win32/win32.c
index 537793ef73..1d36c37b5d 100644
--- a/win32/win32.c
+++ b/win32/win32.c
@@ -2317,6 +2317,21 @@ typedef struct {
#endif
/* License: Ruby's */
+#if RUBY_MSVCRT_VERSION >= 140
+typedef struct {
+ CRITICAL_SECTION lock;
+ intptr_t osfhnd; // underlying OS file HANDLE
+ __int64 startpos; // File position that matches buffer start
+ unsigned char osfile; // Attributes of file (e.g., open in text mode?)
+ char textmode;
+ char _pipe_lookahead;
+
+ uint8_t unicode : 1; // Was the file opened as unicode?
+ uint8_t utf8translations : 1; // Buffer contains translations other than CRLF
+ uint8_t dbcsBufferUsed : 1; // Is the dbcsBuffer in use?
+ char dbcsBuffer; // Buffer for the lead byte of DBCS when converting from DBCS to Unicode
+} ioinfo;
+#else
typedef struct {
intptr_t osfhnd; /* underlying OS file HANDLE */
char osfile; /* attributes of file (e.g., open in text mode?) */
@@ -2328,16 +2343,22 @@ typedef struct {
char pipech2[2];
#endif
} ioinfo;
+#endif
#if !defined _CRTIMP || defined __MINGW32__
#undef _CRTIMP
#define _CRTIMP __declspec(dllimport)
#endif
+#if RUBY_MSVCRT_VERSION >= 140
+static ioinfo ** __pioinfo = NULL;
+#define IOINFO_L2E 6
+#else
EXTERN_C _CRTIMP ioinfo * __pioinfo[];
+#define IOINFO_L2E 5
+#endif
static inline ioinfo* _pioinfo(int);
-#define IOINFO_L2E 5
#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
#define _osfhnd(i) (_pioinfo(i)->osfhnd)
#define _osfile(i) (_pioinfo(i)->osfile)
@@ -2352,6 +2373,39 @@ static size_t pioinfo_extra = 0; /* workaround for VC++8 SP1 */
static void
set_pioinfo_extra(void)
{
+#if RUBY_MSVCRT_VERSION >= 140
+ /* get __pioinfo addr with _isatty */
+ HMODULE mod = GetModuleHandle("ucrtbase.dll");
+ char *p = (char*)GetProcAddress(mod, "_isatty");
+ char *pend = p + 100;
+ /* _osfile(fh) & FDEV /*0x40*/
+#if _WIN64
+ int32_t rel;
+ char *rip;
+ /* lea rdx,[__pioinfo's addr in RIP-relative 32bit addr] */
+# define PIOINFO_MARK "\x48\x8d\x15"
+#else
+ /* mov eax,dword ptr [eax*4+100EB430h] */
+# define PIOINFO_MARK "\x8B\x04\x85"
+#endif
+ for (p; p < pend; p++) {
+ if (memcmp(p, PIOINFO_MARK, strlen(PIOINFO_MARK)) == 0) {
+ goto found;
+ }
+ }
+ fprintf(stderr, "unexpected ucrtbase.dll\n");
+ _exit(1);
+
+ found:
+ p += strlen(PIOINFO_MARK);
+#if _WIN64
+ rel = *(int32_t*)(p);
+ rip = p + sizeof(int32_t);
+ __pioinfo = (ioinfo**)(rip + rel);
+#else
+ __pioinfo = (ioinfo**)(p);
+#endif
+#else
int fd;
fd = _open("NUL", O_RDONLY);
@@ -2366,6 +2420,7 @@ set_pioinfo_extra(void)
/* not found, maybe something wrong... */
pioinfo_extra = 0;
}
+#endif
}
#else
#define pioinfo_extra 0