Mark cs_* as thread local to avoid race condition in multithreads

This commit is contained in:
mio 2022-07-03 11:54:21 +08:00
parent 68cc30db66
commit bdab89496e
2 changed files with 37 additions and 27 deletions

43
cs.c
View File

@ -285,27 +285,26 @@ static const uint32_t all_arch = 0
#endif
;
#if defined(CAPSTONE_USE_SYS_DYN_MEM)
#if !defined(CAPSTONE_HAS_OSXKERNEL) && !defined(_KERNEL_MODE)
// default
cs_malloc_t cs_mem_malloc = malloc;
cs_calloc_t cs_mem_calloc = calloc;
cs_realloc_t cs_mem_realloc = realloc;
cs_free_t cs_mem_free = free;
thread_local cs_malloc_t cs_mem_malloc = malloc;
thread_local cs_calloc_t cs_mem_calloc = calloc;
thread_local cs_realloc_t cs_mem_realloc = realloc;
thread_local cs_free_t cs_mem_free = free;
#if defined(_WIN32_WCE)
cs_vsnprintf_t cs_vsnprintf = _vsnprintf;
thread_local cs_vsnprintf_t cs_vsnprintf = _vsnprintf;
#else
cs_vsnprintf_t cs_vsnprintf = vsnprintf;
thread_local cs_vsnprintf_t cs_vsnprintf = vsnprintf;
#endif // defined(_WIN32_WCE)
#elif defined(_KERNEL_MODE)
// Windows driver
cs_malloc_t cs_mem_malloc = cs_winkernel_malloc;
cs_calloc_t cs_mem_calloc = cs_winkernel_calloc;
cs_realloc_t cs_mem_realloc = cs_winkernel_realloc;
cs_free_t cs_mem_free = cs_winkernel_free;
cs_vsnprintf_t cs_vsnprintf = cs_winkernel_vsnprintf;
thread_local cs_malloc_t cs_mem_malloc = cs_winkernel_malloc;
thread_local cs_calloc_t cs_mem_calloc = cs_winkernel_calloc;
thread_local cs_realloc_t cs_mem_realloc = cs_winkernel_realloc;
thread_local cs_free_t cs_mem_free = cs_winkernel_free;
thread_local cs_vsnprintf_t cs_vsnprintf = cs_winkernel_vsnprintf;
#else
// OSX kernel
extern void* kern_os_malloc(size_t size);
@ -317,19 +316,19 @@ static void* cs_kern_os_calloc(size_t num, size_t size)
return kern_os_malloc(num * size); // malloc bzeroes the buffer
}
cs_malloc_t cs_mem_malloc = kern_os_malloc;
cs_calloc_t cs_mem_calloc = cs_kern_os_calloc;
cs_realloc_t cs_mem_realloc = kern_os_realloc;
cs_free_t cs_mem_free = kern_os_free;
cs_vsnprintf_t cs_vsnprintf = vsnprintf;
thread_local cs_malloc_t cs_mem_malloc = kern_os_malloc;
thread_local cs_calloc_t cs_mem_calloc = cs_kern_os_calloc;
thread_local cs_realloc_t cs_mem_realloc = kern_os_realloc;
thread_local cs_free_t cs_mem_free = kern_os_free;
thread_local cs_vsnprintf_t cs_vsnprintf = vsnprintf;
#endif // !defined(CAPSTONE_HAS_OSXKERNEL) && !defined(_KERNEL_MODE)
#else
// User-defined
cs_malloc_t cs_mem_malloc = NULL;
cs_calloc_t cs_mem_calloc = NULL;
cs_realloc_t cs_mem_realloc = NULL;
cs_free_t cs_mem_free = NULL;
cs_vsnprintf_t cs_vsnprintf = NULL;
thread_local cs_malloc_t cs_mem_malloc = NULL;
thread_local cs_calloc_t cs_mem_calloc = NULL;
thread_local cs_realloc_t cs_mem_realloc = NULL;
thread_local cs_free_t cs_mem_free = NULL;
thread_local cs_vsnprintf_t cs_vsnprintf = NULL;
#endif // defined(CAPSTONE_USE_SYS_DYN_MEM)

View File

@ -83,11 +83,22 @@ struct cs_struct {
// Returns a bool (0 or 1) whether big endian is enabled for a mode
#define MODE_IS_BIG_ENDIAN(mode) (((mode) & CS_MODE_BIG_ENDIAN) != 0)
extern cs_malloc_t cs_mem_malloc;
extern cs_calloc_t cs_mem_calloc;
extern cs_realloc_t cs_mem_realloc;
extern cs_free_t cs_mem_free;
extern cs_vsnprintf_t cs_vsnprintf;
#ifndef thread_local
#if defined (__GNUC__) || defined (__clang__)
#define thread_local __thread // prior to C11
#elif _MSC_VER
#define thread_local __declspec( thread ) // early msvc
#else
#define thread_local // failsafe
#endif
#endif
extern thread_local cs_malloc_t cs_mem_malloc;
extern thread_local cs_calloc_t cs_mem_calloc;
extern thread_local cs_realloc_t cs_mem_realloc;
extern thread_local cs_free_t cs_mem_free;
extern thread_local cs_vsnprintf_t cs_vsnprintf;
// By defining CAPSTONE_DEBUG assertions can be used.
// For any release build CAPSTONE_DEBUG has to be undefined.