summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/Make_cyg_ming.mak9
-rw-r--r--src/Make_mvc.mak13
-rw-r--r--src/if_python3.c22
-rw-r--r--src/os_win32.c70
-rw-r--r--src/proto/os_win32.pro1
-rw-r--r--src/version.c2
6 files changed, 102 insertions, 15 deletions
diff --git a/src/Make_cyg_ming.mak b/src/Make_cyg_ming.mak
index e4fe0be8fb..98c86a6e77 100644
--- a/src/Make_cyg_ming.mak
+++ b/src/Make_cyg_ming.mak
@@ -395,15 +395,20 @@ DYNAMIC_PYTHON3=yes
ifndef PYTHON3_VER
PYTHON3_VER=36
endif
+ ifeq ($(DYNAMIC_PYTHON3_STABLE_ABI),yes)
+PYTHON3_NAME=python3
+ else
+PYTHON3_NAME=python$(PYTHON3_VER)
+ endif
ifndef DYNAMIC_PYTHON3_DLL
-DYNAMIC_PYTHON3_DLL=python$(PYTHON3_VER).dll
+DYNAMIC_PYTHON3_DLL=$(PYTHON3_NAME).dll
endif
ifdef PYTHON3_HOME
PYTHON3_HOME_DEF=-DPYTHON3_HOME=L\"$(PYTHON3_HOME)\"
endif
ifeq (no,$(DYNAMIC_PYTHON3))
-PYTHON3LIB=-L$(PYTHON3)/libs -lpython$(PYTHON3_VER)
+PYTHON3LIB=-L$(PYTHON3)/libs -l$(PYTHON3_NAME)
endif
ifndef PYTHON3INC
diff --git a/src/Make_mvc.mak b/src/Make_mvc.mak
index e1d42fdcb9..618821d690 100644
--- a/src/Make_mvc.mak
+++ b/src/Make_mvc.mak
@@ -937,8 +937,13 @@ PYTHON_LIB = "$(PYTHON)\libs\python$(PYTHON_VER).lib"
! ifndef PYTHON3_VER
PYTHON3_VER = 36
! endif
+! if "$(DYNAMIC_PYTHON3_STABLE_ABI)" == "yes"
+PYTHON3_NAME = python3
+! else
+PYTHON3_NAME = python$(PYTHON3_VER)
+! endif
! ifndef DYNAMIC_PYTHON3_DLL
-DYNAMIC_PYTHON3_DLL = python$(PYTHON3_VER).dll
+DYNAMIC_PYTHON3_DLL = $(PYTHON3_NAME).dll
! endif
! message Python3 requested (version $(PYTHON3_VER)) - root dir is "$(PYTHON3)"
! if "$(DYNAMIC_PYTHON3)" == "yes"
@@ -953,13 +958,11 @@ CFLAGS = $(CFLAGS) -DDYNAMIC_PYTHON3 \
! if "$(DYNAMIC_PYTHON3_STABLE_ABI)" == "yes"
CFLAGS = $(CFLAGS) -DDYNAMIC_PYTHON3_STABLE_ABI
PYTHON3_INC = $(PYTHON3_INC) -DPy_LIMITED_API=0x3080000
-PYTHON3_LIB = /nodefaultlib:python3.lib
-! else
-PYTHON3_LIB = /nodefaultlib:python$(PYTHON3_VER).lib
! endif
+PYTHON3_LIB = /nodefaultlib:$(PYTHON3_NAME).lib
! else
CFLAGS = $(CFLAGS) -DPYTHON3_DLL=\"$(DYNAMIC_PYTHON3_DLL)\"
-PYTHON3_LIB = "$(PYTHON3)\libs\python$(PYTHON3_VER).lib"
+PYTHON3_LIB = "$(PYTHON3)\libs\$(PYTHON3_NAME).lib"
! endif
!endif
diff --git a/src/if_python3.c b/src/if_python3.c
index 2e116620ec..bbbebc39f1 100644
--- a/src/if_python3.c
+++ b/src/if_python3.c
@@ -242,7 +242,7 @@ static HINSTANCE hinstPy3 = 0; // Instance of python.dll
# if PY_VERSION_HEX >= 0x03040000
# define PyType_GetFlags py3_PyType_GetFlags
# endif
-#undef Py_BuildValue
+# undef Py_BuildValue
# define Py_BuildValue py3_Py_BuildValue
# define Py_SetPythonHome py3_Py_SetPythonHome
# define Py_Initialize py3_Py_Initialize
@@ -251,7 +251,9 @@ static HINSTANCE hinstPy3 = 0; // Instance of python.dll
# define _Py_NoneStruct (*py3__Py_NoneStruct)
# define _Py_FalseStruct (*py3__Py_FalseStruct)
# define _Py_TrueStruct (*py3__Py_TrueStruct)
-# define _PyObject_NextNotImplemented (*py3__PyObject_NextNotImplemented)
+# ifndef USE_LIMITED_API
+# define _PyObject_NextNotImplemented (*py3__PyObject_NextNotImplemented)
+# endif
# define PyModule_AddObject py3_PyModule_AddObject
# define PyImport_AppendInittab py3_PyImport_AppendInittab
# define PyImport_AddModule py3_PyImport_AddModule
@@ -288,7 +290,9 @@ static HINSTANCE hinstPy3 = 0; // Instance of python.dll
# define PyFloat_AsDouble py3_PyFloat_AsDouble
# define PyObject_GenericGetAttr py3_PyObject_GenericGetAttr
# define PyType_Type (*py3_PyType_Type)
-# define PyStdPrinter_Type (*py3_PyStdPrinter_Type)
+# ifndef USE_LIMITED_API
+# define PyStdPrinter_Type (*py3_PyStdPrinter_Type)
+# endif
# define PySlice_Type (*py3_PySlice_Type)
# define PyFloat_Type (*py3_PyFloat_Type)
# define PyNumber_Check (*py3_PyNumber_Check)
@@ -449,7 +453,9 @@ static void (*py3_PyErr_Clear)(void);
static PyObject* (*py3_PyErr_Format)(PyObject *, const char *, ...);
static void (*py3_PyErr_PrintEx)(int);
static PyObject*(*py3__PyObject_Init)(PyObject *, PyTypeObject *);
+# ifndef USE_LIMITED_API
static iternextfunc py3__PyObject_NextNotImplemented;
+# endif
static PyObject* py3__Py_NoneStruct;
static PyObject* py3__Py_FalseStruct;
static PyObject* py3__Py_TrueStruct;
@@ -485,7 +491,9 @@ static PyObject* (*py3_PyObject_GenericGetAttr)(PyObject *obj, PyObject *name);
static PyObject* (*py3_PyType_GenericAlloc)(PyTypeObject *type, Py_ssize_t nitems);
static PyObject* (*py3_PyType_GenericNew)(PyTypeObject *type, PyObject *args, PyObject *kwds);
static PyTypeObject* py3_PyType_Type;
+# ifndef USE_LIMITED_API
static PyTypeObject* py3_PyStdPrinter_Type;
+# endif
static PyTypeObject* py3_PySlice_Type;
static PyTypeObject* py3_PyFloat_Type;
PyTypeObject* py3_PyBool_Type;
@@ -633,7 +641,9 @@ static struct
{"PyEval_SaveThread", (PYTHON_PROC*)&py3_PyEval_SaveThread},
{"_PyArg_Parse_SizeT", (PYTHON_PROC*)&py3_PyArg_Parse},
{"Py_IsInitialized", (PYTHON_PROC*)&py3_Py_IsInitialized},
+# ifndef USE_LIMITED_API
{"_PyObject_NextNotImplemented", (PYTHON_PROC*)&py3__PyObject_NextNotImplemented},
+# endif
{"_Py_NoneStruct", (PYTHON_PROC*)&py3__Py_NoneStruct},
{"_Py_FalseStruct", (PYTHON_PROC*)&py3__Py_FalseStruct},
{"_Py_TrueStruct", (PYTHON_PROC*)&py3__Py_TrueStruct},
@@ -681,7 +691,9 @@ static struct
{"PyType_GenericAlloc", (PYTHON_PROC*)&py3_PyType_GenericAlloc},
{"PyType_GenericNew", (PYTHON_PROC*)&py3_PyType_GenericNew},
{"PyType_Type", (PYTHON_PROC*)&py3_PyType_Type},
+# ifndef USE_LIMITED_API
{"PyStdPrinter_Type", (PYTHON_PROC*)&py3_PyStdPrinter_Type},
+# endif
{"PySlice_Type", (PYTHON_PROC*)&py3_PySlice_Type},
{"PyFloat_Type", (PYTHON_PROC*)&py3_PyFloat_Type},
# if PY_VERSION_HEX < 0x030c00b0
@@ -1167,7 +1179,7 @@ reset_stdin(void)
{
FILE *(*py__acrt_iob_func)(unsigned) = NULL;
FILE *(*pyfreopen)(const char *, const char *, FILE *) = NULL;
- HINSTANCE hinst = hinstPy3;
+ HINSTANCE hinst = get_forwarded_dll(hinstPy3);
if (hinst == NULL || is_stdin_readable())
return;
@@ -1219,7 +1231,7 @@ hooked_exit(int ret)
static void
hook_py_exit(void)
{
- HINSTANCE hinst = hinstPy3;
+ HINSTANCE hinst = get_forwarded_dll(hinstPy3);
if (hinst == NULL || orig_exit != NULL)
return;
diff --git a/src/os_win32.c b/src/os_win32.c
index 7891944dab..92bc8c157f 100644
--- a/src/os_win32.c
+++ b/src/os_win32.c
@@ -626,15 +626,20 @@ get_imported_func_info(HINSTANCE hInst, const char *funcname, int info,
PIMAGE_THUNK_DATA pIAT; // Import Address Table
PIMAGE_THUNK_DATA pINT; // Import Name Table
PIMAGE_IMPORT_BY_NAME pImpName;
+ DWORD ImpVA;
if (pDOS->e_magic != IMAGE_DOS_SIGNATURE)
return NULL;
pPE = (PIMAGE_NT_HEADERS)(pImage + pDOS->e_lfanew);
if (pPE->Signature != IMAGE_NT_SIGNATURE)
return NULL;
- pImpDesc = (PIMAGE_IMPORT_DESCRIPTOR)(pImage
- + pPE->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]
- .VirtualAddress);
+
+ ImpVA = pPE->OptionalHeader
+ .DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
+ if (ImpVA == 0)
+ return NULL; // No Import Table
+ pImpDesc = (PIMAGE_IMPORT_DESCRIPTOR)(pImage + ImpVA);
+
for (; pImpDesc->FirstThunk; ++pImpDesc)
{
if (!pImpDesc->OriginalFirstThunk)
@@ -709,6 +714,65 @@ hook_dll_import_func(HINSTANCE hInst, const char *funcname, const void *hook)
}
#endif
+#if defined(FEAT_PYTHON3) || defined(PROTO)
+/*
+ * Check if the specified DLL is a function forwarder.
+ * If yes, return the instance of the forwarded DLL.
+ * If no, return the specified DLL.
+ * If error, return NULL.
+ * This assumes that the DLL forwards all the function to a single DLL.
+ */
+ HINSTANCE
+get_forwarded_dll(HINSTANCE hInst)
+{
+ PBYTE pImage = (PBYTE)hInst;
+ PIMAGE_DOS_HEADER pDOS = (PIMAGE_DOS_HEADER)hInst;
+ PIMAGE_NT_HEADERS pPE;
+ PIMAGE_EXPORT_DIRECTORY pExpDir;
+ DWORD ExpVA;
+ DWORD ExpSize;
+ LPDWORD pFunctionTable;
+
+ if (pDOS->e_magic != IMAGE_DOS_SIGNATURE)
+ return NULL;
+ pPE = (PIMAGE_NT_HEADERS)(pImage + pDOS->e_lfanew);
+ if (pPE->Signature != IMAGE_NT_SIGNATURE)
+ return NULL;
+
+ ExpVA = pPE->OptionalHeader
+ .DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
+ ExpSize = pPE->OptionalHeader
+ .DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size;
+ if (ExpVA == 0)
+ return hInst; // No Export Directory
+ pExpDir = (PIMAGE_EXPORT_DIRECTORY)(pImage + ExpVA);
+ pFunctionTable = (LPDWORD)(pImage + pExpDir->AddressOfFunctions);
+
+ if (pExpDir->NumberOfNames == 0)
+ return hInst; // No export names.
+
+ // Check only the first entry.
+ if ((pFunctionTable[0] < ExpVA) || (pFunctionTable[0] >= ExpVA + ExpSize))
+ // The first entry is not a function forwarder.
+ return hInst;
+
+ // The first entry is a function forwarder.
+ // The name is represented as "DllName.FunctionName".
+ const char *name = (const char *)(pImage + pFunctionTable[0]);
+ const char *p = strchr(name, '.');
+ if (p == NULL)
+ return hInst;
+
+ // Extract DllName.
+ char buf[MAX_PATH];
+ if (p - name + 1 > sizeof(buf))
+ return NULL;
+ strncpy(buf, name, p - name);
+ buf[p - name] = '\0';
+ return GetModuleHandleA(buf);
+}
+#endif
+
#if defined(DYNAMIC_GETTEXT) || defined(PROTO)
# ifndef GETTEXT_DLL
# define GETTEXT_DLL "libintl.dll"
diff --git a/src/proto/os_win32.pro b/src/proto/os_win32.pro
index 7ea5388487..cb84585311 100644
--- a/src/proto/os_win32.pro
+++ b/src/proto/os_win32.pro
@@ -5,6 +5,7 @@ int mch_is_gui_executable(void);
HINSTANCE find_imported_module_by_funcname(HINSTANCE hInst, const char *funcname);
void *get_dll_import_func(HINSTANCE hInst, const char *funcname);
void *hook_dll_import_func(HINSTANCE hInst, const char *funcname, const void *hook);
+HINSTANCE get_forwarded_dll(HINSTANCE hInst);
int dyn_libintl_init(void);
void dyn_libintl_end(void);
void PlatformId(void);
diff --git a/src/version.c b/src/version.c
index ba461ba11f..d7b3c9bd33 100644
--- a/src/version.c
+++ b/src/version.c
@@ -705,6 +705,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 1980,
+/**/
1979,
/**/
1978,