Example #1
0
void
loader_thread_exit(dcontext_t *dcontext)
{
    privmod_t *mod;
    /* assuming context swap have happened when entered DR */
    if (privload_has_thread_entry() &&
        /* Only call if we're cleaning up the currently executing thread, as
         * that's what the entry routine is going to do!  Calling on other
         * threads results in problems like double frees (i#969).  Exiting
         * another thread should only happen on process exit or forced thread
         * termination.  The former can technically continue (app could call
         * NtTerminateProcess(0) but then keep going) but we have never seen
         * that; and the latter doesn't do full native cleanups anyway.  Thus
         * we're not worried about leaks from not calling DLL_THREAD_EXIT.
         * (We can't check get_thread_private_dcontext() b/c it's already cleared.)
         */
        dcontext->owning_thread == get_thread_id()) {
        acquire_recursive_lock(&privload_lock);
        /* Walk forward and call independent libs last */
        for (mod = modlist; mod != NULL; mod = mod->next) {
            if (!mod->externally_loaded)
                privload_call_entry(mod, DLL_THREAD_EXIT);
        }
        release_recursive_lock(&privload_lock);
    }
    /* os specific thread exit for loader, holding no lock */
    os_loader_thread_exit(dcontext);
}
Example #2
0
void
loader_thread_exit(dcontext_t *dcontext)
{
    privmod_t *mod;
    /* assuming context swap have happened when entered DR */
    if (privload_has_thread_entry()) {
        acquire_recursive_lock(&privload_lock);
        /* Walk forward and call independent libs last */
         for (mod = modlist; mod != NULL; mod = mod->next) {
            if (!mod->externally_loaded)
                privload_call_entry(mod, DLL_THREAD_EXIT);
        }
        release_recursive_lock(&privload_lock);
    }
    /* os specific thread exit for loader, holding no lock */
    os_loader_thread_exit(dcontext);
}
Example #3
0
void
loader_thread_init(dcontext_t *dcontext)
{
    privmod_t *mod;

    if (modlist == NULL) {
#ifdef WINDOWS
        /* FIXME i#338: once restore order this will become nop */
        /* os specific thread initilization prologue for loader with no lock */
        os_loader_thread_init_prologue(dcontext);
        /* os specific thread initilization epilogue for loader with no lock */
        os_loader_thread_init_epilogue(dcontext);
#endif /* WINDOWS */
    } else {
        /* os specific thread initilization prologue for loader with no lock */
        os_loader_thread_init_prologue(dcontext);
        if (privload_has_thread_entry()) {
            /* We rely on lock isolation to prevent deadlock while we're here
             * holding privload_lock and the priv lib
             * DllMain may acquire the same lock that another thread acquired
             * in its app code before requesting a synchall (flush, exit).
             * FIXME i#875: we do not have ntdll!RtlpFlsLock isolated.
             * Living w/ it for now.  It should be unlikely for the app to
             * hold RtlpFlsLock and then acquire privload_lock: privload_lock
             * is used for import redirection but those don't apply within
             * ntdll.
             */
            ASSERT_OWN_NO_LOCKS();
            acquire_recursive_lock(&privload_lock);
            /* Walk forward and call independent libs last.
             * We do notify priv libs of client threads.
             */
            for (mod = modlist; mod != NULL; mod = mod->next) {
                if (!mod->externally_loaded)
                    privload_call_entry(mod, DLL_THREAD_INIT);
            }
            release_recursive_lock(&privload_lock);
        }
        /* os specific thread initilization epilogue for loader with no lock */
        os_loader_thread_init_epilogue(dcontext);
    }
}