static void custom_windows_test(void) { void *array; MEMORY_BASIC_INFORMATION mbi; bool ok; dr_fprintf(STDERR, " testing custom windows alloc...."); array = dr_custom_alloc(NULL, DR_ALLOC_NON_HEAP | DR_ALLOC_NON_DR | DR_ALLOC_RESERVE_ONLY, PAGE_SIZE*2, DR_MEMPROT_NONE, NULL); if (array == NULL) dr_fprintf(STDERR, "error: unable to reserve\n"); if (dr_virtual_query(array, &mbi, sizeof(mbi)) != sizeof(mbi)) dr_fprintf(STDERR, "error: unable to query prot\n"); /* 0 is sometimes returned (see VirtualQuery docs) */ if (mbi.Protect != PAGE_NOACCESS && mbi.Protect != 0) dr_fprintf(STDERR, "error: wrong reserve prot %x\n", mbi.Protect); if (mbi.State != MEM_RESERVE) dr_fprintf(STDERR, "error: memory wasn't reserved\n"); array = dr_custom_alloc(NULL, DR_ALLOC_NON_HEAP | DR_ALLOC_NON_DR | DR_ALLOC_COMMIT_ONLY | DR_ALLOC_FIXED_LOCATION, PAGE_SIZE, DR_MEMPROT_READ | DR_MEMPROT_WRITE, array); if (array == NULL) dr_fprintf(STDERR, "error: unable to commit\n"); if (dr_virtual_query(array, &mbi, sizeof(mbi)) != sizeof(mbi)) dr_fprintf(STDERR, "error: unable to query prot\n"); if (mbi.Protect != PAGE_READWRITE) dr_fprintf(STDERR, "error: wrong commit prot %x\n", mbi.Protect); if (mbi.State != MEM_COMMIT || mbi.RegionSize != PAGE_SIZE) dr_fprintf(STDERR, "error: memory wasn't committed\n"); write_array(array); ok = dr_custom_free(NULL, DR_ALLOC_NON_HEAP | DR_ALLOC_NON_DR | DR_ALLOC_COMMIT_ONLY, array, PAGE_SIZE); if (!ok) dr_fprintf(STDERR, "error: failed to de-commit\n"); if (dr_virtual_query(array, &mbi, sizeof(mbi)) != sizeof(mbi)) dr_fprintf(STDERR, "error: unable to query prot\n"); /* 0 is sometimes returned (see VirtualQuery docs) */ if (mbi.Protect != PAGE_NOACCESS && mbi.Protect != 0) dr_fprintf(STDERR, "error: wrong decommit prot %x\n", mbi.Protect); if (mbi.State != MEM_RESERVE) dr_fprintf(STDERR, "error: memory wasn't de-committed %x\n", mbi.State); ok = dr_custom_free(NULL, DR_ALLOC_NON_HEAP | DR_ALLOC_NON_DR | DR_ALLOC_RESERVE_ONLY, array, PAGE_SIZE*2); if (!ok) dr_fprintf(STDERR, "error: failed to un-reserve\n"); if (dr_virtual_query(array, &mbi, sizeof(mbi)) != sizeof(mbi)) dr_fprintf(STDERR, "error: unable to query prot\n"); /* 0 is sometimes returned (see VirtualQuery docs) */ if (mbi.Protect != PAGE_NOACCESS && mbi.Protect != 0) dr_fprintf(STDERR, "error: wrong unreserve prot %x\n", mbi.Protect); if (mbi.State != MEM_FREE) dr_fprintf(STDERR, "error: memory wasn't un-reserved\n"); dr_fprintf(STDERR, "success\n"); }
static void custom_test(void) { void *drcontext = dr_get_current_drcontext(); void *array, *preferred; size_t size; uint prot; dr_fprintf(STDERR, " testing custom memory alloc...."); /* test global */ array = dr_custom_alloc(NULL, 0, SIZE, 0, NULL); write_array(array); dr_custom_free(NULL, 0, array, SIZE); array = dr_custom_alloc(NULL, DR_ALLOC_CACHE_REACHABLE, SIZE, 0, NULL); ASSERT(reachable_from_client(array)); write_array(array); dr_custom_free(NULL, DR_ALLOC_CACHE_REACHABLE, array, SIZE); /* test thread-local */ array = dr_custom_alloc(drcontext, DR_ALLOC_THREAD_PRIVATE, SIZE, 0, NULL); write_array(array); dr_custom_free(drcontext, DR_ALLOC_THREAD_PRIVATE, array, SIZE); array = dr_custom_alloc(drcontext, DR_ALLOC_THREAD_PRIVATE|DR_ALLOC_CACHE_REACHABLE, SIZE, 0, NULL); ASSERT(reachable_from_client(array)); write_array(array); dr_custom_free(drcontext, DR_ALLOC_THREAD_PRIVATE|DR_ALLOC_CACHE_REACHABLE, array, SIZE); /* test non-heap */ array = dr_custom_alloc(NULL, DR_ALLOC_NON_HEAP, PAGE_SIZE, DR_MEMPROT_READ|DR_MEMPROT_WRITE, NULL); write_array(array); dr_custom_free(NULL, DR_ALLOC_NON_HEAP, array, PAGE_SIZE); /* Find a free region of memory without inadvertently "preloading" it. * First probe by allocating 2x the platform allocation alignment unit. */ array = dr_custom_alloc(NULL, DR_ALLOC_NON_HEAP | DR_ALLOC_NON_DR, HINT_ALLOC_SIZE, DR_MEMPROT_READ|DR_MEMPROT_WRITE, NULL); /* Then select the second half as the preferred address for the allocation test. */ preferred = (void *)((ptr_uint_t)array + HINT_OFFSET); /* Free the probe allocation. */ dr_custom_free(NULL, DR_ALLOC_NON_HEAP | DR_ALLOC_NON_DR, array, HINT_ALLOC_SIZE); /* Now `preferred` is guaranteed to be available. */ array = dr_custom_alloc(NULL, DR_ALLOC_NON_HEAP|DR_ALLOC_FIXED_LOCATION, PAGE_SIZE, DR_MEMPROT_READ|DR_MEMPROT_WRITE, preferred); ASSERT(array == preferred); write_array(array); dr_custom_free(NULL, DR_ALLOC_NON_HEAP|DR_ALLOC_FIXED_LOCATION, array, PAGE_SIZE); array = dr_custom_alloc(NULL, DR_ALLOC_NON_HEAP|DR_ALLOC_CACHE_REACHABLE, PAGE_SIZE, DR_MEMPROT_READ|DR_MEMPROT_WRITE, NULL); ASSERT(reachable_from_client(array)); write_array(array); dr_custom_free(NULL, DR_ALLOC_NON_HEAP|DR_ALLOC_CACHE_REACHABLE, array, PAGE_SIZE); array = dr_custom_alloc(NULL, DR_ALLOC_NON_HEAP|DR_ALLOC_LOW_2GB, PAGE_SIZE, DR_MEMPROT_READ|DR_MEMPROT_WRITE, NULL); #ifdef X64 ASSERT((ptr_uint_t)array < 0x80000000); #endif write_array(array); dr_custom_free(NULL, DR_ALLOC_NON_HEAP|DR_ALLOC_LOW_2GB, array, PAGE_SIZE); array = dr_custom_alloc(NULL, DR_ALLOC_NON_HEAP|DR_ALLOC_NON_DR, PAGE_SIZE, DR_MEMPROT_READ|DR_MEMPROT_WRITE, NULL); write_array(array); dr_custom_free(NULL, DR_ALLOC_NON_HEAP|DR_ALLOC_NON_DR, array, PAGE_SIZE); array = dr_custom_alloc(NULL, DR_ALLOC_NON_HEAP, PAGE_SIZE, DR_MEMPROT_READ|DR_MEMPROT_WRITE|DR_MEMPROT_EXEC, NULL); ASSERT(dr_query_memory((byte *)array, NULL, &size, &prot) && size == PAGE_SIZE && prot == (DR_MEMPROT_READ|DR_MEMPROT_WRITE| DR_MEMPROT_EXEC)); write_array(array); dr_custom_free(NULL, DR_ALLOC_NON_HEAP, array, PAGE_SIZE); dr_fprintf(STDERR, "success\n"); }
static void custom_test(void) { void *drcontext = dr_get_current_drcontext(); void *array; size_t size; uint prot; dr_fprintf(STDERR, " testing custom memory alloc...."); /* test global */ array = dr_custom_alloc(NULL, 0, SIZE, 0, NULL); write_array(array); dr_custom_free(NULL, 0, array, SIZE); array = dr_custom_alloc(NULL, DR_ALLOC_CACHE_REACHABLE, SIZE, 0, NULL); ASSERT(reachable_from_client(array)); write_array(array); dr_custom_free(NULL, DR_ALLOC_CACHE_REACHABLE, array, SIZE); /* test thread-local */ array = dr_custom_alloc(drcontext, DR_ALLOC_THREAD_PRIVATE, SIZE, 0, NULL); write_array(array); dr_custom_free(drcontext, DR_ALLOC_THREAD_PRIVATE, array, SIZE); array = dr_custom_alloc(drcontext, DR_ALLOC_THREAD_PRIVATE|DR_ALLOC_CACHE_REACHABLE, SIZE, 0, NULL); ASSERT(reachable_from_client(array)); write_array(array); dr_custom_free(drcontext, DR_ALLOC_THREAD_PRIVATE|DR_ALLOC_CACHE_REACHABLE, array, SIZE); /* test non-heap */ array = dr_custom_alloc(NULL, DR_ALLOC_NON_HEAP, PAGE_SIZE, DR_MEMPROT_READ|DR_MEMPROT_WRITE, NULL); write_array(array); dr_custom_free(NULL, DR_ALLOC_NON_HEAP, array, PAGE_SIZE); array = dr_custom_alloc(NULL, DR_ALLOC_NON_HEAP|DR_ALLOC_FIXED_LOCATION, PAGE_SIZE, DR_MEMPROT_READ|DR_MEMPROT_WRITE, PREFERRED_ADDR); ASSERT(array == (void *)PREFERRED_ADDR); write_array(array); dr_custom_free(NULL, DR_ALLOC_NON_HEAP|DR_ALLOC_FIXED_LOCATION, array, PAGE_SIZE); array = dr_custom_alloc(NULL, DR_ALLOC_NON_HEAP|DR_ALLOC_CACHE_REACHABLE, PAGE_SIZE, DR_MEMPROT_READ|DR_MEMPROT_WRITE, NULL); ASSERT(reachable_from_client(array)); write_array(array); dr_custom_free(NULL, DR_ALLOC_NON_HEAP|DR_ALLOC_CACHE_REACHABLE, array, PAGE_SIZE); array = dr_custom_alloc(NULL, DR_ALLOC_NON_HEAP|DR_ALLOC_LOW_2GB, PAGE_SIZE, DR_MEMPROT_READ|DR_MEMPROT_WRITE, NULL); #ifdef X64 ASSERT((ptr_uint_t)array < 0x80000000); #endif write_array(array); dr_custom_free(NULL, DR_ALLOC_NON_HEAP|DR_ALLOC_LOW_2GB, array, PAGE_SIZE); array = dr_custom_alloc(NULL, DR_ALLOC_NON_HEAP|DR_ALLOC_NON_DR, PAGE_SIZE, DR_MEMPROT_READ|DR_MEMPROT_WRITE, NULL); write_array(array); dr_custom_free(NULL, DR_ALLOC_NON_HEAP|DR_ALLOC_NON_DR, array, PAGE_SIZE); array = dr_custom_alloc(NULL, DR_ALLOC_NON_HEAP, PAGE_SIZE, DR_MEMPROT_READ|DR_MEMPROT_WRITE|DR_MEMPROT_EXEC, NULL); ASSERT(dr_query_memory((byte *)array, NULL, &size, &prot) && size == PAGE_SIZE && prot == (DR_MEMPROT_READ|DR_MEMPROT_WRITE| DR_MEMPROT_EXEC)); write_array(array); dr_custom_free(NULL, DR_ALLOC_NON_HEAP, array, PAGE_SIZE); dr_fprintf(STDERR, "success\n"); }
void pre_realloc(void *wrapctx, OUT void **user_data) { malloc_t *block; malloc_t *new_block; realloc_tmp_t *tmp = NULL; void *start = drwrap_get_arg(wrapctx, 0); size_t size = (size_t)drwrap_get_arg(wrapctx, 1); void *drc = drwrap_get_drcontext(wrapctx); dr_mutex_lock(lock); /* // the first call on 64 bit and the second in 32bit */ /* // are init call, so we have to do nothing */ /* #ifdef BUILD_64 */ /* if (!realloc_init) */ /* { */ /* realloc_init++; */ /* dr_mutex_unlock(lock); */ /* return; */ /* } */ /* #else */ /* if (realloc_init++ == 1) */ /* { */ /* dr_mutex_unlock(lock); */ /* return; */ /* } */ /* #endif */ // if size == 0, realloc call free if (!size) { // this can happen if a block is alloc by a non wrap module and realloc // on a wrapped one if (!(block = search_on_tree(active_blocks, start))) { dr_mutex_unlock(lock); return; } block->free_pc = get_prev_instr_pc(drwrap_get_retaddr(wrapctx), drc); get_caller_data(&(block->free_func_pc), &(block->free_func_sym), &(block->free_module_name), drc, 1); dr_mutex_unlock(lock); return; } if (!(tmp = dr_global_alloc(sizeof(realloc_tmp_t)))) { dr_printf("dr_malloc fail\n"); dr_mutex_unlock(lock); return; } // if realloc is use like malloc save the size to set it on the post wrapping tmp->size = size; *user_data = tmp; // if start == 0, realloc call malloc if (!start) { // if a block is alloc by a wrapped function and realloc by // an unwrapped one we have to take the realloc // so when realloc is called to do a malloc is the only case // when we have to check if the module is wrapped if(!module_is_wrapped(drc)) { *user_data = NULL; dr_global_free(tmp, sizeof(*tmp)); dr_mutex_unlock(lock); return; } tmp->block = NULL; dr_mutex_unlock(lock); return; } // this can happen if the block is alloc by a non wrapped module if (!(block = search_on_tree(active_blocks, start))) { *user_data = NULL; dr_global_free(tmp, sizeof(*tmp)); dr_mutex_unlock(lock); return; } else { del_from_tree(&active_blocks, start, NULL, false); if ((new_block = dr_custom_alloc(NULL, 0, sizeof(*new_block), DR_MEMPROT_WRITE | DR_MEMPROT_READ, NULL))) { block->flag |= FREE_BY_REALLOC; block->free_pc = get_prev_instr_pc(drwrap_get_retaddr(wrapctx), drc); get_caller_data(&(block->free_func_pc), &(block->free_func_sym), &(block->free_module_name), drc, 1); block->next = old_blocks; old_blocks = block; old_blocks_count++; if (!args->console && old_blocks_count == MAX_OLD_BLOCKS) { flush_old_block(); old_blocks_count = 0; } ds_memset(new_block, 0, sizeof(*new_block)); new_block->flag |= ALLOC_BY_REALLOC; block = new_block; } else dr_printf("fail alloc\n"); block->size = size; } tmp->block = block; dr_mutex_unlock(lock); }