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;
}
Beispiel #2
0
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;
}
Beispiel #3
0
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();
}