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

ruby-changes:15878

From: nobu <ko1@a...>
Date: Sun, 16 May 2010 15:12:08 +0900 (JST)
Subject: [ruby-changes:15878] Ruby:r27816 (trunk): * dln.c (rb_w32_check_imported): check if extension library to be

nobu	2010-05-16 15:09:40 +0900 (Sun, 16 May 2010)

  New Revision: 27816

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=27816

  Log:
    * dln.c (rb_w32_check_imported): check if extension library to be
      loaded imports from different ruby dll.

  Modified files:
    trunk/ChangeLog
    trunk/configure.in
    trunk/dln.c
    trunk/win32/Makefile.sub

Index: configure.in
===================================================================
--- configure.in	(revision 27815)
+++ configure.in	(revision 27816)
@@ -874,7 +874,7 @@
 [cygwin*], [	ac_cv_header_langinfo_h=yes
 		AC_LIBOBJ([langinfo])
 		],
-[mingw*], [	LIBS="-lshell32 -lws2_32 $LIBS"
+[mingw*], [	LIBS="-lshell32 -lws2_32 -limagehlp $LIBS"
 		ac_cv_header_a_out_h=no
 		ac_cv_header_pwd_h=no
 		ac_cv_header_utime_h=no
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 27815)
+++ ChangeLog	(revision 27816)
@@ -1,3 +1,8 @@
+Sun May 16 15:09:36 2010  Nobuyoshi Nakada  <nobu@r...>
+
+	* dln.c (rb_w32_check_imported): check if extension library to be
+	  loaded imports from different ruby dll.
+
 Sun May 16 14:55:39 2010  Nobuyoshi Nakada  <nobu@r...>
 
 	* common.mk (dln_find.o): fix dependency.
Index: win32/Makefile.sub
===================================================================
--- win32/Makefile.sub	(revision 27815)
+++ win32/Makefile.sub	(revision 27816)
@@ -212,7 +212,7 @@
 EXTLIBS =
 !endif
 !if !defined(LIBS)
-LIBS = oldnames.lib user32.lib advapi32.lib shell32.lib ws2_32.lib $(EXTLIBS)
+LIBS = oldnames.lib user32.lib advapi32.lib shell32.lib ws2_32.lib imagehlp.lib $(EXTLIBS)
 !endif
 !if "$(ENABLE_WIN95)" == "yes"
 LIBS = unicows.lib $(LIBS)
Index: dln.c
===================================================================
--- dln.c	(revision 27815)
+++ dln.c	(revision 27816)
@@ -1116,10 +1116,30 @@
 
 #if defined _WIN32 && !defined __CYGWIN__
 #include <windows.h>
+#include <imagehlp.h>
 #endif
 
-#if ! defined _AIX
+#if defined _WIN32 && !defined __CYGWIN__
 static const char *
+dln_strerror(char *message, size_t size)
+{
+    int error = GetLastError();
+    char *p = message;
+    size_t len = snprintf(message, size, "%d: ", error);
+
+    FormatMessage(
+	FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
+	NULL, error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+	message + len, size - len, NULL);
+    for (p = message + len; *p; p++) {
+	if (*p == '\n' || *p == '\r')
+	    *p = ' ';
+    }
+    return message;
+}
+#define dln_strerror() dln_strerror(message, sizeof message)
+#elif ! defined _AIX
+static const char *
 dln_strerror(void)
 {
 #ifdef USE_DLN_A_OUT
@@ -1146,27 +1166,6 @@
 #ifdef USE_DLN_DLOPEN
     return (char*)dlerror();
 #endif
-
-#if defined _WIN32 && !defined __CYGWIN__
-    static char message[1024];
-    int error = GetLastError();
-    char *p = message;
-    p += sprintf(message, "%d: ", error);
-    FormatMessage(
-	FORMAT_MESSAGE_FROM_SYSTEM	 | FORMAT_MESSAGE_IGNORE_INSERTS,
-	NULL,
-	error,
-	MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
-	p,
-	sizeof message - strlen(message),
-	NULL);
-
-    for (p = message; *p; p++) {
-	if (*p == '\n' || *p == '\r')
-	    *p = ' ';
-    }
-    return message;
-#endif
 }
 #endif
 
@@ -1196,6 +1195,36 @@
 }
 #endif
 
+#if defined _WIN32 && defined RUBY_EXPORT
+HANDLE rb_libruby_handle(void);
+
+static int
+rb_w32_check_imported(HMODULE ext, HMODULE mine)
+{
+    ULONG size;
+    const IMAGE_IMPORT_DESCRIPTOR *desc;
+
+    desc = ImageDirectoryEntryToData(ext, TRUE, IMAGE_DIRECTORY_ENTRY_IMPORT, &size);
+    if (!desc) return 0;
+    while (desc->Name) {
+	PIMAGE_THUNK_DATA pint = (PIMAGE_THUNK_DATA)((char *)ext + desc->Characteristics);
+	PIMAGE_THUNK_DATA piat = (PIMAGE_THUNK_DATA)((char *)ext + desc->FirstThunk);
+	while (piat->u1.Function) {
+	    PIMAGE_IMPORT_BY_NAME pii = (PIMAGE_IMPORT_BY_NAME)((char *)ext + pint->u1.AddressOfData);
+	    static const char prefix[] = "rb_";
+	    if (strncmp(pii->Name, prefix, sizeof(prefix) - 1) == 0) {
+		FARPROC addr = GetProcAddress(mine, pii->Name);
+		if (addr) return (FARPROC)piat->u1.Function == addr;
+	    }
+	    piat++;
+	    pint++;
+	}
+	desc++;
+    }
+    return 1;
+}
+#endif
+
 #if defined(DLN_NEEDS_ALT_SEPARATOR) && DLN_NEEDS_ALT_SEPARATOR
 #define translit_separator(src) do { \
 	char *tmp = ALLOCA_N(char, strlen(src) + 1), *p = tmp, c; \
@@ -1219,6 +1248,7 @@
 #if defined _WIN32 && !defined __CYGWIN__
     HINSTANCE handle;
     char winfile[MAXPATHLEN];
+    char message[1024];
     void (*init_fct)();
     char *buf;
 
@@ -1235,6 +1265,12 @@
 	goto failed;
     }
 
+    if (!rb_w32_check_imported(handle, rb_libruby_handle())) {
+	FreeLibrary(handle);
+	error = "incompatible library version";
+	goto failed;
+    }
+
     if ((init_fct = (void(*)())GetProcAddress(handle, buf)) == NULL) {
 	dln_loaderror("%s - %s\n%s", dln_strerror(), buf, file);
     }

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

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