/** * Copyright (C) Mellanox Technologies Ltd. 2001-2017. ALL RIGHTS RESERVED. * * See file LICENSE for terms. */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include #include #include #include #include #include #include #include #include #include #include #ifndef MAP_FAILED #define MAP_FAILED ((void*)-1) #endif #ifdef PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP pthread_mutex_t ucm_reloc_get_orig_lock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; #else pthread_mutex_t ucm_reloc_get_orig_lock; static void ucm_reloc_get_orig_lock_init(void) __attribute__((constructor(101))); static void ucm_reloc_get_orig_lock_init(void) { pthread_mutexattr_t attr; pthread_mutexattr_init(&attr); pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); pthread_mutex_init(&ucm_reloc_get_orig_lock, &attr); } #endif pthread_t volatile ucm_reloc_get_orig_thread = (pthread_t)-1; UCM_DEFINE_REPLACE_FUNC(mmap, void*, MAP_FAILED, void*, size_t, int, int, int, off_t) UCM_DEFINE_REPLACE_FUNC(munmap, int, -1, void*, size_t) #if HAVE_MREMAP UCM_DEFINE_REPLACE_FUNC(mremap, void*, MAP_FAILED, void*, size_t, size_t, int) #endif UCM_DEFINE_REPLACE_FUNC(shmat, void*, MAP_FAILED, int, const void*, int) UCM_DEFINE_REPLACE_FUNC(shmdt, int, -1, const void*) UCM_DEFINE_REPLACE_FUNC(sbrk, void*, MAP_FAILED, intptr_t) UCM_DEFINE_REPLACE_FUNC(brk, int, -1, void*) UCM_DEFINE_REPLACE_FUNC(madvise, int, -1, void*, size_t, int) UCM_DEFINE_SELECT_FUNC(mmap, void*, MAP_FAILED, SYS_mmap, void*, size_t, int, int, int, off_t) UCM_DEFINE_SELECT_FUNC(munmap, int, -1, SYS_munmap, void*, size_t) #if HAVE_MREMAP UCM_DEFINE_SELECT_FUNC(mremap, void*, MAP_FAILED, SYS_mremap, void*, size_t, size_t, int) #endif UCM_DEFINE_SELECT_FUNC(madvise, int, -1, SYS_madvise, void*, size_t, int) #if UCM_BISTRO_HOOKS #if HAVE_DECL_SYS_SHMAT UCM_DEFINE_SELECT_FUNC(shmat, void*, MAP_FAILED, SYS_shmat, int, const void*, int) #elif HAVE_DECL_SYS_IPC # ifndef IPCOP_shmat # define IPCOP_shmat 21 # endif _UCM_DEFINE_DLSYM_FUNC(shmat, ucm_orig_dlsym_shmat, ucm_override_shmat, void*, MAP_FAILED, int, const void*, int) void *ucm_orig_shmat(int shmid, const void *shmaddr, int shmflg) { unsigned long res; void *addr; if (ucm_mmap_hook_mode() == UCM_MMAP_HOOK_RELOC) { return ucm_orig_dlsym_shmat(shmid, shmaddr, shmflg); } else { /* Using IPC syscall of shmat implementation */ res = syscall(SYS_ipc, IPCOP_shmat, shmid, shmflg, &addr, shmaddr); return res ? MAP_FAILED : addr; } } #endif #if HAVE_DECL_SYS_SHMDT UCM_DEFINE_SELECT_FUNC(shmdt, int, -1, SYS_shmdt, const void*) #elif HAVE_DECL_SYS_IPC # ifndef IPCOP_shmdt # define IPCOP_shmdt 22 # endif _UCM_DEFINE_DLSYM_FUNC(shmdt, ucm_orig_dlsym_shmdt, ucm_override_shmdt, int, -1, const void*) int ucm_orig_shmdt(const void *shmaddr) { if (ucm_mmap_hook_mode() == UCM_MMAP_HOOK_RELOC) { return ucm_orig_dlsym_shmdt(shmaddr); } else { /* Using IPC syscall of shmdt implementation */ return syscall(SYS_ipc, IPCOP_shmdt, 0, 0, 0, shmaddr); } } #endif #if HAVE___CURBRK extern void *__curbrk; #endif _UCM_DEFINE_DLSYM_FUNC(brk, ucm_orig_dlsym_brk, ucm_override_brk, int, -1, void*) void *ucm_brk_syscall(void *addr) { return (void*)syscall(SYS_brk, addr); } int ucm_orig_brk(void *addr) { void *new_addr; #if HAVE___CURBRK __curbrk = #endif new_addr = ucm_brk_syscall(addr); if (new_addr < addr) { errno = ENOMEM; return -1; } else { return 0; } } _UCM_DEFINE_DLSYM_FUNC(sbrk, ucm_orig_dlsym_sbrk, ucm_override_sbrk, void*, MAP_FAILED, intptr_t) void *ucm_orig_sbrk(intptr_t increment) { void *prev; if (ucm_mmap_hook_mode() == UCM_MMAP_HOOK_RELOC) { return ucm_orig_dlsym_sbrk(increment); } else { prev = ucm_brk_syscall(0); return ucm_orig_brk(UCS_PTR_BYTE_OFFSET(prev, increment)) ? (void*)-1 : prev; } } #else /* UCM_BISTRO_HOOKS */ UCM_DEFINE_DLSYM_FUNC(sbrk, void*, MAP_FAILED, intptr_t) UCM_DEFINE_DLSYM_FUNC(shmat, void*, MAP_FAILED, int, const void*, int) UCM_DEFINE_DLSYM_FUNC(shmdt, int, -1, const void*) #endif /* UCM_BISTRO_HOOKS */