/* 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);
}
/* Parse CL options and register DR event handlers and annotation handlers */
DR_EXPORT void
dr_client_main(client_id_t id, int argc, const char *argv[])
{
    context_lock = dr_mutex_create();
    write_lock = dr_mutex_create();

# ifdef WINDOWS
    dr_enable_console_printing();
# endif

    client_id = id;

    /* XXX: should use droption */
    if (argc > 1 && strcmp(argv[1], "full-decode") == 0) {
        PRINTF("Init annotation test client with full decoding");
        dr_register_bb_event(empty_bb_event);
    } else if (argc > 1 && strlen(argv[1]) >= 8 && strncmp(argv[1], "truncate", 8) == 0) {
        bb_truncation_length = (argv[1][9] - '0'); /* format is "truncate@n" (0<n<10) */
        ASSERT(bb_truncation_length < 10 && bb_truncation_length > 0);
        PRINTF("Init annotation test client with bb truncation");
        dr_register_bb_event(bb_event_truncate);
    } else {
        PRINTF("Init annotation test client with fast decoding");
    }

    context_list = dr_global_alloc(sizeof(context_list_t));
    memset(context_list, 0, sizeof(context_list_t));

#if !(defined (WINDOWS) && defined (X64))
    mem_defines = dr_global_alloc(sizeof(mem_defines_t));
    memset(mem_defines, 0, sizeof(mem_defines_t));
#endif

    dr_register_exit_event(event_exit);

    register_call("test_annotation_init_mode", (void *) init_mode, 1);
    register_call("test_annotation_init_context", (void *) init_context, 3);
    register_call("test_annotation_get_mode", (void *) get_mode, 1);
    register_call("test_annotation_set_mode", (void *) set_mode, 2);
#if !(defined (WINDOWS) && defined (X64))
    register_call("test_annotation_rotate_valgrind_handler",
                  (void *) rotate_valgrind_handler, 1);
#endif

    register_call("test_annotation_eight_args", (void *) test_eight_args_v1, 8);
    register_call("test_annotation_eight_args", (void *) test_eight_args_v2, 8);
    /* Test removing the last handler */
    dr_annotation_unregister_call("test_annotation_eight_args", test_eight_args_v1);

    register_call("test_annotation_nine_args", (void *) test_nine_args_v1, 9);
    register_call("test_annotation_nine_args", (void *) test_nine_args_v2, 9);
    /* Test removing the first handler */
    dr_annotation_unregister_call("test_annotation_nine_args", test_nine_args_v2);

    /* Test multiple handlers */
    register_call("test_annotation_ten_args", (void *) test_ten_args_v1, 10);
    register_call("test_annotation_ten_args", (void *) test_ten_args_v2, 10);

    dr_annotation_register_return("test_annotation_get_client_version", (void *) "2.2.8");
}
Esempio n. 3
0
/* adds an address to the linear list with addresses */
static bbinfo_t * add_bb_to_list (bbinfo_t * bb_list, unsigned int addr, bool extra_info, uint size){

	DR_ASSERT(size > bb_list[0].start_addr);


	bb_list[0].start_addr++;  //first element of the start address will have the length
	bb_list[bb_list[0].start_addr].start_addr = addr;
	bb_list[bb_list[0].start_addr].freq = 0;
	bb_list[bb_list[0].start_addr].printable = true;

	if(extra_info){
		//initialize from and to bbs
		bb_list[bb_list[0].start_addr].from_bbs = (call_bb_info_t *)dr_global_alloc(sizeof(call_bb_info_t)*MAX_TARGETS);
		bb_list[bb_list[0].start_addr].from_bbs[0].start_addr = 0;

		bb_list[bb_list[0].start_addr].to_bbs = (call_bb_info_t *)dr_global_alloc(sizeof(call_bb_info_t)*MAX_TARGETS);
		bb_list[bb_list[0].start_addr].to_bbs[0].start_addr = 0;

		//initialize call target
		bb_list[bb_list[0].start_addr].called_from = (call_target_info_t *)dr_global_alloc(sizeof(call_target_info_t)*MAX_TARGETS);
		bb_list[bb_list[0].start_addr].called_from[0].bb_addr = 0;

		//initialize called tos
		bb_list[bb_list[0].start_addr].called_to = (call_target_info_t *)dr_global_alloc(sizeof(call_target_info_t)*MAX_TARGETS);
		bb_list[bb_list[0].start_addr].called_to[0].bb_addr = 0;

		bb_list[bb_list[0].start_addr].func = NULL;
		bb_list[bb_list[0].start_addr].func_addr = 0;

	}

	return &bb_list[bb_list[0].start_addr];

}
Esempio n. 4
0
static
void increment(void *tag)
{
    elem_t *elem;

    elem = find(tag);
    if (elem != NULL) {
        elem->count++;
    }
    else {
        elem = dr_global_alloc(sizeof(elem_t));

        elem->tag = tag;
        elem->count = 1;
        elem->next = NULL;
        elem->prev = NULL;

        if (head == NULL) {
            head = elem;
            tail = elem;
        }
        else {
            tail->next = elem;
            elem->prev = tail;
            tail = elem;
        }
    }
}
Esempio n. 5
0
static void *
hash_alloc(size_t size)
{
    if (alloc_func != NULL)
        return (*alloc_func)(size);
    else
        return dr_global_alloc(size);
}
Esempio n. 6
0
/* gets a new element */
static module_t * new_elem (char * name,
							unsigned int list_length){

	module_t * elem = (module_t *)dr_global_alloc(sizeof(module_t));

	elem->module = (char *)dr_global_alloc(sizeof(char)*MAX_STRING_LENGTH);
	strncpy(elem->module,name,MAX_STRING_LENGTH);

	elem->bbs = (bbinfo_t *)dr_global_alloc(sizeof(bbinfo_t)*list_length);
	elem->bbs[0].start_addr = 0;    // this is there for storing the length

	elem->size_bbs = list_length;
	elem->next = NULL;

	return elem;

}
Esempio n. 7
0
module_table_t *
module_table_create()
{
    module_table_t *table = dr_global_alloc(sizeof(*table));
    memset(table->cache, 0, sizeof(table->cache));
    drvector_init(&table->vector, 16, false, module_table_entry_free);
    return table;
}
Esempio n. 8
0
/** Allocates storage for wrapper context. */
static struct wrap* alloc_wrap() {
  struct wrap* wrap = ( struct wrap* )dr_global_alloc( sizeof( struct wrap ) );
  if( wrap == NULL ) {
    dr_printf( "Failed to allocate memory for struct wrap\n" );
    exit( 1 );
  }
  return wrap;
}
Esempio n. 9
0
static
list_t *new_list()
{
    list_t *list = (list_t *)dr_global_alloc(sizeof(list_t));
    list->head = NULL;
    list->tail = NULL;
    return list;
}
Esempio n. 10
0
/** Allocates, initializes and registers a new tag_info structure.
 *  Must be called with tags_lock held. */
struct tag_info_t* tag_info_new(void* tag) {
  struct tag_info_t* tag_info = dr_global_alloc(sizeof(struct tag_info_t));
  tag_info->id = 0;
  tag_info->counter = 0;
  memset(&tag_info->instr_info, 0, sizeof(struct instr_info_t));
  hashtable_add(&tags, tag, tag_info);
  return tag_info;
}
Esempio n. 11
0
static bool parse_commandline_args(const char * args) {

	client_arg = (client_arg_t *)dr_global_alloc(sizeof(client_arg_t));

	if (dr_sscanf(args, "%s", &client_arg->filter_filename) != 1){
		return false;
	}

	return true;
}
Esempio n. 12
0
static void
drvector_increase_size(drvector_t *vec, uint newcap)
{
    void **newarray = dr_global_alloc(newcap * sizeof(void *));
    if (vec->array != NULL) {
        memcpy(newarray, vec->array, vec->entries * sizeof(void *));
        dr_global_free(vec->array, vec->capacity * sizeof(void *));
    }
    vec->array = newarray;
    vec->capacity = newcap;
}
Esempio n. 13
0
static char * get_mem_dump_filename(app_pc base_pc, uint size, uint write, uint other_info){

	char other_details[MAX_STRING_LENGTH];
	char * filename = dr_global_alloc(sizeof(char) * MAX_STRING_LENGTH);
	
	dr_snprintf(other_details, MAX_STRING_LENGTH, "%x_%d_%d_%d", base_pc, size, write, other_info);
	populate_conv_filename(filename, client_arg->output_folder, ins_pass_name, other_details);
	return filename;


}
Esempio n. 14
0
static bool parse_commandline_args (const char * args) {

	client_arg = (client_arg_t *)dr_global_alloc(sizeof(client_arg_t));
	if(dr_sscanf(args,"%s %d %s %s",&client_arg->filter_filename,
								&client_arg->filter_mode,
								&client_arg->output_folder,
								&client_arg->extra_info)!=4){
		return false;
	}
	
	return true;
}
Esempio n. 15
0
static trace_head_entry_t *
create_trace_head_entry(void *tag)
{
    trace_head_entry_t *e = (trace_head_entry_t *) dr_global_alloc(sizeof(*e));
    e->tag = tag;
    e->end_next = 0;
    e->size = 0;
    e->has_ret = false;
    e->is_trace_head = false;
    e->refcount = 1;
    return e;
}
Esempio n. 16
0
hash_table_t new_table()
{
    int i;
    hash_table_t table = (hash_table_t)dr_global_alloc
        (sizeof(list_t *) * HASH_TABLE_SIZE);

    for (i=0; i<HASH_TABLE_SIZE; i++) {
        table[i] = NULL;
    }

    return table;
}
Esempio n. 17
0
static
elem_t *new_elem(app_pc addr, cbr_state_t state)
{
    elem_t *elem = (elem_t *)dr_global_alloc(sizeof(elem_t));
    ASSERT(elem != NULL);

    elem->next  = NULL;
    elem->addr  = addr;
    elem->state = state;

    return elem;
}
Esempio n. 18
0
/*
 * Record the allocation of some memory. (Common code between malloc
 * and realloc.)
 */
static void allocated(void *ptr, size_t size)
{
    if (outfile == INVALID_FILE)
        return; /* no need to track allocations outside a logging interval */

    struct allocation *alloc = dr_global_alloc(sizeof(struct allocation));
    alloc->start = (uintptr_t)ptr;
    alloc->size = size;
    alloc->index = next_alloc_index++;
    alloc->prev = alloc_ends->prev;
    alloc->next = alloc_ends;
    alloc->prev->next = alloc->next->prev = alloc;
}
Esempio n. 19
0
static void
event_module_load(void *drcontext, const module_data_t *data, bool loaded)
{
    module_entry_t *entry = NULL;
    module_data_t  *mod;
    int i;
    /* Some apps repeatedly unload and reload the same module,
     * so we will try to re-use the old one.
     */
    ASSERT(data != NULL, "data must not be NULL");
    drvector_lock(&module_table.vector);
    /* Assuming most recently loaded entries are most likely to be unloaded,
     * we iterate the module table in a backward way for better performance.
     */
    for (i = module_table.vector.entries-1; i >= 0; i--) {
        entry = drvector_get_entry(&module_table.vector, i);
        mod   = entry->data;
        if (entry->unload &&
            /* If the same module is re-loaded at the same address,
             * we will try to use the existing entry.
             */
            mod->start       == data->start        &&
            mod->end         == data->end          &&
            mod->entry_point == data->entry_point  &&
#ifdef WINDOWS
            mod->checksum    == data->checksum     &&
            mod->timestamp   == data->timestamp    &&
#endif
            /* If a module w/ no name (there are some) is loaded, we will
             * keep making new entries.
             */
            dr_module_preferred_name(data) != NULL &&
            dr_module_preferred_name(mod)  != NULL &&
            strcmp(dr_module_preferred_name(data),
                   dr_module_preferred_name(mod)) == 0) {
            entry->unload = false;
            break;
        }
        entry = NULL;
    }
    if (entry == NULL) {
        entry = dr_global_alloc(sizeof(*entry));
        entry->id = module_table.vector.entries;
        entry->unload = false;
        entry->data = dr_copy_module_data(data);
        drvector_append(&module_table.vector, entry);
    }
    drvector_unlock(&module_table.vector);
    global_module_cache_add(module_table.cache, entry);
}
Esempio n. 20
0
/* WARNING i#262: if you use the cmake binary package, ctest is built
 * without a GNU_STACK section, which causes the linux kernel to set
 * the READ_IMPLIES_EXEC personality flag, which is propagated to
 * children and causes all mmaps to be +x, breaking all these tests
 * that check for mmapped memory to be +rw or +r!
 */
static
void global_test(void)
{
    char *array;
    uint prot;
    dr_fprintf(STDERR, "  testing global memory alloc...");
    array = dr_global_alloc(SIZE);
    write_array(array);
    dr_query_memory((const byte *)array, NULL, NULL, &prot);
    if (prot != get_os_mem_prot(DR_MEMPROT_READ|DR_MEMPROT_WRITE))
        dr_fprintf(STDERR, "[error: prot %d doesn't match rw] ", prot);
    dr_global_free(array, SIZE);
    dr_fprintf(STDERR, "success\n");
}
Esempio n. 21
0
bool
drvector_init(drvector_t *vec, uint initial_capacity, bool synch,
              void (*free_data_func)(void*))
{
    if (vec == NULL)
        return false;
    vec->array = dr_global_alloc(initial_capacity * sizeof(void*));
    vec->entries = 0;
    vec->capacity = initial_capacity;
    vec->synch = synch;
    vec->lock = dr_mutex_create();
    vec->free_data_func = free_data_func;
    return true;
}
Esempio n. 22
0
static void do_mem_dump(file_t file, uint base_pc,uint size){

	uint read;
	bool ok;
	byte * mem_values = dr_global_alloc(sizeof(byte) * size);
	ssize_t written;

	ok = dr_safe_read(base_pc, size, mem_values, &read);
	DR_ASSERT(ok);
	written = dr_write_file(file, mem_values, size);
	DEBUG_PRINT("read %d from %x of size %d and written %d\n", read, base_pc, size, written);

	dr_global_free(mem_values, sizeof(byte) * size);

}
Esempio n. 23
0
static bool
drmgr_generic_event_add(generic_event_entry_t **list,
                        void *rwlock,
                        void (*func)(void))
{
    generic_event_entry_t *e;
    if (func == NULL)
        return false;
    dr_rwlock_write_lock(rwlock);
    e = (generic_event_entry_t *) dr_global_alloc(sizeof(*e));
    e->cb.generic_cb = func;
    e->next = *list;
    *list = e;
    dr_rwlock_write_unlock(rwlock);
    return true;
}
Esempio n. 24
0
drcovlib_status_t
drmodtrack_dump(file_t log)
{
    drcovlib_status_t res;
    size_t size = 200 + module_table.vector.entries * (MAXIMUM_PATH + 40);
    char *buf;
    do {
        buf = dr_global_alloc(size);
        res = drmodtrack_dump_buf(buf, size);
        if (res == DRCOVLIB_SUCCESS)
            dr_write_file(log, buf, strlen(buf));
        dr_global_free(buf, size);
        size *= 2;
    } while (res == DRCOVLIB_ERROR_BUF_TOO_SMALL);
    return res;
}
Esempio n. 25
0
/* Caller must hold htable_mutex if drcontext == NULL. */
static trace_head_entry_t *
add_trace_head_entry(void *drcontext, void *tag)
{
    trace_head_entry_t **table = htable;
    trace_head_entry_t *e;
    uint hindex;
    e = (trace_head_entry_t *) dr_global_alloc(sizeof(trace_head_entry_t));
    e->tag = tag;
    e->end_next = 0;
    e->size = 0;
    e->has_ret = false;
    e->is_trace_head = false;
    hindex = (uint) HASH_FUNC_BITS((ptr_uint_t)tag, HASH_BITS);
    e->next = table[hindex];
    table[hindex] = e;
    return e;
}
Esempio n. 26
0
static void
read_table()
{
    file_t file;
    bool read_entry = true;

    file = dr_open_file(table_def_file_name, DR_FILE_READ);
    if (file == INVALID_FILE) {
        DISPLAY_FUNC(NAME" error opening config file \"%s\"\n", table_def_file_name);
        return;
    }

    VVDISPLAY_FUNC(NAME" reading config file: \"%s\"\n", table_def_file_name);

    do {
        table_entry_t *entry = (table_entry_t *)dr_global_alloc(sizeof(table_entry_t));
        if (dr_read_file(file, &entry->value, sizeof(table_value_t)) !=
            sizeof(table_value_t)) {
            /* end of file */
            read_entry = false;
            dr_global_free(entry, sizeof(table_entry_t));
        } else {
            int i;
            /* insert NULL termination for module name (including space padding) */
            for (i = sizeof(entry->value.module_name) - 1;
                 i >= 0 && entry->value.module_name[i] == ' '; i--) {
                entry->value.module_name[i] = '\0';
            }
            /* just in case */
            entry->value.module_name[sizeof(entry->value.module_name)-1] = '\0';

            /* add to the table */
            entry->next = table;
            table = entry;
            VVDISPLAY_FUNC(NAME" read entry for module=\"%s\" to_stack=%s to_heap=%s "
                           "transfer_to_here=%s\n", entry->value.module_name,
                           (entry->value.allow_to_stack == 'y' ||
                            entry->value.allow_to_stack == 'Y') ? "yes" : "no",
                           (entry->value.allow_to_heap == 'y' ||
                            entry->value.allow_to_heap == 'Y') ? "yes" : "no",
                           (entry->value.allow_to_here == 'y' ||
                            entry->value.allow_to_here == 'Y') ? "yes" : "no");
        }
    } while (read_entry);
    VVDISPLAY_FUNC(NAME" done reading config file.");
}
Esempio n. 27
0
static void
wrap_pre_SSL_read(void *wrapcxt, OUT void **user_data)
{
    struct SSL_read_data *sd;

    /* int SSL_read(SSL *ssl, void *buf, int num);
     *
     * ssize_t gnutls_record_recv(gnutls_session_t session,
     *                            void * data, size_t sizeofdata);
     */

    sd = dr_global_alloc(sizeof(struct SSL_read_data));
    sd->read_buffer = (unsigned char *)drwrap_get_arg(wrapcxt, 1);
    sd->ssl = (void *)drwrap_get_arg(wrapcxt, 0);

    *user_data = (void *)sd;
}
Esempio n. 28
0
/* Library offset has to be computed before the probe library is loaded
 * into memory.  Reading it from the map file is one of the easiest ways to
 * do it.
 */
unsigned int get_symbol_offset_from_map(const char *map_file, const char *symbol)
{
    const char *pref_addr_str = "Preferred load address is ";
    unsigned int pref_base, sym_addr, offset = 0xdeadc0de;
    ssize_t file_sz;
    file_t fd = INVALID_FILE;
    char *buf, *temp;

    fd = dr_open_file(map_file, DR_FILE_READ);
    if (fd == INVALID_FILE)
        goto _get_module_offset_exit; 

    /* This seems to be the easiest way to get the size of the file. */
    if (!dr_file_seek(fd, 0, DR_SEEK_END))
        goto _get_module_offset_exit; 
    file_sz = (ssize_t) dr_file_tell(fd);
    if (file_sz <= 0)
        goto _get_module_offset_exit; 
    if (!dr_file_seek(fd, 0, DR_SEEK_SET))
        goto _get_module_offset_exit; 

    /* Read the whole file. */
    buf = dr_global_alloc(file_sz + 1);
    if (buf == NULL)
        goto _get_module_offset_exit; 
    dr_read_file(fd, buf, file_sz);
    buf[file_sz] = '\0';

    /* Locate preferred base & symbol address. */
    temp = strstr(buf, pref_addr_str);
    if (temp != NULL)
    {
        pref_base = strtoul(temp + strlen(pref_addr_str), NULL, 16);
        temp = strstr(buf, symbol);
        if (temp != NULL)
            sym_addr = strtoul(temp + strlen(symbol), NULL, 16);
        offset = sym_addr - pref_base;
    }

    dr_global_free(buf, file_sz + 1);

 _get_module_offset_exit:
    if (fd != INVALID_FILE)
        dr_close_file(fd);
    return offset;
}
Esempio n. 29
0
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);
}
Esempio n. 30
0
static per_thread_t *
thread_data_create(void *drcontext)
{
    per_thread_t *data;
    if (drcontext == NULL) {
        ASSERT(!drcov_per_thread, "drcov_per_thread should not be set");
        data = dr_global_alloc(sizeof(*data));
    } else {
        ASSERT(drcov_per_thread, "drcov_per_thread should be set");
        data = dr_thread_alloc(drcontext, sizeof(*data));
    }
    /* XXX: can we assume bb create event is serialized,
     * if so, no lock is required for bb_table operation.
     */
    data->bb_table = bb_table_create(drcontext == NULL ? true : false);
    log_file_create(drcontext, data);
    return data;
}