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/