mirror of
https://github.com/microsoft/mimalloc.git
synced 2025-05-04 22:49:32 +03:00
fix dynamic override when both msvcrt and ucrtbase are loaded in any order using priorities
This commit is contained in:
parent
9390642879
commit
7b4f3591f0
1 changed files with 15 additions and 10 deletions
|
@ -377,6 +377,7 @@ typedef enum patch_apply_e {
|
||||||
|
|
||||||
typedef struct mi_patch_s {
|
typedef struct mi_patch_s {
|
||||||
const char* name; // name of the function to patch
|
const char* name; // name of the function to patch
|
||||||
|
int priority; // priority to patch this one (used to prioritize over multiple entries in various dll's)
|
||||||
void* original; // the resolved address of the function (or NULL)
|
void* original; // the resolved address of the function (or NULL)
|
||||||
void* target; // the address of the new target (never NULL)
|
void* target; // the address of the new target (never NULL)
|
||||||
void* target_term;// the address of the target during termination (or NULL)
|
void* target_term;// the address of the target during termination (or NULL)
|
||||||
|
@ -384,8 +385,8 @@ typedef struct mi_patch_s {
|
||||||
mi_jump_t save; // the saved instructions in case it was applied
|
mi_jump_t save; // the saved instructions in case it was applied
|
||||||
} mi_patch_t;
|
} mi_patch_t;
|
||||||
|
|
||||||
#define MI_PATCH_NAME3(name,target,term) { name, NULL, &target, &term, false }
|
#define MI_PATCH_NAME3(name,target,term) { name, 0, NULL, &target, &term, PATCH_NONE }
|
||||||
#define MI_PATCH_NAME2(name,target) { name, NULL, &target, NULL, false }
|
#define MI_PATCH_NAME2(name,target) { name, 0, NULL, &target, NULL, PATCH_NONE }
|
||||||
#define MI_PATCH3(name,target,term) MI_PATCH_NAME3(#name, target, term)
|
#define MI_PATCH3(name,target,term) MI_PATCH_NAME3(#name, target, term)
|
||||||
#define MI_PATCH2(name,target) MI_PATCH_NAME2(#name, target)
|
#define MI_PATCH2(name,target) MI_PATCH_NAME2(#name, target)
|
||||||
#define MI_PATCH1(name) MI_PATCH2(name,mi_##name)
|
#define MI_PATCH1(name) MI_PATCH2(name,mi_##name)
|
||||||
|
@ -447,7 +448,7 @@ static mi_patch_t patches[] = {
|
||||||
MI_PATCH_NAME3("??_V@YAXPAXABUnothrow_t@std@@@Z", mi_free, mi_free_term),
|
MI_PATCH_NAME3("??_V@YAXPAXABUnothrow_t@std@@@Z", mi_free, mi_free_term),
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
{ NULL, NULL, NULL, false }
|
{ NULL, 0, NULL, NULL, NULL, PATCH_NONE }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -522,15 +523,16 @@ static int __cdecl mi_setmaxstdio(int newmax) {
|
||||||
// ------------------------------------------------------
|
// ------------------------------------------------------
|
||||||
|
|
||||||
// Try to resolve patches for a given module (DLL)
|
// Try to resolve patches for a given module (DLL)
|
||||||
static void mi_module_resolve(HMODULE mod) {
|
static void mi_module_resolve(HMODULE mod, int priority) {
|
||||||
// see if any patches apply
|
// see if any patches apply
|
||||||
for (size_t i = 0; patches[i].name != NULL; i++) {
|
for (size_t i = 0; patches[i].name != NULL; i++) {
|
||||||
mi_patch_t* patch = &patches[i];
|
mi_patch_t* patch = &patches[i];
|
||||||
if (!patch->applied && patch->original==NULL) { // we apply only the first found dll
|
if (!patch->applied && patch->priority < priority) {
|
||||||
void* addr = GetProcAddress(mod, patch->name);
|
void* addr = GetProcAddress(mod, patch->name);
|
||||||
if (addr != NULL) {
|
if (addr != NULL) {
|
||||||
// found it! set the address
|
// found it! set the address
|
||||||
patch->original = addr;
|
patch->original = addr;
|
||||||
|
patch->priority = priority;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -566,16 +568,19 @@ static bool mi_patches_resolve(void) {
|
||||||
filename[slen] = 0;
|
filename[slen] = 0;
|
||||||
const char* lastsep = strrchr(filename, '\\');
|
const char* lastsep = strrchr(filename, '\\');
|
||||||
const char* basename = (lastsep==NULL ? filename : lastsep+1);
|
const char* basename = (lastsep==NULL ? filename : lastsep+1);
|
||||||
if (i==0 // main module to allow static crt linking
|
|
||||||
|| _strnicmp(basename, "ucrt", 4) == 0 // new ucrtbase.dll in windows 10
|
int priority = 0;
|
||||||
|| _strnicmp(basename, "msvcr", 5) == 0) // older runtimes
|
if (i == 0) priority = 2; // main module to allow static crt linking
|
||||||
{
|
else if (_strnicmp(basename, "ucrt", 4) == 0) priority = 3; // new ucrtbase.dll in windows 10
|
||||||
|
else if (_strnicmp(basename, "msvcr", 5) == 0) priority = 1; // older runtimes
|
||||||
|
|
||||||
|
if (priority > 0) {
|
||||||
// remember indices so we can check load order (in debug mode)
|
// remember indices so we can check load order (in debug mode)
|
||||||
if (_stricmp(basename, MIMALLOC_NAME) == 0) mimalloc_index = i;
|
if (_stricmp(basename, MIMALLOC_NAME) == 0) mimalloc_index = i;
|
||||||
if (_stricmp(basename, UCRTBASE_NAME) == 0) ucrtbase_index = i;
|
if (_stricmp(basename, UCRTBASE_NAME) == 0) ucrtbase_index = i;
|
||||||
|
|
||||||
// probably found a crt module, try to patch it
|
// probably found a crt module, try to patch it
|
||||||
mi_module_resolve(mod);
|
mi_module_resolve(mod,priority);
|
||||||
|
|
||||||
// try to find the atexit functions for the main process (in `ucrtbase.dll`)
|
// try to find the atexit functions for the main process (in `ucrtbase.dll`)
|
||||||
if (crt_atexit==NULL) crt_atexit = (atexit_fun_t*)GetProcAddress(mod, "_crt_atexit");
|
if (crt_atexit==NULL) crt_atexit = (atexit_fun_t*)GetProcAddress(mod, "_crt_atexit");
|
||||||
|
|
Loading…
Add table
Reference in a new issue