Ejemplo n.º 1
0
/* callbacks for the entire process */
void memdump_init(client_id_t id, const char * name, const char * arguments)
{

	char logfilename[MAX_STRING_LENGTH];
	file_t in_file;

	drmgr_init();
	drutil_init();
	drwrap_init();
	tls_index = drmgr_register_tls_field();
	DR_ASSERT(parse_commandline_args(arguments) == true);

	filter_head = md_initialize();
	done_head = md_initialize();
	app_pc_head = md_initialize();
	
	in_file = dr_open_file(client_arg->filter_filename, DR_FILE_READ);
	md_read_from_file(filter_head, in_file, false);
	dr_close_file(in_file);
	
	in_file = dr_open_file(client_arg->app_pc_filename, DR_FILE_READ);
	md_read_from_file(app_pc_head, in_file, false);
	dr_close_file(in_file);


	if (log_mode){
		populate_conv_filename(logfilename, logdir, name, NULL);
		logfile = dr_open_file(logfilename, DR_FILE_WRITE_OVERWRITE);
	}
	strncpy(ins_pass_name, name, MAX_STRING_LENGTH);
	mutex = dr_mutex_create();

}
Ejemplo n.º 2
0
void
terminate_IPC(int idx)
{
    ipc_channel_t *channel = &IPC[idx];

    if (channel->standalone)
    {
        dr_raw_mem_free(channel->shared_mem, sizeof(Sigil2DBISharedData));
    }
    else
    {
        /* send terminate sequence */
        uint finished = SIGIL2_IPC_FINISHED;
        uint last_buffer = channel->shmem_buf_idx;
        if(dr_write_file(channel->full_fifo, &last_buffer, sizeof(last_buffer)) != sizeof(last_buffer) ||
           dr_write_file(channel->full_fifo, &finished,    sizeof(finished))    != sizeof(finished))
            DR_ABORT_MSG("error writing finish sequence sigil2 fifos");

        /* wait for sigil2 to disconnect */
        while(dr_read_file(channel->empty_fifo, &finished, sizeof(finished)) > 0);

        dr_close_file(channel->empty_fifo);
        dr_close_file(channel->full_fifo);
        dr_unmap_file(channel->shared_mem, sizeof(Sigil2DBISharedData));
    }

    dr_global_free((void*)channel->ticket_queue.head, sizeof(ticket_queue_t));
    dr_mutex_destroy(channel->queue_lock);
}
Ejemplo n.º 3
0
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));

}
Ejemplo n.º 4
0
void instrace_exit_event()
{

	int i;

	DEBUG_PRINT("%s - total amount of instructions - %d\n",ins_pass_name, num_refs);

	if (client_arg->instrace_mode == OPCODE_TRACE){
		dr_printf("opcodes that were covered in this part of the code - \n");
		for (i = OP_FIRST; i <= OP_LAST; i++){
			if (opcodes_visited[i]){
				dr_printf(logfile,"%s - ", decode_opcode_name(i));
			}
		}
		dr_printf("\n");
	}

	md_delete_list(head, false);
	md_delete_list(instrace_head, false);
	dr_global_free(client_arg,sizeof(client_arg_t));
    code_cache_exit();
    drmgr_unregister_tls_field(tls_index);
    dr_mutex_destroy(mutex);
	if (log_mode){
		dr_close_file(logfile);
	}
    drutil_exit();
    drmgr_exit();
}
Ejemplo n.º 5
0
void inscount_init(client_id_t id, const char * name,  const char * arguments)
{

	file_t in_file;
	char logfilename[MAX_STRING_LENGTH];

	drmgr_init();

	global_count = 0;

	DR_ASSERT(parse_commandline_args(arguments) == true);
	head = md_initialize();


	if(client_arg->filter_mode != FILTER_NONE){
		in_file = dr_open_file(client_arg->filter_filename,DR_FILE_READ);
		DR_ASSERT(in_file != INVALID_FILE);
		md_read_from_file(head,in_file,false);
		dr_close_file(in_file);
	}

	if (log_mode){
		populate_conv_filename(logfilename, logdir, name, NULL);
		logfile = dr_open_file(logfilename, DR_FILE_WRITE_OVERWRITE);
	}
	strncpy(ins_pass_name, name, MAX_STRING_LENGTH);



}
Ejemplo n.º 6
0
/* callbacks for the entire process */
void funcwrap_init(client_id_t id, const char * name, const char * arguments)
{

	file_t in_file;
	char logfilename[MAX_STRING_LENGTH];

	drmgr_init();
	drwrap_init();
	tls_index = drmgr_register_tls_field();

	DR_ASSERT(parse_commandline_args(arguments) == true);
	head = md_initialize();
	if (!dr_file_exists(client_arg->filter_filename)){
		file_registered = false;
	}
	/* we expect the filter file to be of the form for function filtering */
	else{
		file_registered = true;
		in_file = dr_open_file(client_arg->filter_filename, DR_FILE_READ);
		DR_ASSERT(in_file != INVALID_FILE);
		md_read_from_file(head, in_file, false);
		dr_close_file(in_file);
	}

	if (log_mode){
		populate_conv_filename(logfilename, logdir, name, NULL);
		logfile = dr_open_file(logfilename, DR_FILE_WRITE_OVERWRITE);
	}
	strncpy(ins_pass_name, name, MAX_STRING_LENGTH);
	

}
Ejemplo n.º 7
0
static void
event_exit(void)
{
    file_t f;
    /* Display the results! */
    char msg[512];
    int len;
    len = dr_snprintf(msg, sizeof(msg)/sizeof(msg[0]),
                      "Instrumentation results:\n"
                      "  saw %" STAT_FORMAT_CODE " flops\n", stats->num_flops);
    DR_ASSERT(len > 0);
    msg[sizeof(msg)/sizeof(msg[0])-1] = '\0';
#ifdef SHOW_RESULTS
    DISPLAY_STRING(msg);
#endif /* SHOW_RESULTS */

    /* On Windows we need an absolute path so we place it in
     * the same directory as our library.
     */
    f = log_file_open(my_id, NULL, NULL /* client lib path */, "stats", 0);
    DR_ASSERT(f != INVALID_FILE);
    dr_fprintf(f, "%s\n", msg);
    dr_close_file(f);

    shared_memory_exit();

    drx_exit();
    if (!drmgr_unregister_bb_instrumentation_event(event_analyze_bb))
        DR_ASSERT(false);
    drmgr_exit();
}
Ejemplo n.º 8
0
void memtrace_thread_exit(void *drcontext)
{
    per_thread_t *data;

    memtrace(drcontext);
    data = drmgr_get_tls_field(drcontext, tls_index);
    dr_mutex_lock(mutex);
    num_refs += data->num_refs;
    dr_mutex_unlock(mutex);
	if (log_mode){
		dr_close_file(data->logfile);
	}
	dr_close_file(data->outfile);
    dr_thread_free(drcontext, data->buf_base, MEM_BUF_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));
}
Ejemplo n.º 9
0
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);


}
Ejemplo n.º 10
0
static client_stats_t *
shared_memory_init(void)
{
    bool is_NT = is_windows_NT();
    int num;
    int pos;
    /* We do not want to rely on the registry.
     * Instead, a piece of shared memory with the key base name holds the
     * total number of stats instances.
     */
    shared_map_count =
        CreateFileMappingW(INVALID_HANDLE_VALUE, NULL,
                           PAGE_READWRITE, 0, sizeof(client_stats_t),
                           is_NT ? CLIENT_SHMEM_KEY_NT_L : CLIENT_SHMEM_KEY_L);
    DR_ASSERT(shared_map_count != NULL);
    shared_view_count =
        MapViewOfFile(shared_map_count, FILE_MAP_READ|FILE_MAP_WRITE, 0, 0, 0);
    DR_ASSERT(shared_view_count != NULL);
    shared_count = (int *) shared_view_count;
    /* ASSUMPTION: memory is initialized to 0!
     * otherwise our protocol won't work
     * it's hard to build a protocol to initialize it to 0 -- if you want
     * to add one, feel free, but make sure it's correct
     */
    do {
        pos = (int) atomic_swap(shared_count, (uint) -1);
        /* if get -1 back, someone else is looking at it */
    } while (pos == -1);
    /* now increment it */
    atomic_swap(shared_count, pos+1);

    num = 0;
    while (1) {
        _snwprintf(shared_keyname, KEYNAME_MAXLEN, L"%s.%03d",
                   is_NT ? CLIENT_SHMEM_KEY_NT_L : CLIENT_SHMEM_KEY_L, num);
        shared_map = CreateFileMappingW(INVALID_HANDLE_VALUE, NULL,
                                        PAGE_READWRITE, 0,
                                        sizeof(client_stats_t),
                                        shared_keyname);
        if (shared_map != NULL && GetLastError() == ERROR_ALREADY_EXISTS) {
            dr_close_file(shared_map);
            shared_map = NULL;
        }
        if (shared_map != NULL)
            break;
        num++;
    }
    dr_log(NULL, LOG_ALL, 1, "Shared memory key is: \"%S\"\n", shared_keyname);
#ifdef SHOW_RESULTS
    dr_fprintf(STDERR, "Shared memory key is: \"%S\"\n", shared_keyname);
#endif
    shared_view = MapViewOfFile(shared_map, FILE_MAP_READ|FILE_MAP_WRITE, 0, 0, 0);
    DR_ASSERT(shared_view != NULL);
    return (client_stats_t *) shared_view;
}
Ejemplo n.º 11
0
void <client_name>_exit_event(void)
{

	md_delete_list(head, false);
	dr_global_free(client_arg, sizeof(client_arg_t));
	drmgr_unregister_tls_field(tls_index);
	if (log_mode){
		dr_close_file(logfile);
	}
	drmgr_exit();

}
Ejemplo n.º 12
0
void
funcwrap_thread_exit(void *drcontext){
	per_thread_t * data;
	data = drmgr_get_tls_field(drcontext, tls_index);
	if (log_mode){
		dr_close_file(data->logfile);
	}
	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));

}
Ejemplo n.º 13
0
static
void exit_event(void)
{
    if (outf != STDERR)
        dr_close_file(outf);
    if (drsys_exit() != DRMF_SUCCESS)
        ASSERT(false, "drsys failed to exit");
    drsym_exit();
    drx_exit();
    drmgr_exit();
    hashtable_delete(&nconsts_table);
}
Ejemplo n.º 14
0
static void exit_event(void)
{
    if (outfile != INVALID_FILE) {
        dr_fprintf(outfile, "exit while recording enabled\n");
        dr_close_file(outfile);
        outfile = INVALID_FILE;
    }
    drsym_exit();
    drreg_exit();
    drwrap_exit();
    drutil_exit();
    drmgr_exit();
}
Ejemplo n.º 15
0
void memtrace_exit_event()
{

	md_delete_list(head,false);
    code_cache_exit();
    drmgr_unregister_tls_field(tls_index);
	if (log_mode){
		dr_close_file(logfile);
	}
    dr_mutex_destroy(mutex);
	dr_global_free(client_arg, sizeof(client_arg_t));
    drutil_exit();
    drmgr_exit();
}
Ejemplo n.º 16
0
static void onExit() {
  dr_printf( "In onExit()\n" );

  // Clean up hashtable.
  hashtable_delete( &wraps );

  // Clean up output.
  dr_mutex_destroy( outMutex );
  dr_close_file( outFile );

  // Clean up extensions.
  drwrap_exit();
  drsym_exit();
}
Ejemplo n.º 17
0
static void
thread_data_destroy(void *drcontext, per_thread_t *data)
{
    /* destroy the bb table */
    bb_table_destroy(data->bb_table, data);
    dr_close_file(data->log);
    /* free thread data */
    if (drcontext == NULL) {
        ASSERT(!drcov_per_thread, "drcov_per_thread should not be set");
        dr_global_free(data, sizeof(*data));
    } else {
        ASSERT(drcov_per_thread, "drcov_per_thread is not set");
        dr_thread_free(drcontext, data, sizeof(*data));
    }
}
Ejemplo n.º 18
0
static void
event_exit(void)
{
    /* ensure our file was not closed by the app */
    if (!dr_file_seek(file, 0, DR_SEEK_SET))
        dr_fprintf(STDERR, "seek error in exit event\n");
    dr_close_file(file);
    dr_fprintf(STDERR, "file separation check\n");

    /* i#1213: test float i/o.
     * Technically we should save fpstate (for detach) but we're not bothering.
     */
    dr_fprintf(STDERR, "float i/o test: %6.5g\n", 3.1415916);

    dr_fprintf(STDERR, "done\n");
}
Ejemplo n.º 19
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;
}
Ejemplo n.º 20
0
int
main(int argc, char *argv[])
{
    file_t f;
    void *drcontext = dr_standalone_init();
    if (argc != 2) {
        dr_fprintf(STDERR, "Usage: %s <objfile>\n", argv[0]);
        return 1;
    }
    f = dr_open_file(argv[1], DR_FILE_READ | DR_FILE_ALLOW_LARGE);
    if (f == INVALID_FILE) {
        dr_fprintf(STDERR, "Error opening %s\n", argv[1]);
        return 1;
    }
    read_data(f, drcontext);
    dr_close_file(f);
    return 0;
}
Ejemplo n.º 21
0
static void
shared_memory_exit(void)
{
    int pos;
    stats->exited = true;
    /* close down statistics */
    UnmapViewOfFile(shared_view);
    dr_close_file(shared_map);
    /* decrement count, then unmap */
    do {
        pos = atomic_swap(shared_count, (uint) -1);
        /* if get -1 back, someone else is looking at it */
    } while (pos == -1);
    /* now increment it */
    atomic_swap(shared_count, pos-1);
    UnmapViewOfFile(shared_view_count);
    CloseHandle(shared_map_count);
}
Ejemplo n.º 22
0
void instrace_init(client_id_t id, const char * name, const char * arguments)
{

	file_t in_file;
	file_t out_file;
	int i;
	char logfilename[MAX_STRING_LENGTH];

    drmgr_init();
    drutil_init();
    client_id = id;

	DR_ASSERT(parse_commandline_args(arguments)==true);

	head = md_initialize();
	instrace_head = md_initialize();

	if(client_arg->filter_mode != FILTER_NONE){
		in_file = dr_open_file(client_arg->filter_filename,DR_FILE_READ);
		DR_ASSERT(in_file != INVALID_FILE);
		md_read_from_file(head,in_file,false);
		dr_close_file(in_file);
	}

	mutex = dr_mutex_create();
    tls_index = drmgr_register_tls_field();
    DR_ASSERT(tls_index != -1);
    code_cache_init();

	if (log_mode){
		populate_conv_filename(logfilename, logdir, name, NULL);
		logfile = dr_open_file(logfilename, DR_FILE_WRITE_OVERWRITE);
	}
	strncpy(ins_pass_name, name, MAX_STRING_LENGTH);

	for(i=OP_FIRST;i<=OP_LAST; i++){
		opcodes_visited[i] = false;
	}

	
	

}
Ejemplo n.º 23
0
static void post_func_cb(void * wrapcxt, void ** user_data){
	//do the dump for the written app_pcs
	int i = 0;
	file_t dump_file;
	char * dump_filename;

	DEBUG_PRINT("post function call for dumping\n");

	/* if for same memdump it is overwritten */
		for (i = 0; i < write_region_size; i++){
			dump_filename = get_mem_dump_filename(write_regions[i].base_pc, write_regions[i].size, true, written_count);
			dump_file = dr_open_file(dump_filename, DR_FILE_WRITE_OVERWRITE);
			do_mem_dump(dump_file, write_regions[i].base_pc, write_regions[i].size);
			dr_global_free(dump_filename, sizeof(char) * MAX_STRING_LENGTH);
			dr_close_file(dump_file);
		}
		written_count++;
	

}
Ejemplo n.º 24
0
void dr_exit() {
  dr_fprintf(STDERR, "info: stopping dtrace..\n");

  tb_delete(trace_buffer);
  dr_mutex_destroy(trace_buffer_lock);

  dr_close_file(trace_file);
  dr_mutex_destroy(trace_file_lock);

  hashtable_delete(&tags);
  dr_mutex_destroy(tags_lock);

  dr_unregister_exit_event(&dr_exit);
  dr_unregister_thread_init_event(&handle_thread_init);
  dr_unregister_thread_exit_event(&handle_thread_exit);
  dr_unregister_bb_event(&handle_bb);
  dr_unregister_trace_event(&handle_trace);
  dr_unregister_delete_event(&handle_delete);
  dr_unregister_signal_event(&handle_signal);
  dr_unregister_restore_state_event(&handle_restore_state);
}
Ejemplo n.º 25
0
/*
 * Wrap the log_set_file() function in testsc.c, and respond to it by
 * opening or closing log files.
 */
static void wrap_logsetfile(void *wrapctx, void **user_data)
{
    if (outfile) {
        dr_close_file(outfile);
        outfile = INVALID_FILE;
    }

    const char *outfilename = drwrap_get_arg(wrapctx, 0);
    if (outfilename) {
        outfile = dr_open_file(outfilename, DR_FILE_WRITE_OVERWRITE);
        DR_ASSERT(outfile != INVALID_FILE);
    }

    /*
     * Reset the allocation list to empty, whenever we open or close a
     * log file.
     */
    while (alloc_ends->next != alloc_ends)
        free_allocation(alloc_ends->next);
    next_alloc_index = 0;
}
Ejemplo n.º 26
0
void memdump_exit_event(void)
{

	int i = 0;

	md_delete_list(filter_head, false);
	md_delete_list(done_head, false);
	md_delete_list(app_pc_head, false);

	dr_global_free(client_arg, sizeof(client_arg_t));
	drmgr_unregister_tls_field(tls_index);
	if (log_mode){
		dr_close_file(logfile);
	}
	for (i = 0; i < instr_clone_amount; i++){
		instr_destroy(dr_get_current_drcontext(), instr_clones[i]);
	}
	dr_mutex_destroy(mutex);
	drutil_exit();
	drmgr_exit();
	drwrap_exit();

}
Ejemplo n.º 27
0
void inscount_exit_event(void)
{
#ifdef SHOW_RESULTS
	char msg[512];
	int len;
	len = dr_snprintf(msg, sizeof(msg)/sizeof(msg[0]),
					  "process name - %s\nInstrumentation results: %llu instructions executed - %d bbcount\n"
					  ,dr_get_application_name(),global_count,bbcount);
	DR_ASSERT(len > 0);
	NULL_TERMINATE(msg);
	DISPLAY_STRING(msg);
#endif /* SHOW_RESULTS */

	md_delete_list(head,false);
	dr_global_free(client_arg, sizeof(client_arg_t));

	if (log_mode){
		dr_close_file(logfile);
	}

	drmgr_exit();

}
Ejemplo n.º 28
0
/* Sets modcache->has_debug_info.
 * No lock is needed as we assume the caller hasn't exposed modcache outside this
 * thread yet.
 */
static bool
symcache_read_symfile(const module_data_t *mod, const char *modname,
                      mod_cache_t *modcache)
{
    hashtable_t *symtable = &modcache->table;
    bool res = false;
    const char *line, *next_line;
    char symbol[MAX_SYMLEN];
    size_t offs;
    uint64 map_size;
    size_t actual_size;
    bool ok;
    void *map = NULL;
    char symfile[MAXIMUM_PATH];
    file_t f;

    symcache_get_filename(modname, symfile, BUFFER_SIZE_ELEMENTS(symfile));
    f = dr_open_file(symfile, DR_FILE_READ);
    if (f == INVALID_FILE)
        goto symcache_read_symfile_done;
    LOG(2, "processing symbol cache file for %s\n", modname);
    /* we avoid having to do our own buffering by just mapping the whole file */
    ok = dr_file_size(f, &map_size);
    if (ok) {
        actual_size = (size_t) map_size;
        ASSERT(actual_size == map_size, "file size too large");
        map = dr_map_file(f, &actual_size, 0, NULL, DR_MEMPROT_READ, 0);
    }
    if (!ok || map == NULL || actual_size < map_size) {
        NOTIFY_ERROR("Error mapping symcache file for %s"NL, modname);
        goto symcache_read_symfile_done;
    }
    if (strncmp((char *)map, SYMCACHE_FILE_HEADER, strlen(SYMCACHE_FILE_HEADER)) != 0) {
        WARN("WARNING: symbol cache file is corrupted\n");
        goto symcache_read_symfile_done;
    }
    /* i#1057: We use dr_sscanf() because sscanf() from ntdll will call strlen()
     * and read off the end of the mapped file if it doesn't hit a null.
     */
    if (dr_sscanf((char *)map + strlen(SYMCACHE_FILE_HEADER) + 1, "%d",
                  (uint *)&offs) != 1 ||
        /* neither forward nor backward compatible */
        offs != SYMCACHE_VERSION) {
        WARN("WARNING: symbol cache file has wrong version\n");
        goto symcache_read_symfile_done;
    }
    line = strchr((char *) map, '\n');
    if (line != NULL)
        line++;

    if (line != NULL) {
        /* Module consistency checks */
        uint cache_file_size;
        uint64 module_file_size;
        uint timestamp;
#ifdef WINDOWS
        version_number_t file_version;
        version_number_t product_version;
        uint checksum;
        size_t module_internal_size;
        if (dr_sscanf(line, "%u,"UINT64_FORMAT_STRING","UINT64_FORMAT_STRING","
                      UINT64_FORMAT_STRING",%u,%u,%lu",
                      &cache_file_size, &module_file_size, &file_version.version,
                      &product_version.version, &checksum, &timestamp,
                      &module_internal_size) != 7) {
            WARN("WARNING: %s symbol cache file has bad consistency header\n", modname);
            goto symcache_read_symfile_done;
        }
        if (module_file_size != modcache->module_file_size ||
            file_version.version != modcache->file_version.version ||
            product_version.version != modcache->product_version.version ||
            checksum != modcache->checksum ||
            timestamp != modcache->timestamp ||
            module_internal_size != modcache->module_internal_size) {
            LOG(1, "module version mismatch: %s symbol cache file is stale\n", modname);
            LOG(2, "\t"UINT64_FORMAT_STRING" vs "UINT64_FORMAT_STRING", "
                UINT64_FORMAT_STRING" vs "UINT64_FORMAT_STRING", "
                UINT64_FORMAT_STRING" vs "UINT64_FORMAT_STRING", "
                "%u vs %u, %u vs %u, %lu vs %lu\n",
                module_file_size, modcache->module_file_size,
                file_version.version, modcache->file_version.version,
                product_version.version, modcache->product_version.version,
                checksum, modcache->checksum,
                timestamp, modcache->timestamp,
                module_internal_size, modcache->module_internal_size);
            goto symcache_read_symfile_done;
        }
#elif defined(LINUX)
        if (dr_sscanf(line, "%u,"UINT64_FORMAT_STRING",%u",
                      &cache_file_size, &module_file_size, &timestamp) != 3) {
            WARN("WARNING: %s symbol cache file has bad consistency header\n", modname);
            goto symcache_read_symfile_done;
        }
        if (module_file_size != modcache->module_file_size ||
            timestamp != modcache->timestamp) {
            LOG(1, "module version mismatch: %s symbol cache file is stale\n", modname);
            goto symcache_read_symfile_done;
        }
#elif defined(MACOS)
        uint current_version;
        uint compatibility_version;
        byte uuid[16];
        /* XXX: if dr_sscanf supported %n maybe we could split these into
         * separate scans on the same string and share code w/ Linux.
         */
        if (dr_sscanf(line, "%u,"UINT64_FORMAT_STRING",%u,%u,%u,%x,%x,%x,%x",
                      &cache_file_size, &module_file_size, &timestamp,
                      &current_version, &compatibility_version,
                      (uint*)(&uuid[0]), (uint*)(&uuid[4]),
                      (uint*)(&uuid[8]), (uint*)(&uuid[12])) != 9) {
            WARN("WARNING: %s symbol cache file has bad consistency header B\n", modname);
            goto symcache_read_symfile_done;
        }
        if (current_version != modcache->current_version ||
            compatibility_version != modcache->compatibility_version ||
            memcmp(uuid, modcache->uuid, sizeof(uuid)) != 0) {
            LOG(1, "module version mismatch: %s symbol cache file is stale\n", modname);
            goto symcache_read_symfile_done;
        }
#endif
        /* We could go further w/ CRC or even MD5 but not worth it for dev tool */
        if (cache_file_size != (uint)map_size) {
            WARN("WARNING: %s symbol cache file is corrupted: map=%d vs file=%d\n",
                 modname, (uint)map_size, cache_file_size);
            goto symcache_read_symfile_done;
        }
    }
    line = strchr(line, '\n');
    if (line != NULL)
        line++;
    if (line != NULL) {
        uint has_debug_info;
        if (dr_sscanf(line, "%u", &has_debug_info) != 1) {
            WARN("WARNING: %s symbol cache file has bad consistency header\n", modname);
            goto symcache_read_symfile_done;
        }
        if (has_debug_info) {
            /* We assume that the current availability of debug info doesn't matter */
            modcache->has_debug_info = true;
        } else {
            /* We delay the costly check for symbols until we've read the symcache
             * b/c if its entry indicates symbols we don't need to look
             */
            if (module_has_symbols(mod)) {
                LOG(1, "module now has debug info: %s symbol cache is stale\n", modname);
                goto symcache_read_symfile_done;
            }
        }
    }
    line = strchr(line, '\n');
    if (line != NULL)
        line++;

    symbol[0] = '\0';
    for (; line != NULL && line < ((char *)map) + map_size; line = next_line) {
        const char *comma = strchr(line, ',');
        const char *newline = strchr(line, '\n');
        size_t symlen = (comma != NULL ? comma - line : 0);
        if (newline == NULL) {
            next_line = ((char *)map) + map_size + 1; /* handle EOF w/o trailing \n */
        } else {
            next_line = newline + 1;
        }
        if (symlen > 0 && symlen < MAX_SYMLEN) {
            strncpy(symbol, line, symlen);
            symbol[symlen] = '\0';
        }
        if (comma != NULL && symlen < MAX_SYMLEN && symbol[0] != '\0' &&
            dr_sscanf(comma, ",0x%x", (uint *)&offs) == 1) {
#ifdef WINDOWS
            /* Guard against corrupted files that cause DrMem to crash (i#1465) */
            if (offs >= modcache->module_internal_size) {
                /* This one we want to know about */
                NOTIFY("SYMCACHE ERROR: %s file has too-large entry "PIFX" for %s"NL,
                       modname, offs, symbol);
                goto symcache_read_symfile_done;
            }
#endif
            symcache_symbol_add(modname, symtable, symbol, offs);
        } else {
            WARN("WARNING: malformed symbol cache line \"%.*s\"\n",
                 next_line - line - 1, line);
            /* We abort in case there were two dueling writes to the file
             * and it somehow got past the self-consistency check,
             * putting a header in the middle of the file, and we can't
             * trust subsequent lines since they may belong to a different
             * version of the module
             */
            break; /* res should still be true */
        }
    }
    res = true;
 symcache_read_symfile_done:
    if (map != NULL)
        dr_unmap_file(map, actual_size);
    if (f != INVALID_FILE)
        dr_close_file(f);
    if (!res)
        modcache->has_debug_info = module_has_symbols(mod);

    return res;
}
Ejemplo n.º 29
0
/* caller must hold symcache_lock */
static void
symcache_write_symfile(const char *modname, mod_cache_t *modcache)
{
    uint i;
    file_t f;
    hashtable_t *symtable = &modcache->table;
    char buf[SYMCACHE_BUFFER_SIZE];
    size_t sofar = 0;
    ssize_t len;
    size_t bsz = BUFFER_SIZE_ELEMENTS(buf);
    size_t filesz_loc;
    char symfile[MAXIMUM_PATH];
    char symfile_tmp[MAXIMUM_PATH];
    int64 file_size;

    ASSERT(dr_mutex_self_owns(symcache_lock), "missing symcache lock");

    /* if from file, we assume it's a waste of time to re-write file:
     * the version matched after all, unless we appended to it.
     */
    if (modcache->from_file && !modcache->appended)
        return;
    if (symtable->entries == 0)
        return; /* nothing to write */

    /* Open the temp symcache that we will rename.  */
    symcache_get_filename(modname, symfile, BUFFER_SIZE_ELEMENTS(symfile));
    f = INVALID_FILE;
    i = 0;
    while (f == INVALID_FILE && i < SYMCACHE_MAX_TMP_TRIES) {
        dr_snprintf(symfile_tmp, BUFFER_SIZE_ELEMENTS(symfile_tmp),
                    "%s.%04d.tmp", symfile, i);
        NULL_TERMINATE_BUFFER(symfile_tmp);
        f = dr_open_file(symfile_tmp, DR_FILE_WRITE_REQUIRE_NEW);
        i++;
    }
    if (f == INVALID_FILE) {
        NOTIFY("WARNING: Unable to create symcache temp file %s"NL,
               symfile_tmp);
        return;
    }

    BUFFERED_WRITE(f, buf, bsz, sofar, len, "%s %d\n",
                   SYMCACHE_FILE_HEADER, SYMCACHE_VERSION);
    /* Leave room for file size for self-consistency check */
    filesz_loc = sofar;  /* XXX: Assumes that the buffer hasn't been flushed. */
    BUFFERED_WRITE(f, buf, bsz, sofar, len,
                   "%"STRINGIFY(SYMCACHE_SIZE_DIGITS)"u,", 0);
#ifdef WINDOWS
    BUFFERED_WRITE(f, buf, bsz, sofar, len,
                   UINT64_FORMAT_STRING","UINT64_FORMAT_STRING","
                   UINT64_FORMAT_STRING",%u,%u,%lu\n",
                   modcache->module_file_size, modcache->file_version.version,
                   modcache->product_version.version,
                   modcache->checksum, modcache->timestamp,
                   modcache->module_internal_size);
#else
    BUFFERED_WRITE(f, buf, bsz, sofar, len, UINT64_FORMAT_STRING",%u",
                   modcache->module_file_size, modcache->timestamp);
# ifdef MACOS
    BUFFERED_WRITE(f, buf, bsz, sofar, len, ",%u,%u,",
                   modcache->current_version, modcache->compatibility_version);
    /* For easy sscanf we print as 4 ints */
    for (i = 0; i < 4; i++)
        BUFFERED_WRITE(f, buf, bsz, sofar, len, "%08x,", *(int*)(&modcache->uuid[i*4]));
# endif
    BUFFERED_WRITE(f, buf, bsz, sofar, len, "\n");
#endif
    BUFFERED_WRITE(f, buf, bsz, sofar, len, "%u\n", modcache->has_debug_info);
    for (i = 0; i < HASHTABLE_SIZE(symtable->table_bits); i++) {
        hash_entry_t *he;
        for (he = symtable->table[i]; he != NULL; he = he->next) {
            offset_list_t *olist = (offset_list_t *) he->payload;
            offset_entry_t *e;
            if (olist == NULL)
                continue;
            /* skip symbol in dup entries to save space */
            BUFFERED_WRITE(f, buf, bsz, sofar, len, "%s", he->key);
            e = olist->list;
            while (e != NULL) {
                BUFFERED_WRITE(f, buf, bsz, sofar, len, ",0x%x\n", e->offs);
                e = e->next;
            }
        }
    }

    /* now update size */
    FLUSH_BUFFER(f, buf, sofar);
    if ((file_size = dr_file_tell(f)) < 0 ||
        dr_snprintf(buf, BUFFER_SIZE_ELEMENTS(buf),
                    "%"STRINGIFY(SYMCACHE_SIZE_DIGITS)"u", (uint)file_size) < 0 ||
        !dr_file_seek(f, filesz_loc, DR_SEEK_SET) ||
        dr_write_file(f, buf, SYMCACHE_SIZE_DIGITS) != SYMCACHE_SIZE_DIGITS) {
        /* If any steps fail, warn and give up. */
        NOTIFY("WARNING: Unable to write symcache file size."NL);
        dr_close_file(f);
        dr_delete_file(symfile_tmp);
        return;
    } else {
        LOG(3, "Wrote symcache %s file size %u to pos "SZFMT"\n",
            modname, (uint)file_size, filesz_loc);
        ASSERT(strlen(buf) <= SYMCACHE_SIZE_DIGITS, "not enough space for file size");
    }

    dr_close_file(f);

    if (!dr_rename_file(symfile_tmp, symfile, /*replace*/true)) {
        NOTIFY_ERROR("WARNING: Failed to rename the symcache file."NL);
        dr_delete_file(symfile_tmp);
    }
}
Ejemplo n.º 30
0
void
init_IPC(int idx, const char *path, bool standalone)
{
    DR_ASSERT(idx < MAX_IPC_CHANNELS);

    int path_len, pad_len, shmem_len, fullfifo_len, emptyfifo_len;
    ipc_channel_t *channel = &IPC[idx];

    channel->standalone = standalone;

    /* Initialize channel state */
    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 = NULL;
    node->waiting = false;
    node->thread_id = 0;
    channel->ticket_queue.head = node;
    channel->ticket_queue.tail = node;
    channel->ticket_queue.locked = false;
    channel->queue_lock = dr_mutex_create();

    channel->shared_mem = NULL;
    channel->full_fifo = -1;
    channel->empty_fifo = -1;
    channel->shmem_buf_idx = 0;

    for(uint i=0; i<sizeof(channel->empty_buf_idx)/sizeof(channel->empty_buf_idx[0]); ++i)
        channel->empty_buf_idx[i] = true;

    channel->last_active_tid = 0;
    channel->initialized     = false;

    if (standalone)
    {
        /* mimic shared memory writes */
        channel->shared_mem = dr_raw_mem_alloc(sizeof(Sigil2DBISharedData),
                                               DR_MEMPROT_READ | DR_MEMPROT_WRITE,
                                               NULL);
        if (channel->shared_mem == NULL)
            DR_ABORT_MSG("Failed to allocate pseudo shared memory buffer\n");
        for (int i=0; i<SIGIL2_IPC_BUFFERS; ++i)
            channel->shared_mem->eventBuffers[i].used = 0;
    }
    else
    {
        /* Connect to Sigil2 */
        path_len = strlen(path);
        pad_len = 4; /* extra space for '/', 2x'-', '\0' */
        shmem_len     = (path_len + pad_len +
                         sizeof(SIGIL2_IPC_SHMEM_BASENAME) +
                         sizeof(STRINGIFY(MAX_IPC_CHANNELS)));
        fullfifo_len  = (path_len + pad_len +
                         sizeof(SIGIL2_IPC_FULLFIFO_BASENAME) +
                         sizeof(STRINGIFY(MAX_IPC_CHANNELS)));
        emptyfifo_len = (path_len + pad_len +
                         sizeof(SIGIL2_IPC_EMPTYFIFO_BASENAME) +
                         sizeof(STRINGIFY(MAX_IPC_CHANNELS)));

        /* set up names of IPC files */
        char shmem_name[shmem_len];
        sprintf(shmem_name, "%s/%s-%d", path, SIGIL2_IPC_SHMEM_BASENAME, idx);

        char fullfifo_name[fullfifo_len];
        sprintf(fullfifo_name, "%s/%s-%d", path, SIGIL2_IPC_FULLFIFO_BASENAME, idx);

        char emptyfifo_name[emptyfifo_len];
        sprintf(emptyfifo_name, "%s/%s-%d", path, SIGIL2_IPC_EMPTYFIFO_BASENAME, idx);


        /* initialize read/write pipes */
        channel->empty_fifo = open_sigil2_fifo(emptyfifo_name, DR_FILE_READ);
        channel->full_fifo = open_sigil2_fifo(fullfifo_name, DR_FILE_WRITE_ONLY);

        /* no need to timeout on file because shared memory MUST be initialized
         * by Sigil2 before the fifos are created */
        file_t map_file = dr_open_file(shmem_name, DR_FILE_READ|DR_FILE_WRITE_APPEND);
        if(map_file == INVALID_FILE)
            DR_ABORT_MSG("error opening shared memory file");

        size_t mapped_size = sizeof(Sigil2DBISharedData);
        channel->shared_mem = dr_map_file(map_file, &mapped_size,
                                          0, 0, /* assume this is not honored */
                                          DR_MEMPROT_READ|DR_MEMPROT_WRITE, 0);

        if(mapped_size != sizeof(Sigil2DBISharedData) || channel->shared_mem == NULL)
            DR_ABORT_MSG("error mapping shared memory");

        dr_close_file(map_file);
    }

    channel->initialized = true;
}