2015-08-21 10:04:50 +03:00
|
|
|
#ifndef UNICORN_COMMON_H_
|
|
|
|
#define UNICORN_COMMON_H_
|
|
|
|
|
|
|
|
#include "tcg.h"
|
|
|
|
|
|
|
|
// This header define common patterns/codes that will be included in all arch-sepcific
|
|
|
|
// codes for unicorns purposes.
|
|
|
|
|
|
|
|
// return true on success, false on failure
|
|
|
|
static inline bool cpu_physical_mem_read(AddressSpace *as, hwaddr addr,
|
|
|
|
uint8_t *buf, int len)
|
|
|
|
{
|
|
|
|
return !cpu_physical_memory_rw(as, addr, (void *)buf, len, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline bool cpu_physical_mem_write(AddressSpace *as, hwaddr addr,
|
2015-08-24 18:02:14 +03:00
|
|
|
const uint8_t *buf, int len)
|
2015-08-21 10:04:50 +03:00
|
|
|
{
|
|
|
|
return !cpu_physical_memory_rw(as, addr, (void *)buf, len, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void free_table(gpointer key, gpointer value, gpointer data)
|
|
|
|
{
|
|
|
|
TypeInfo *ti = (TypeInfo*) value;
|
|
|
|
g_free((void*) ti->class);
|
|
|
|
g_free((void*) ti->name);
|
|
|
|
g_free((void*) ti->parent);
|
|
|
|
g_free((void*) ti);
|
|
|
|
}
|
|
|
|
|
|
|
|
void tb_cleanup(struct uc_struct *uc);
|
|
|
|
|
|
|
|
/** Freeing common resources */
|
|
|
|
static void release_common(void *t)
|
|
|
|
{
|
|
|
|
TCGContext *s = (TCGContext *)t;
|
|
|
|
struct uc_struct* uc = s->uc;
|
2016-01-08 02:41:45 +03:00
|
|
|
CPUState *cpu;
|
2016-02-01 07:05:46 +03:00
|
|
|
#if TCG_TARGET_REG_BITS == 32
|
|
|
|
int i;
|
|
|
|
#endif
|
2015-08-21 10:04:50 +03:00
|
|
|
|
|
|
|
// Clean TCG.
|
|
|
|
TCGOpDef* def = &s->tcg_op_defs[0];
|
|
|
|
g_free(def->args_ct);
|
|
|
|
g_free(def->sorted_args);
|
|
|
|
g_free(s->tcg_op_defs);
|
2016-02-01 01:22:20 +03:00
|
|
|
|
2015-08-21 10:04:50 +03:00
|
|
|
TCGPool *po, *to;
|
|
|
|
for (po = s->pool_first; po; po = to) {
|
|
|
|
to = po->next;
|
|
|
|
g_free(po);
|
|
|
|
}
|
|
|
|
tcg_pool_reset(s);
|
|
|
|
g_hash_table_destroy(s->helpers);
|
|
|
|
|
|
|
|
// Clean memory.
|
|
|
|
phys_mem_clean(uc);
|
|
|
|
address_space_destroy(&(uc->as));
|
|
|
|
memory_free(uc);
|
|
|
|
|
|
|
|
// Clean CPU.
|
2016-01-08 02:41:45 +03:00
|
|
|
CPU_FOREACH(cpu) {
|
|
|
|
g_free(cpu->tcg_as_listener);
|
|
|
|
g_free(cpu->thread);
|
|
|
|
g_free(cpu->halt_cond);
|
|
|
|
}
|
|
|
|
|
|
|
|
OBJECT(uc->machine_state->accelerator)->ref = 1;
|
|
|
|
OBJECT(uc->machine_state)->ref = 1;
|
|
|
|
OBJECT(uc->owner)->ref = 1;
|
|
|
|
OBJECT(uc->root)->ref = 1;
|
|
|
|
|
|
|
|
object_unref(uc, OBJECT(uc->machine_state->accelerator));
|
|
|
|
object_unref(uc, OBJECT(uc->machine_state));
|
2015-08-21 10:04:50 +03:00
|
|
|
object_unref(uc, uc->cpu);
|
2016-01-08 02:41:45 +03:00
|
|
|
object_unref(uc, OBJECT(&uc->io_mem_notdirty));
|
|
|
|
object_unref(uc, OBJECT(&uc->io_mem_unassigned));
|
|
|
|
object_unref(uc, OBJECT(&uc->io_mem_rom));
|
|
|
|
object_unref(uc, OBJECT(uc->root));
|
2015-08-21 10:04:50 +03:00
|
|
|
g_hash_table_foreach(uc->type_table, free_table, uc);
|
|
|
|
|
2016-01-08 02:41:45 +03:00
|
|
|
g_free(uc->system_memory);
|
|
|
|
|
2016-01-10 18:10:00 +03:00
|
|
|
if (uc->qemu_thread_data)
|
2016-01-08 02:41:45 +03:00
|
|
|
free(uc->qemu_thread_data);
|
|
|
|
|
|
|
|
#if TCG_TARGET_REG_BITS == 32
|
2016-02-01 07:05:46 +03:00
|
|
|
for(i = 0; i < s->nb_globals; i++) {
|
2016-01-08 02:41:45 +03:00
|
|
|
TCGTemp *ts = &s->temps[i];
|
2016-01-10 18:10:00 +03:00
|
|
|
if (ts->base_type == TCG_TYPE_I64) {
|
|
|
|
if (ts->name && ((strcmp(ts->name+(strlen(ts->name)-2), "_0") == 0) ||
|
|
|
|
(strcmp(ts->name+(strlen(ts->name)-2), "_1") == 0))) {
|
2016-01-08 02:41:45 +03:00
|
|
|
free((void *)ts->name);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
qemu_mutex_destroy(&uc->qemu_global_mutex);
|
|
|
|
qemu_cond_destroy(&uc->qemu_cpu_cond);
|
|
|
|
|
2015-08-21 10:04:50 +03:00
|
|
|
// Clean cache.
|
|
|
|
tb_cleanup(uc);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void uc_common_init(struct uc_struct* uc)
|
|
|
|
{
|
|
|
|
memory_register_types(uc);
|
|
|
|
uc->write_mem = cpu_physical_mem_write;
|
|
|
|
uc->read_mem = cpu_physical_mem_read;
|
|
|
|
uc->tcg_enabled = tcg_enabled;
|
|
|
|
uc->tcg_exec_init = tcg_exec_init;
|
|
|
|
uc->cpu_exec_init_all = cpu_exec_init_all;
|
|
|
|
uc->vm_start = vm_start;
|
|
|
|
uc->memory_map = memory_map;
|
2015-11-28 04:25:53 +03:00
|
|
|
uc->memory_map_ptr = memory_map_ptr;
|
2015-08-30 07:17:30 +03:00
|
|
|
uc->memory_unmap = memory_unmap;
|
2015-08-26 23:29:54 +03:00
|
|
|
uc->readonly_mem = memory_region_set_readonly;
|
2015-08-21 10:04:50 +03:00
|
|
|
|
2015-08-31 11:00:44 +03:00
|
|
|
uc->target_page_size = TARGET_PAGE_SIZE;
|
2015-09-03 13:16:49 +03:00
|
|
|
uc->target_page_align = TARGET_PAGE_SIZE - 1;
|
2015-08-31 11:00:44 +03:00
|
|
|
|
2015-08-21 10:04:50 +03:00
|
|
|
if (!uc->release)
|
|
|
|
uc->release = release_common;
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|