static void
code_cache_init(void)
{
void *drcontext;
instrlist_t *ilist;
instr_t *where;
byte *end;
drcontext = dr_get_current_drcontext();
code_cache =
dr_nonheap_alloc(page_size, DR_MEMPROT_READ | DR_MEMPROT_WRITE | DR_MEMPROT_EXEC);
ilist = instrlist_create(drcontext);
/* The lean procecure simply performs a clean call, and then jumps back. */
/* Jump back to DR's code cache. */
where = INSTR_CREATE_jmp_ind(drcontext, opnd_create_reg(DR_REG_XCX));
instrlist_meta_append(ilist, where);
/* Clean call */
dr_insert_clean_call(drcontext, ilist, where, (void *)clean_call, false, 0);
/* Encode the instructions into memory and clean up. */
end = instrlist_encode(drcontext, ilist, code_cache, false);
DR_ASSERT((size_t)(end - code_cache) < page_size);
instrlist_clear_and_destroy(drcontext, ilist);
/* Set the memory as just +rx now. */
dr_memory_protect(code_cache, page_size, DR_MEMPROT_READ | DR_MEMPROT_EXEC);
}