void * VG_NOTIFY_ON_LOAD(ifunc_wrapper) (void) { OrigFn fn; Addr result = 0; Addr fnentry; /* Call the original indirect function and get it's result */ VALGRIND_GET_ORIG_FN(fn); CALL_FN_W_v(result, fn); #if defined(VGP_ppc64be_linux) /* ppc64be uses function descriptors, so get the actual function entry address for the client request, but return the function descriptor from this function. result points to the function descriptor, which starts with the function entry. */ fnentry = *(Addr*)result; #else fnentry = result; #endif /* Ask the valgrind core running on the real CPU (as opposed to this code which runs on the emulated CPU) to update the redirection that led to this function. This client request eventually gives control to the function VG_(redir_add_ifunc_target) in m_redir.c */ VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__ADD_IFUNC_TARGET, fn.nraddr, fnentry, 0, 0, 0); return (void*)result; }
UInt I_WRAP_SONAME_FNNAME_ZU(NONE,fn_0) ( UInt a1 ) { UInt r; void* fn; VALGRIND_GET_ORIG_FN(fn); printf("fn_0 wrapper pre ()\n"); CALL_FN_W_v(r, fn); printf("fn_0 wrapper post1 = %d\n", (int)r); CALL_FN_v_v(fn); printf("fn_0 wrapper post2 = %d\n", (int)r); return r; }
void * VG_NOTIFY_ON_LOAD(ifunc_wrapper) (void) { OrigFn fn; Addr result = 0; /* Call the original indirect function and get it's result */ VALGRIND_GET_ORIG_FN(fn); CALL_FN_W_v(result, fn); /* Ask the valgrind core running on the real CPU (as opposed to this code which runs on the emulated CPU) to update the redirection that led to this function. This client request eventually gives control to the function VG_(redir_add_ifunc_target) in m_redir.c */ VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__ADD_IFUNC_TARGET, fn.nraddr, result, 0, 0, 0); return (void*)result; }
cudaError_t I_WRAP_SONAME_FNNAME_ZZ(libcudartZdsoZa, cudaThreadSynchronize)() { // TODO: Rewrite to use helper functions instead of going through the // whole list manually. // Pointer to the Cudagrind internal list of registered contexts extern cgCtxListType *cgCtxList; // Fetch this pointer to work with locally cgCtxListType *nodeCtx = cgCtxList; OrigFn fn; cudaError_t result; VALGRIND_GET_ORIG_FN(fn); cgLock(); // TODO: Could we call original function before lock to cover more cases? CALL_FN_W_v(result, fn); // We go through the whole list and delete all locks held by any stream. while (nodeCtx) { cgMemListType *nodeMem = nodeCtx->memory; while (nodeMem) { if (nodeMem->locked) { nodeMem->locked = 0; } nodeMem = nodeMem->next; } cgArrListType *nodeArr = nodeCtx->array; while (nodeArr) { if (nodeArr->locked) { nodeArr->locked = 0; } nodeArr = nodeArr->next; } nodeCtx = nodeCtx->next; } cgUnlock(); }