unicorn/qemu/unicorn_common.h

118 lines
3.2 KiB
C
Raw Normal View History

2015-08-21 09:04:50 +02: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);
2015-08-21 09:04:50 +02:00
}
static inline bool cpu_physical_mem_write(AddressSpace *as, hwaddr addr,
const uint8_t *buf, int len)
2015-08-21 09:04:50 +02:00
{
return cpu_physical_memory_rw(as, addr, (void *)buf, len, 1);
2015-08-21 09:04:50 +02:00
}
void tb_cleanup(struct uc_struct *uc);
void free_code_gen_buffer(struct uc_struct *uc);
2015-08-21 09:04:50 +02:00
2018-03-12 00:54:46 +01:00
static inline void free_address_spaces(struct uc_struct *uc)
{
int i;
address_space_destroy(&uc->as);
for (i = 0; i < uc->cpu->num_ases; i++) {
AddressSpace *as = uc->cpu->cpu_ases[i].as;
address_space_destroy(as);
g_free(as);
}
}
/* This is *supposed* to be done by the class finalizer but it never executes */
static inline void free_machine_class_name(struct uc_struct *uc) {
MachineClass *mc = MACHINE_GET_CLASS(uc, uc->machine_state);
g_free(mc->name);
mc->name = NULL;
}
static inline void free_tcg_temp_names(TCGContext *s)
{
#if TCG_TARGET_REG_BITS == 32
int i;
for (i = 0; i < s->nb_globals; i++) {
TCGTemp *ts = &s->temps[i];
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))) {
free((void *)ts->name);
}
}
}
#endif
}
2015-08-21 09:04:50 +02:00
/** Freeing common resources */
static void release_common(void *t)
{
TCGPool *po, *to;
2015-08-21 09:04:50 +02:00
TCGContext *s = (TCGContext *)t;
// Clean TCG.
TCGOpDef* def = &s->tcg_op_defs[0];
g_free(def->args_ct);
g_free(s->tcg_op_defs);
2016-01-31 23:22:20 +01:00
2015-08-21 09:04:50 +02:00
for (po = s->pool_first; po; po = to) {
to = po->next;
g_free(po);
2015-08-21 09:04:50 +02:00
}
tcg_pool_reset(s);
g_hash_table_destroy(s->helpers);
// Destory flat view hash table
g_hash_table_destroy(s->uc->flat_views);
unicorn_free_empty_flat_view(s->uc);
// TODO(danghvu): these function is not available outside qemu
// so we keep them here instead of outside uc_close.
2018-03-12 00:54:46 +01:00
free_address_spaces(s->uc);
memory_free(s->uc);
2016-07-08 19:49:43 +02:00
tb_cleanup(s->uc);
free_code_gen_buffer(s->uc);
2018-03-12 00:54:46 +01:00
free_machine_class_name(s->uc);
free_tcg_temp_names(s);
2015-08-21 09:04:50 +02:00
}
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->cpu_exec_exit = cpu_exec_exit;
2015-08-21 09:04:50 +02:00
uc->vm_start = vm_start;
uc->memory_map = memory_map;
uc->memory_map_ptr = memory_map_ptr;
uc->memory_unmap = memory_unmap;
uc->readonly_mem = memory_region_set_readonly;
2015-08-21 09:04:50 +02:00
uc->target_page_size = TARGET_PAGE_SIZE;
2015-09-03 12:16:49 +02:00
uc->target_page_align = TARGET_PAGE_SIZE - 1;
2018-03-12 00:54:46 +01:00
if (!uc->release) {
2015-08-21 09:04:50 +02:00
uc->release = release_common;
2018-03-12 00:54:46 +01:00
}
2015-08-21 09:04:50 +02:00
}
#endif