From: Thomas H. <th...@us...> - 2005-04-20 12:59:33
|
Update of /cvsroot/py2exe/py2exe/hacks/memimp In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv14275 Modified Files: MemoryModule.h MemoryModule.c Log Message: Enclose the python specific stuff into #ifdef FOR_PYTHON/#endif blocks. Implement binary search in MemoryGetProcAddress - gives a large speedup for modules exporting lots of functions (the wxwindows dll exports about 13000 symbols). Implement MyGetModuleHandle, which operates on normal and on Memory modules. Index: MemoryModule.h =================================================================== RCS file: /cvsroot/py2exe/py2exe/hacks/memimp/MemoryModule.h,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** MemoryModule.h 20 Apr 2005 08:45:04 -0000 1.4 --- MemoryModule.h 20 Apr 2005 12:59:17 -0000 1.5 *************** *** 47,50 **** --- 47,51 ---- HMODULE MyLoadLibrary(char *lpFileName, FINDPROC, void *); FARPROC MyGetProcAddress(HMODULE hModule, LPCSTR lpProcName); + HMODULE MyGetModuleHandle(LPCTSTR lpModuleName); #ifdef __cplusplus Index: MemoryModule.c =================================================================== RCS file: /cvsroot/py2exe/py2exe/hacks/memimp/MemoryModule.c,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** MemoryModule.c 20 Apr 2005 08:45:04 -0000 1.5 --- MemoryModule.c 20 Apr 2005 12:59:18 -0000 1.6 *************** *** 1,5 **** /* * Memory DLL loading code ! * Version 0.0.2 * * Copyright (c) 2004-2005 by Joachim Bauch / ma...@jo... --- 1,5 ---- /* * Memory DLL loading code ! * Version 0.0.2 with additions from Thomas Heller * * Copyright (c) 2004-2005 by Joachim Bauch / ma...@jo... *************** *** 23,26 **** --- 23,28 ---- * Joachim Bauch. All Rights Reserved. * + * Portions Copyright (C) 2005 Thomas Heller. + * */ *************** *** 37,40 **** --- 39,51 ---- #include "MemoryModule.h" + #define FOR_PYTHON // define this to enable special processing for pywintypes and pythoncom + + /******************************************************************/ + + struct NAME_TABLE { + char *name; + DWORD ordinal; + }; + typedef struct tagMEMORYMODULE { PIMAGE_NT_HEADERS headers; *************** *** 44,47 **** --- 55,60 ---- int initialized; + struct NAME_TABLE *name_table; + char *name; int refcount; *************** *** 63,76 **** module->prev = NULL; loaded = module; ! if (0 == strcmp(name, "pywintypes23.dll")) { FARPROC proc; ! proc = MyGetProcAddress(module, "initpywintypes"); proc(); } else if (0 == strcmp(name, "pythoncom23.dll")) { FARPROC proc; ! proc = MyGetProcAddress(module, "initpythoncom"); proc(); } } --- 76,90 ---- module->prev = NULL; loaded = module; ! #ifdef FOR_PYTHON if (0 == strcmp(name, "pywintypes23.dll")) { FARPROC proc; ! proc = MyGetProcAddress((HMODULE)module, "initpywintypes"); proc(); } else if (0 == strcmp(name, "pythoncom23.dll")) { FARPROC proc; ! proc = MyGetProcAddress((HMODULE)module, "initpythoncom"); proc(); } + #endif } *************** *** 86,89 **** --- 100,120 ---- } + HMODULE MyGetModuleHandle(LPCTSTR lpModuleName) + { + MEMORYMODULE *p = loaded; + OutputDebugString(lpModuleName); + while (p) { + // If already loaded, only increment the reference count + if (0 == stricmp(lpModuleName, p->name)) { + OutputDebugString("MyGetModuleHandle -> return MEMORYMODULE"); + return (HMODULE)p; + } + p = p->next; + } + OutputDebugString(lpModuleName); + OutputDebugString("MyGetModuleHandle -> calling GetModuleHandle()"); + return GetModuleHandle(lpModuleName); + } + HMODULE MyLoadLibrary(char *lpFileName, FINDPROC findproc, void *userdata) { *************** *** 423,426 **** --- 454,458 ---- result->refcount = 1; result->name = NULL; + result->name_table = NULL; // XXX: is it correct to commit the complete memory region at once? *************** *** 494,505 **** } FARPROC MemoryGetProcAddress(HMEMORYMODULE module, const char *name) { unsigned char *codeBase = ((PMEMORYMODULE)module)->codeBase; int idx=-1; ! DWORD i, *nameRef; ! WORD *ordinal; PIMAGE_EXPORT_DIRECTORY exports; PIMAGE_DATA_DIRECTORY directory = GET_HEADER_DICTIONARY((PMEMORYMODULE)module, IMAGE_DIRECTORY_ENTRY_EXPORT); if (directory->Size == 0) // no export table found --- 526,581 ---- } + int _compare(const struct NAME_TABLE *p1, const struct NAME_TABLE *p2) + { + return stricmp(p1->name, p2->name); + } + + int _find(const char **name, const struct NAME_TABLE *p) + { + return stricmp(*name, p->name); + } + + struct NAME_TABLE *GetNameTable(PMEMORYMODULE module) + { + unsigned char *codeBase; + PIMAGE_EXPORT_DIRECTORY exports; + PIMAGE_DATA_DIRECTORY directory; + DWORD i, *nameRef; + WORD *ordinal; + struct NAME_TABLE *p, *ptab; + + if (module->name_table) + return module->name_table; + + codeBase = module->codeBase; + directory = GET_HEADER_DICTIONARY(module, IMAGE_DIRECTORY_ENTRY_EXPORT); + exports = (PIMAGE_EXPORT_DIRECTORY)(codeBase + directory->VirtualAddress); + + nameRef = (DWORD *)(codeBase + exports->AddressOfNames); + ordinal = (WORD *)(codeBase + exports->AddressOfNameOrdinals); + + p = ((PMEMORYMODULE)module)->name_table = (struct NAME_TABLE *)malloc(sizeof(struct NAME_TABLE) + * exports->NumberOfNames); + if (p == NULL) + return NULL; + ptab = p; + for (i=0; i<exports->NumberOfNames; ++i) { + p->name = (char *)(codeBase + *nameRef++); + p->ordinal = *ordinal++; + ++p; + } + qsort(ptab, exports->NumberOfNames, sizeof(struct NAME_TABLE), _compare); + return ptab; + } + FARPROC MemoryGetProcAddress(HMEMORYMODULE module, const char *name) { unsigned char *codeBase = ((PMEMORYMODULE)module)->codeBase; int idx=-1; ! struct NAME_TABLE *ptab; ! struct NAME_TABLE *found; PIMAGE_EXPORT_DIRECTORY exports; PIMAGE_DATA_DIRECTORY directory = GET_HEADER_DICTIONARY((PMEMORYMODULE)module, IMAGE_DIRECTORY_ENTRY_EXPORT); + if (directory->Size == 0) // no export table found *************** *** 511,532 **** return NULL; ! // search function name in list of exported names ! nameRef = (DWORD *)(codeBase + exports->AddressOfNames); ! ordinal = (WORD *)(codeBase + exports->AddressOfNameOrdinals); ! ! for (i=0; i<exports->NumberOfNames; i++, nameRef++, ordinal++) ! if (stricmp(name, (const char *)(codeBase + *nameRef)) == 0) ! { ! idx = *ordinal; ! break; ! } ! if (idx == -1) // exported symbol not found return NULL; ! if ((DWORD)idx > exports->NumberOfFunctions) // name <-> ordinal number don't match return NULL; ! // AddressOfFunctions contains the RVAs to the "real" functions return (FARPROC)(codeBase + *(DWORD *)(codeBase + exports->AddressOfFunctions + (idx*4))); --- 587,604 ---- return NULL; ! ptab = GetNameTable((PMEMORYMODULE)module); ! if (ptab == NULL) ! // some failure ! return NULL; ! found = bsearch(&name, ptab, exports->NumberOfNames, sizeof(struct NAME_TABLE), _find); ! if (found == NULL) // exported symbol not found return NULL; ! ! idx = found->ordinal; if ((DWORD)idx > exports->NumberOfFunctions) // name <-> ordinal number don't match return NULL; ! // AddressOfFunctions contains the RVAs to the "real" functions return (FARPROC)(codeBase + *(DWORD *)(codeBase + exports->AddressOfFunctions + (idx*4))); *************** *** 562,565 **** --- 634,640 ---- VirtualFree(module->codeBase, 0, MEM_RELEASE); + if (module->name_table != NULL) + free(module->name_table); + HeapFree(GetProcessHeap(), 0, module); } |