diff --git a/qemu/softmmu/memory.c b/qemu/softmmu/memory.c index c79d9038..7399f873 100644 --- a/qemu/softmmu/memory.c +++ b/qemu/softmmu/memory.c @@ -786,12 +786,23 @@ static void address_space_update_topology_pass(AddressSpace *as, static void flatviews_init(struct uc_struct *uc) { + static FlatView *empty_view; + if (uc->flat_views) { return; } uc->flat_views = g_hash_table_new_full(NULL, NULL, NULL, (GDestroyNotify) flatview_unref); + + if (!empty_view) { + empty_view = generate_memory_topology(uc, NULL); + /* We keep it alive forever in the global variable. */ + flatview_ref(empty_view); + } else { + g_hash_table_replace(uc->flat_views, NULL, empty_view); + flatview_ref(empty_view); + } } static void flatviews_reset(struct uc_struct *uc) diff --git a/uc.c b/uc.c index 7991fdd7..3e24674c 100644 --- a/uc.c +++ b/uc.c @@ -339,6 +339,11 @@ uc_err uc_close(uc_engine *uc) /* cpu */ free(uc->cpu); + /* flatviews */ + g_hash_table_destroy(uc->flat_views); + + // During flatviews destruction, we may still access memory regions. + // So we free them afterwards. /* memory */ mr = &uc->io_mem_unassigned; mr->destructor(mr); @@ -347,10 +352,7 @@ uc_err uc_close(uc_engine *uc) mr = uc->system_memory; mr->destructor(mr); g_free(uc->system_memory); - //g_free(uc->system_io); - - /* flatviews */ - g_hash_table_destroy(uc->flat_views); + g_free(uc->system_io); // Thread relateds. if (uc->qemu_thread_data) {