[前][次][番号順一覧][スレッド一覧]

ruby-changes:43720

From: usa <ko1@a...>
Date: Tue, 2 Aug 2016 04:12:44 +0900 (JST)
Subject: [ruby-changes:43720] usa:r55792 (trunk): * win32/win32.c (set_pioinfo_extra): use more reliable way to search

usa	2016-08-02 04:12:28 +0900 (Tue, 02 Aug 2016)

  New Revision: 55792

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=55792

  Log:
    * win32/win32.c (set_pioinfo_extra): use more reliable way to search
      the position of pioinfo of VC14, and also support debug library of it.
      patched by davispuh AT gmail.com
      [ruby-core:76644] [Bug #12644]
      this fixes also [Bug #12631]

  Modified files:
    trunk/ChangeLog
    trunk/win32/win32.c
Index: win32/win32.c
===================================================================
--- win32/win32.c	(revision 55791)
+++ win32/win32.c	(revision 55792)
@@ -2312,13 +2312,16 @@ typedef struct { https://github.com/ruby/ruby/blob/trunk/win32/win32.c#L2312
 
 /* License: Ruby's */
 #if RUBY_MSVCRT_VERSION >= 140
+typedef char lowio_text_mode;
+typedef char lowio_pipe_lookahead[3];
+
 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;
+    lowio_text_mode            textmode;
+    lowio_pipe_lookahead       _pipe_lookahead;
 
     uint8_t unicode          : 1; // Was the file opened as unicode?
     uint8_t utf8translations : 1; // Buffer contains translations other than CRLF
@@ -2356,7 +2359,6 @@ static inline ioinfo* _pioinfo(int); https://github.com/ruby/ruby/blob/trunk/win32/win32.c#L2359
 #define IOINFO_ARRAY_ELTS	(1 << IOINFO_L2E)
 #define _osfhnd(i)  (_pioinfo(i)->osfhnd)
 #define _osfile(i)  (_pioinfo(i)->osfile)
-#define _pipech(i)  (_pioinfo(i)->pipech)
 #define rb_acrt_lowio_lock_fh(i)   EnterCriticalSection(&_pioinfo(i)->lock)
 #define rb_acrt_lowio_unlock_fh(i) LeaveCriticalSection(&_pioinfo(i)->lock)
 
@@ -2368,35 +2370,65 @@ static void https://github.com/ruby/ruby/blob/trunk/win32/win32.c#L2370
 set_pioinfo_extra(void)
 {
 #if RUBY_MSVCRT_VERSION >= 140
+# define FUNCTION_RET 0xc3 /* ret */
+# ifdef _DEBUG
+#  define UCRTBASE "ucrtbased.dll"
+# else
+#  define UCRTBASE "ucrtbase.dll"
+# endif
     /* get __pioinfo addr with _isatty */
-    char *p = (char*)get_proc_address("ucrtbase.dll", "_isatty", NULL);
-    char *pend = p + 100;
+    char *p = (char*)get_proc_address(UCRTBASE, "_isatty", NULL);
+    char *pend = p;
     /* _osfile(fh) & FDEV */
-#if _WIN64
+
+# if _WIN64
     int32_t rel;
     char *rip;
+    /* add rsp, _ */
+#  define FUNCTION_BEFORE_RET_MARK "\x48\x83\xc4"
+#  define FUNCTION_SKIP_BYTES 1
+#  ifdef _DEBUG
+    /* lea rcx,[__pioinfo's addr in RIP-relative 32bit addr] */
+#   define PIOINFO_MARK "\x48\x8d\x0d"
+#  else
     /* lea rdx,[__pioinfo's addr in RIP-relative 32bit addr] */
-# define PIOINFO_MARK "\x48\x8d\x15"
-#else
+#   define PIOINFO_MARK "\x48\x8d\x15"
+#  endif
+
+# else /* x86 */
+    /* pop ebp */
+#  define FUNCTION_BEFORE_RET_MARK "\x5d"
+#  define FUNCTION_SKIP_BYTES 0
     /* 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;
+#  define PIOINFO_MARK "\x8B\x04\x85"
+# endif
+    if (p) {
+        for (pend += 10; pend < p + 300; pend++) {
+            // find end of function
+            if (memcmp(pend, FUNCTION_BEFORE_RET_MARK, sizeof(FUNCTION_BEFORE_RET_MARK) - 1) == 0 &&
+                *(pend + (sizeof(FUNCTION_BEFORE_RET_MARK) - 1) + FUNCTION_SKIP_BYTES) & FUNCTION_RET == FUNCTION_RET) {
+                // search backwards from end of function
+                for (pend -= (sizeof(PIOINFO_MARK) - 1); pend > p; pend--) {
+                    if (memcmp(pend, PIOINFO_MARK, sizeof(PIOINFO_MARK) - 1) == 0) {
+                        p = pend;
+                        goto found;
+                    }
+                }
+                break;
+            }
         }
     }
-    fprintf(stderr, "unexpected ucrtbase.dll\n");
+    fprintf(stderr, "unexpected " UCRTBASE "\n");
     _exit(1);
 
     found:
-    p += strlen(PIOINFO_MARK);
+    p += sizeof(PIOINFO_MARK) - 1;
 #if _WIN64
     rel = *(int32_t*)(p);
     rip = p + sizeof(int32_t);
     __pioinfo = (ioinfo**)(rip + rel);
 #else
-    __pioinfo = (ioinfo**)(p);
+    __pioinfo = *(ioinfo***)(p);
 #endif
 #else
     int fd;
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 55791)
+++ ChangeLog	(revision 55792)
@@ -1,3 +1,11 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Tue Aug  2 04:07:29 2016  NAKAMURA Usaku  <usa@r...>
+
+	* win32/win32.c (set_pioinfo_extra): use more reliable way to search
+	  the position of pioinfo of VC14, and also support debug library of it.
+	  patched by davispuh AT gmail.com
+	  [ruby-core:76644] [Bug #12644]
+	  this fixes also [Bug #12631]
+
 Mon Aug  1 21:39:52 2016  Nobuyoshi Nakada  <nobu@r...>
 
 	* ext/extmk.rb: [EXPERIMENTAL] build extension libraries in

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]