bool hashtable_add(hashtable_t *table, void *key, void *payload) { uint hindex = hash_key(table, key); hash_entry_t *e; /* if payload is null can't tell from lookup miss */ ASSERT(payload != NULL, "hashtable_add internal error"); if (table->synch) dr_mutex_lock(table->lock); for (e = table->table[hindex]; e != NULL; e = e->next) { if (keys_equal(table, e->key, key)) { /* we have a use where payload != existing entry so we don't assert on that */ if (table->synch) dr_mutex_unlock(table->lock); return false; } } e = (hash_entry_t *) hash_alloc(sizeof(*e)); if (table->str_dup) { const char *s = (const char *) key; e->key = hash_alloc(strlen(s)+1); strncpy((char *)e->key, s, strlen(s)+1); } else e->key = key; e->payload = payload; e->next = table->table[hindex]; table->table[hindex] = e; table->entries++; hashtable_check_for_resize(table); if (table->synch) dr_mutex_unlock(table->lock); return true; }
static dr_emit_flags_t event_basic_block(void *drcontext, void *tag, instrlist_t *bb, bool for_trace, bool translating) { instr_t *instr; trace_head_entry_t *e = NULL; if (translating) return DR_EMIT_DEFAULT; for (instr = instrlist_first(bb); instr != NULL; instr = instr_get_next(instr)) { /* blocks containing calls are trace heads */ if (instr_is_call(instr)) { dr_mark_trace_head(drcontext, tag); dr_mutex_lock(htable_mutex); e = add_trace_head_entry(NULL, tag); e->is_trace_head = true; dr_mutex_unlock(htable_mutex); #ifdef VERBOSE dr_log(drcontext, LOG_ALL, 3, "inline: marking bb "PFX" as trace head\n", tag); #endif /* doesn't matter what's in rest of bb */ return DR_EMIT_DEFAULT; } else if (instr_is_return(instr)) { dr_mutex_lock(htable_mutex); e = add_trace_head_entry(NULL, tag); e->has_ret = true; dr_mutex_unlock(htable_mutex); } } return DR_EMIT_DEFAULT; }
/* Annotation handler to initialize a client context (associated with an app thread) */ static void init_context(uint id, const char *label, uint initial_mode) { context_t *context; dr_mutex_lock(context_lock); PRINTF("Initialize context %d '%s' in mode %d", id, label, initial_mode); context = get_context(id); if (context == NULL) { uint label_length = (uint) (sizeof(char) * strlen(label)) + 1; context = dr_global_alloc(sizeof(context_t)); context->id = id; context->label = dr_global_alloc(label_length); context->mode = initial_mode; context->mode_history = dr_global_alloc(MAX_MODE_HISTORY * sizeof(uint)); context->mode_history[0] = initial_mode; context->mode_history_index = 1; memcpy(context->label, label, label_length); context->next = NULL; if (context_list->head == NULL) { context_list->head = context_list->tail = context; } else { context_list->tail->next = context; context_list->tail = context; } } dr_mutex_unlock(context_lock); }
void post_malloc(void *wrapctx, void *user_data) { malloc_t *block = (malloc_t *)user_data; dr_mutex_lock(lock); if (!block) { dr_mutex_unlock(lock); return; } set_addr_malloc(block, drwrap_get_retval(wrapctx), ALLOC, 0); dr_mutex_unlock(lock); }
DR_EXPORT void drmgr_exit(void) { static bool exited; /* try to handle multiple calls to exit. still possible to crash * trying to lock a destroyed lock. */ if (exited || !dr_mutex_trylock(exit_lock) || exited) return; exited = true; drmgr_bb_exit(); drmgr_event_exit(); dr_rwlock_destroy(presys_event_lock); dr_rwlock_destroy(cls_event_lock); dr_mutex_destroy(tls_lock); dr_rwlock_destroy(thread_event_lock); dr_rwlock_destroy(bb_cb_lock); dr_mutex_destroy(note_lock); dr_mutex_unlock(exit_lock); dr_mutex_destroy(exit_lock); }
void hashtable_delete(hashtable_t *table) { uint i; if (table->synch) dr_mutex_lock(table->lock); for (i = 0; i < HASHTABLE_SIZE(table->table_bits); i++) { hash_entry_t *e = table->table[i]; while (e != NULL) { hash_entry_t *nexte = e->next; if (table->str_dup) hash_free(e->key, strlen((const char *)e->key) + 1); if (table->free_payload_func != NULL) (table->free_payload_func)(e->payload); hash_free(e, sizeof(*e)); e = nexte; } } hash_free(table->table, (size_t)HASHTABLE_SIZE(table->table_bits) * sizeof(hash_entry_t*)); table->table = NULL; table->entries = 0; if (table->synch) dr_mutex_unlock(table->lock); dr_mutex_destroy(table->lock); }
void add_hit(void *pc, size_t size, void *target, int read, void *drcontext, ctx_t *ctx) { malloc_t *block = search_on_tree(active_blocks, target); access_t *access; // if the access is not on a malloc block we do nothing // we have to check if the target is not the and of the block // (because last offset is out of the user // data and use only for malloc's internal purposes) if (!block || target == block->end) return; dr_mutex_lock(lock); if (read) access = get_access(target - block->start, &(block->read), block); else access = get_access(target - block->start, &(block->write), block); access->total_hits++; incr_orig(access, size, pc, drcontext, block, ctx); dr_mutex_unlock(lock); }
void instrace_thread_exit(void *drcontext) { per_thread_t *data; int i; if (client_arg->instrace_mode == INS_TRACE){ ins_trace(drcontext); } data = drmgr_get_tls_field(drcontext, tls_index); dr_mutex_lock(mutex); num_refs += data->num_refs; dr_mutex_unlock(mutex); dr_close_file(data->outfile); if (log_mode){ dr_close_file(data->logfile); } dr_thread_free(drcontext, data->buf_base, INSTR_BUF_SIZE); dr_thread_free(drcontext, data->output_array, OUTPUT_BUF_SIZE); DEBUG_PRINT("%s - thread id : %d, cloned instructions freeing now - %d\n",ins_pass_name, dr_get_thread_id(drcontext),data->static_ptr); for(i=0 ; i<data->static_ptr; i++){ instr_destroy(dr_get_current_drcontext(),data->static_array[i]); } dr_thread_free(drcontext, data->static_array, sizeof(instr_t *)*client_arg->static_info_size); dr_thread_free(drcontext, data, sizeof(per_thread_t)); DEBUG_PRINT("%s - exiting thread done %d\n", ins_pass_name, dr_get_thread_id(drcontext)); }
/* to keep the size of our hashtable down */ static void event_fragment_deleted(void *drcontext, void *tag) { dr_mutex_lock(htable_mutex); remove_trace_head_entry(NULL, tag); dr_mutex_unlock(htable_mutex); }
bool drvector_delete(drvector_t *vec) { uint i; if (vec == NULL) return false; if (vec->synch) dr_mutex_lock(vec->lock); /* Since we lazily initialize the array, vec->array could be NULL if we * called drvector_init with capacity 0 and never inserted an element into * the vec. We check vec->array here and below before access. * */ if (vec->free_data_func != NULL && vec->array != NULL) { for (i = 0; i < vec->entries; i++) { (vec->free_data_func)(vec->array[i]); } } if (vec->array != NULL) { dr_global_free(vec->array, vec->capacity * sizeof(void *)); vec->array = NULL; vec->entries = 0; } if (vec->synch) dr_mutex_unlock(vec->lock); dr_mutex_destroy(vec->lock); return true; }
static void inc_count_second(int second) { dr_mutex_lock(mutex); counts[second]++; dr_mutex_unlock(mutex); }
bool hashtable_remove(hashtable_t *table, void *key) { bool res = false; hash_entry_t *e, *prev_e; uint hindex = hash_key(table, key); if (table->synch) dr_mutex_lock(table->lock); for (e = table->table[hindex], prev_e = NULL; e != NULL; prev_e = e, e = e->next) { if (keys_equal(table, e->key, key)) { if (prev_e == NULL) table->table[hindex] = e->next; else prev_e->next = e->next; if (table->str_dup) hash_free(e->key, strlen((const char *)e->key) + 1); if (table->free_payload_func != NULL) (table->free_payload_func)(e->payload); hash_free(e, sizeof(*e)); res = true; table->entries--; break; } } if (table->synch) dr_mutex_unlock(table->lock); return res; }
static inline void ordered_lock(ipc_channel_t *channel, uint tid) { dr_mutex_lock(channel->queue_lock); ticket_queue_t *q = &channel->ticket_queue; if (q->locked) { ticket_node_t *node = dr_global_alloc(sizeof(ticket_node_t)); if (node == NULL) DR_ABORT_MSG("Failed to allocate ticket node\n"); node->next = NULL; node->dr_event = dr_event_create(); node->waiting = true; node->thread_id = tid; DR_ASSERT(q->tail->next == NULL); q->tail = q->tail->next = node; SGL_DEBUG("Sleeping Thread :%d\n", tid); dr_mutex_unlock(channel->queue_lock); /* MDL20170425 TODO(soonish) * how likely is it that we'll miss a wakeup here? */ while (node->waiting) dr_event_wait(node->dr_event); dr_mutex_lock(channel->queue_lock); q->head->next = node->next; if (q->tail == node) q->tail = q->head; dr_event_destroy(node->dr_event); dr_global_free(node, sizeof(ticket_node_t)); SGL_DEBUG("Awakened Thread :%d\n", tid); } else { q->locked = true; } dr_mutex_unlock(channel->queue_lock); }
static void inc_count_first(int first, int second) { dr_mutex_lock(mutex); if (counts[second] == 0) dr_fprintf(STDERR, "%s is called before %s\n", name[first], name[second]); counts[first]++; dr_mutex_unlock(mutex); }
static void delete_fragment(void *drcontext, app_pc tag) { dr_mutex_lock(mutex); deletions++; dr_mutex_unlock(mutex); dr_delete_fragment(drcontext, tag); }
void hashtable_clear(hashtable_t *table) { if (table->synch) dr_mutex_lock(table->lock); hashtable_clear_internal(table); if (table->synch) dr_mutex_unlock(table->lock); }
void clean_call_mem_information(instr_t * instr, app_pc mem_val, uint write){ void * drcontext = dr_get_current_drcontext(); module_data_t * data = dr_lookup_module(instr_get_app_pc(instr)); uint offset; app_pc base_pc; size_t size; uint prot; file_t dump_file; char * dump_filename; DR_ASSERT(data != NULL); offset = instr_get_app_pc(instr) - data->start; dr_mutex_lock(mutex); //if (!md_lookup_bb_in_module(done_head, data->full_path, offset)){ //md_add_bb_to_module(done_head, data->full_path, offset, MAX_BBS_PER_MODULE, false); dr_query_memory(mem_val, &base_pc, &size, &prot); //DEBUG_PRINT("base pc - %x, size - %u, write - %u\n", base_pc, size, write); if (write){ /* postpone till the end of the function */ if (!is_mem_region_present(write_regions, base_pc, size, write_region_size)){ DEBUG_PRINT("write registered - offset - %x memval %x\n", offset, mem_val); add_to_mem_region(write_regions, base_pc, size, &write_region_size); DEBUG_PRINT("base pc %x, size %d\n", base_pc, size); } } else{ if (!is_mem_region_present(read_regions, base_pc, size, read_region_size)){ add_to_mem_region(read_regions, base_pc, size, &read_region_size); //DEBUG_PRINT("size - %d\n", read_region_size); //DEBUG_PRINT("present - %d\n", is_mem_region_present(read_regions, base_pc, size, read_region_size)); //dr_abort(); DEBUG_PRINT("read registered - offset - %x memval %x\n", offset, mem_val); DEBUG_PRINT("base pc %x, size %d\n", base_pc, size); dump_filename = get_mem_dump_filename(base_pc, size, write,0); dump_file = dr_open_file(dump_filename, DR_FILE_WRITE_OVERWRITE); DEBUG_PRINT("%s dumping file\n", dump_filename); do_mem_dump(dump_file, base_pc, size); DEBUG_PRINT("file dumped\n"); dr_global_free(dump_filename, sizeof(char) * MAX_STRING_LENGTH); dr_close_file(dump_file); } } //} dr_mutex_unlock(mutex); dr_free_module_data(data); }
int main(int argc, char *argv[]) { #ifdef STANDALONE_DECODER void *dcontext = GLOBAL_DCONTEXT; #else void *dcontext = dr_standalone_init(); /* simple test of deadlock_avoidance, etc. being disabled in standalone */ void *x = dr_mutex_create(); dr_mutex_lock(x); dr_mutex_unlock(x); dr_mutex_destroy(x); #endif test_all_opcodes_0(dcontext); #ifndef STANDALONE_DECODER /* speed up compilation */ test_all_opcodes_1(dcontext); test_all_opcodes_2(dcontext); test_all_opcodes_2_mm(dcontext); test_all_opcodes_3(dcontext); test_all_opcodes_3_avx(dcontext); test_all_opcodes_4(dcontext); #endif test_disp_control(dcontext); test_indirect_cti(dcontext); test_cti_prefixes(dcontext); #ifndef X64 test_modrm16(dcontext); #endif test_size_changes(dcontext); test_nop_xchg(dcontext); #ifdef X64 test_x86_mode(dcontext); test_x64_abs_addr(dcontext); test_x64_inc(dcontext); #endif test_regs(dcontext); test_instr_opnds(dcontext); test_strict_invalid(dcontext); print("all done\n"); return 0; }
static void event_thread_exit_ex(void *drcontext) { if (!in_event_thread_exit_ex) { dr_mutex_lock(threadlock); if (!in_event_thread_exit_ex) { dr_fprintf(STDERR, "in event_thread_exit_ex\n"); in_event_thread_exit_ex = true; } dr_mutex_unlock(threadlock); } }
void pre_calloc(void *wrapctx, OUT void **user_data) { void *drc; drc = drwrap_get_drcontext(wrapctx); dr_mutex_lock(lock); if (!module_is_wrapped(drc)) { dr_mutex_unlock(lock); return; } *user_data = add_block((size_t)drwrap_get_arg(wrapctx, 1) * (size_t)drwrap_get_arg(wrapctx, 0), get_prev_instr_pc(drwrap_get_retaddr(wrapctx), drc), drc); dr_mutex_unlock(lock); }
static void onLoad( void* ctx, const module_data_t* m, bool loaded ) { dr_printf( "In onLoad(%s, %p-%p)\n", m->full_path, m->start, m->end ); dr_mutex_lock( outMutex ); dr_fprintf( outFile, "M %p %p %s\n", m->start, m->end, m->full_path ); dr_mutex_unlock( outMutex ); drsym_error_t rc = drsym_enumerate_symbols( m->full_path, onSymbol, (void*)m, 0 ); if( DRSYM_SUCCESS != rc ) { dr_printf( " drsym_enumerate_symbols() failed: %i\n", rc ); } }
static void event_post_sys_B(void *drcontext, int sysnum) { if (!in_post_syscall_B) { dr_mutex_lock(syslock); if (!in_post_syscall_B) { dr_fprintf(STDERR, "in post_sys_B\n"); in_post_syscall_B = true; } dr_mutex_unlock(syslock); } }
/* If an entry already exists and is 0, replaces it; else adds a new * offset for that symbol. */ bool symcache_add(const module_data_t *mod, const char *symbol, size_t offs) { mod_cache_t *modcache; const char *modname = dr_module_preferred_name(mod); if (modname == NULL) return false; /* don't support caching */ ASSERT(initialized, "symcache was not initialized"); dr_mutex_lock(symcache_lock); modcache = (mod_cache_t *) hashtable_lookup(&symcache_table, (void *)mod->full_path); if (modcache == NULL) { LOG(2, "%s: there is no cache for %s\n", __FUNCTION__, modname); dr_mutex_unlock(symcache_lock); return false; } if (symcache_symbol_add(modname, &modcache->table, symbol, offs) && modcache->from_file) modcache->appended = true; dr_mutex_unlock(symcache_lock); return true; }
static void event_nudge(void *drcontext, uint64 argument) { DISPLAY_FUNC(NAME" received nudge event; re-reading config file."); /* An external process has nudged us with dr_nudge_process() telling us * to re-read the configuration file. */ dr_mutex_lock(table_lock); free_table(); read_table(); dr_mutex_unlock(table_lock); }
/** Finds information associated with given tag. */ struct tag_info_t* find_tag_or_die(void* tag) { struct tag_info_t* tag_info; dr_mutex_lock(tags_lock); tag_info = hashtable_lookup(&tags, tag); dr_mutex_unlock(tags_lock); if(tag_info == NULL) { dr_fprintf(STDERR, "fatal: could not locate tag %p\n", tag); dr_exit_process(1); } return tag_info; }
static void fork_init_event2(void *drcontext) { int i; dr_mutex_lock(mutex); for (i = 0; i < EVENT_last; i++) counts[i] = 0; counts[EVENT_FORK_INIT_2]++; dr_mutex_unlock(mutex); if (!dr_unregister_fork_init_event(fork_init_event2)) dr_fprintf(STDERR, "unregister failed!\n"); }
static void onUnload( void* ctx, const module_data_t* m ) { dr_printf( "In onUnload(%s, %p-%p)\n", m->full_path, m->start, m->end ); dr_mutex_lock( outMutex ); dr_fprintf( outFile, "m %p %p %s\n", (void*)m->start, (void*)m->end, m->full_path ); dr_mutex_unlock( outMutex ); hashtable_lock( &wraps ); hashtable_remove_range( &wraps, (void*)m->start, (void*)m->end ); hashtable_unlock( &wraps ); }
/** Wrapper pre-callback. */ static void wrapperPre( void* ctx, void** data ) { dr_mutex_lock( outMutex ); uint64 currentTimeMillis = dr_get_milliseconds(); if( currentTimeMillis > nextTimestampMillis ) { dr_fprintf( outFile, "T 0x%.16llx\n", currentTimeMillis ); nextTimestampMillis = currentTimeMillis + timestampIntervalMillis; } dr_fprintf( outFile, "X %p %p\n", (void*)drwrap_get_func( ctx ), drwrap_get_arg( ctx, 0 ) ); dr_mutex_unlock( outMutex ); }
static bool event_pre_sys_B(void *drcontext, int sysnum) { if (!in_syscall_B) { dr_mutex_lock(syslock); if (!in_syscall_B) { dr_fprintf(STDERR, "in pre_sys_B\n"); in_syscall_B = true; } dr_mutex_unlock(syslock); } return true; }
static void wrap_post(void *wrapcxt, void *user_data) { size_t sz = (size_t) user_data; /* test out-of-memory by having a random moderately-large alloc fail */ if (sz > 1024 && dr_get_random_value(1000) < 10) { bool ok = drwrap_set_retval(wrapcxt, NULL); DR_ASSERT(ok); dr_mutex_lock(max_lock); malloc_oom++; dr_mutex_unlock(max_lock); } }