drmf_status_t drsyscall_os_init(void *drcontext) { uint i; hashtable_init_ex(&systable, SYSTABLE_HASH_BITS, HASH_INTPTR, false/*!strdup*/, false/*!synch*/, NULL, sysnum_hash, sysnum_cmp); /* We initialize & leave secondary_systable empty to be in sync with our * Windows & Linux solutions. Xref i#1438 i#1549. */ hashtable_init_ex(&secondary_systable, SECONDARY_SYSTABLE_HASH_BITS, HASH_INTPTR, false/*!strdup*/, false/*!synch*/, NULL, sysnum_hash, sysnum_cmp); hashtable_init(&name2num_table, NAME2NUM_TABLE_HASH_BITS, HASH_STRING, false/*!strdup*/); dr_recurlock_lock(systable_lock); for (i = 0; i < count_syscall_info_bsd; i++) { IF_DEBUG(bool ok =) hashtable_add(&systable, (void *) &syscall_info_bsd[i].num, (void *) &syscall_info_bsd[i]); ASSERT(ok, "no dups"); IF_DEBUG(ok =) hashtable_add(&name2num_table, (void *) syscall_info_bsd[i].name, (void *) &syscall_info_bsd[i].num); ASSERT(ok || strcmp(syscall_info_bsd[i].name, "ni_syscall") == 0, "no dups"); } dr_recurlock_unlock(systable_lock); return DRMF_SUCCESS; }
void symcache_init(const char *symcache_dir_in, size_t modsize_cache_threshold) { initialized = true; op_modsize_cache_threshold = modsize_cache_threshold; hashtable_init_ex(&symcache_table, SYMCACHE_MASTER_TABLE_HASH_BITS, IF_WINDOWS_ELSE(HASH_STRING_NOCASE, HASH_STRING), true/*strdup*/, false/*!synch*/, symcache_free_entry, NULL, NULL); symcache_lock = dr_mutex_create(); dr_snprintf(symcache_dir, BUFFER_SIZE_ELEMENTS(symcache_dir), "%s", symcache_dir_in); NULL_TERMINATE_BUFFER(symcache_dir); if (!dr_directory_exists(symcache_dir)) { if (!dr_create_dir(symcache_dir)) { /* check again in case of a race (i#616) */ if (!dr_directory_exists(symcache_dir)) { NOTIFY_ERROR("Unable to create symcache dir %s"NL, symcache_dir); ASSERT(false, "unable to create symcache dir"); dr_abort(); } } } }
DR_EXPORT void dr_client_main(client_id_t id, int argc, const char *argv[]) { dr_set_client_name("DynamoRIO Sample Client 'inline'", "http://dynamorio.org/issues"); if (!drmgr_init()) DR_ASSERT(false); hashtable_init_ex(&head_table, HASH_BITS, HASH_INTPTR, false/*!strdup*/, false/*synchronization is external*/, free_trace_head_entry, NULL, NULL); dr_register_exit_event(event_exit); if (!drmgr_register_bb_instrumentation_event(event_analyze_bb, NULL, NULL)) DR_ASSERT(false); dr_register_delete_event(event_fragment_deleted); dr_register_end_trace_event(query_end_trace); /* Make it easy to tell from the log file which client executed. */ dr_log(NULL, DR_LOG_ALL, 1, "Client 'inline' initializing\n"); #ifdef SHOW_RESULTS /* also give notification to stderr */ if (dr_is_notify_on()) { # ifdef WINDOWS /* Ask for best-effort printing to cmd window. Must be called at init. */ dr_enable_console_printing(); # endif dr_fprintf(STDERR, "Client inline is running\n"); } #endif }
DR_EXPORT void dr_init(client_id_t id) { dr_fprintf(STDERR, "info: starting dtrace, &dr_init=%p..\n", &dr_init); trace_file = dr_open_file(TRACE_FILE_NAME, DR_FILE_ALLOW_LARGE | DR_FILE_WRITE_OVERWRITE); if(trace_file == INVALID_FILE) { dr_fprintf(STDERR, "fatal: dr_open_file() failed\n"); dr_exit_process(1); } trace_file_lock = dr_mutex_create(); trace_buffer = tb_create(-1); trace_buffer_lock = dr_mutex_create(); hashtable_init_ex(&tags, 16, HASH_INTPTR, false, false, &tag_info_free_raw, NULL, NULL); tags_lock = dr_mutex_create(); dr_register_exit_event(&dr_exit); dr_register_thread_init_event(&handle_thread_init); dr_register_thread_exit_event(&handle_thread_exit); dr_register_bb_event(&handle_bb); dr_register_trace_event(&handle_trace); dr_register_delete_event(&handle_delete); dr_register_signal_event(&handle_signal); dr_register_restore_state_event(&handle_restore_state); }
DR_EXPORT drmf_status_t drfuzz_init(client_id_t client_id) { drmf_status_t res; int count = dr_atomic_add32_return_sum(&drfuzz_init_count, 1); if (count > 1) return DRMF_SUCCESS; res = drmf_check_version(client_id); if (res != DRMF_SUCCESS) return res; callbacks = global_alloc(sizeof(drfuzz_callbacks_t), HEAPSTAT_MISC); memset(callbacks, 0, sizeof(drfuzz_callbacks_t)); drmgr_init(); drwrap_init(); #ifdef UNIX drmgr_register_signal_event(fault_handler); #else /* WINDOWS */ drmgr_register_exception_event(fault_handler); #endif drmgr_register_thread_init_event(thread_init); drmgr_register_thread_exit_event(thread_exit); drmgr_register_bb_app2app_event(bb_event, NULL); tls_idx_fuzzer = drmgr_register_tls_field(); if (tls_idx_fuzzer < 0) { DRFUZZ_ERROR("drfuzz failed to reserve TLS slot--initialization failed\n"); return DRMF_ERROR; } /* Synchronized to allow addition and removal of fuzz targets during execution * of the target program, e.g. to explore control flow paths. */ hashtable_init_ex(&fuzz_target_htable, 3, HASH_INTPTR, false/*no strdup*/, true/*synchronized*/, free_fuzz_target, NULL/*no custom hash*/, NULL/*no custom comparator*/); return DRMF_SUCCESS; }
DR_EXPORT void dr_init( client_id_t id ) { dr_printf( "In dr_init()\n" ); // Initialize extensions. drsym_error_t rc = drsym_init( 0 ); if( DRSYM_SUCCESS != rc ) { dr_printf( "drsym_init() failed: %i\n", rc ); exit( 1 ); } bool wrapInit = drwrap_init(); if( !wrapInit ) { dr_printf( "drwrap_init() failed\n" ); exit( 1 ); } // Set up output. char fileName[256]; unsigned int pid = (unsigned int)dr_get_process_id(); dr_snprintf( fileName, sizeof( fileName ), "objcount-%u.out", pid ); fileName[sizeof( fileName ) - 1] = 0; outFile = dr_open_file( fileName, DR_FILE_WRITE_OVERWRITE ); outMutex = dr_mutex_create(); // Set up hashtable. hashtable_init_ex( &wraps, // table 16, // num_bits HASH_INTPTR, // hashtype false, // str_dup false, // synch &free_wrap, // free_payload_func NULL, // hash_key_func NULL ); // cmp_key_func // Register for events. dr_register_module_load_event( onLoad ); dr_register_exit_event( onExit ); }
DR_EXPORT drmf_status_t drsymcache_init(client_id_t client_id, const char *symcache_dir_in, size_t modsize_cache_threshold) { #ifdef WINDOWS module_data_t *mod; #endif drmf_status_t res; drmgr_priority_t pri_mod_load_cache = {sizeof(pri_mod_load_cache), DRMGR_PRIORITY_NAME_DRSYMCACHE, NULL, NULL, DRMGR_PRIORITY_MODLOAD_DRSYMCACHE_READ}; drmgr_priority_t pri_mod_unload_cache = {sizeof(pri_mod_unload_cache), DRMGR_PRIORITY_NAME_DRSYMCACHE, NULL, NULL, DRMGR_PRIORITY_MODUNLOAD_DRSYMCACHE}; drmgr_priority_t pri_mod_save_cache = {sizeof(pri_mod_save_cache), DRMGR_PRIORITY_NAME_DRSYMCACHE_SAVE, NULL, NULL, DRMGR_PRIORITY_MODLOAD_DRSYMCACHE_SAVE}; /* handle multiple sets of init/exit calls */ int count = dr_atomic_add32_return_sum(&symcache_init_count, 1); if (count > 1) return DRMF_WARNING_ALREADY_INITIALIZED; res = drmf_check_version(client_id); if (res != DRMF_SUCCESS) return res; drmgr_init(); drmgr_register_module_load_event_ex(symcache_module_load, &pri_mod_load_cache); drmgr_register_module_unload_event_ex(symcache_module_unload, &pri_mod_unload_cache); drmgr_register_module_load_event_ex(symcache_module_load_save, &pri_mod_save_cache); initialized = true; op_modsize_cache_threshold = modsize_cache_threshold; hashtable_init_ex(&symcache_table, SYMCACHE_MASTER_TABLE_HASH_BITS, IF_WINDOWS_ELSE(HASH_STRING_NOCASE, HASH_STRING), true/*strdup*/, false/*!synch*/, symcache_free_entry, NULL, NULL); symcache_lock = dr_mutex_create(); dr_snprintf(symcache_dir, BUFFER_SIZE_ELEMENTS(symcache_dir), "%s", symcache_dir_in); NULL_TERMINATE_BUFFER(symcache_dir); if (!dr_directory_exists(symcache_dir)) { if (!dr_create_dir(symcache_dir)) { /* check again in case of a race (i#616) */ if (!dr_directory_exists(symcache_dir)) { NOTIFY_ERROR("Unable to create symcache dir %s"NL, symcache_dir); ASSERT(false, "unable to create symcache dir"); dr_abort(); } } } #ifdef WINDOWS /* It's common for tools to query ntdll in their init routines so we add it * early here */ mod = dr_lookup_module_by_name("ntdll.dll"); if (mod != NULL) { symcache_module_load(dr_get_current_drcontext(), mod, true); dr_free_module_data(mod); } #endif return DRMF_SUCCESS; }
void hashtable_init(hashtable_t *table, uint num_bits, hash_type_t hashtype, bool str_dup) { hashtable_init_ex(table, num_bits, hashtype, str_dup, true, NULL, NULL, NULL); }
void symcache_module_load(void *drcontext, const module_data_t *mod, bool loaded) { /* look for cache file for this module. * fill in hashtable: key is string, value is list of offsets */ mod_cache_t *modcache; const char *modname = dr_module_preferred_name(mod); file_t f; if (modname == NULL) return; /* don't support caching */ /* if smaller than threshold, not worth caching */ if (mod->end - mod->start < op_modsize_cache_threshold) { LOG(1, "%s: module %s too small to cache\n", __FUNCTION__, modname); return; } ASSERT(initialized, "symcache was not initialized"); /* support initializing prior to module events => called twice */ dr_mutex_lock(symcache_lock); modcache = (mod_cache_t *) hashtable_lookup(&symcache_table, (void *)mod->full_path); dr_mutex_unlock(symcache_lock); if (modcache != NULL) return; modcache = (mod_cache_t *) global_alloc(sizeof(*modcache), HEAPSTAT_HASHTABLE); memset(modcache, 0, sizeof(*modcache)); hashtable_init_ex(&modcache->table, SYMCACHE_MODULE_TABLE_HASH_BITS, HASH_STRING, true/*strdup*/, true/*synch*/, symcache_free_list, NULL, NULL); /* store consistency fields */ f = dr_open_file(mod->full_path, DR_FILE_READ); if (f != INVALID_FILE) { bool ok = dr_file_size(f, &modcache->module_file_size); if (!ok) WARN("WARNING: unable to determine size of %s\n", mod->full_path); dr_close_file(f); } else WARN("WARNING: unable to open %s\n", mod->full_path); #ifdef WINDOWS modcache->file_version = mod->file_version; modcache->product_version = mod->product_version; modcache->checksum = mod->checksum; modcache->timestamp = mod->timestamp; modcache->module_internal_size = mod->module_internal_size; #endif modcache->modname = drmem_strdup(modname, HEAPSTAT_HASHTABLE); modcache->from_file = symcache_read_symfile(mod, modname, modcache); dr_mutex_lock(symcache_lock); if (!hashtable_add(&symcache_table, (void *)mod->full_path, (void *)modcache)) { /* this should be really rare to have dup paths (xref i#729) -- and * actually we now have a lookup up above so we should only get here * on a race while we let go of the lock */ WARN("WARNING: duplicate module paths: only caching symbols from first\n"); hashtable_delete(&modcache->table); global_free(modcache, sizeof(*modcache), HEAPSTAT_HASHTABLE); } dr_mutex_unlock(symcache_lock); }