diff options
Diffstat (limited to 'src/analysis')
-rw-r--r-- | src/analysis/block-int.h | 1 | ||||
-rw-r--r-- | src/analysis/block.c | 3 | ||||
-rw-r--r-- | src/analysis/db/collection-int.h | 1 | ||||
-rw-r--r-- | src/analysis/db/collection.c | 2 | ||||
-rw-r--r-- | src/analysis/db/items/comment.c | 10 | ||||
-rw-r--r-- | src/analysis/disass/area.c | 6 | ||||
-rw-r--r-- | src/analysis/disass/block.c | 12 | ||||
-rw-r--r-- | src/analysis/disass/links.c | 1 | ||||
-rw-r--r-- | src/analysis/loading.c | 23 | ||||
-rw-r--r-- | src/analysis/project.c | 62 | ||||
-rw-r--r-- | src/analysis/routine.c | 95 |
11 files changed, 154 insertions, 62 deletions
diff --git a/src/analysis/block-int.h b/src/analysis/block-int.h index 8f97794..6759e7b 100644 --- a/src/analysis/block-int.h +++ b/src/analysis/block-int.h @@ -53,6 +53,7 @@ struct _GCodeBlock { GObject parent; /* A laisser en premier */ + /* Référence circulaire */ GBlockList *list; /* Lien vers l'ensemble */ bitfield_t *domination; /* Blocs dominés de l'ensemble */ diff --git a/src/analysis/block.c b/src/analysis/block.c index 9708ef4..a7172af 100644 --- a/src/analysis/block.c +++ b/src/analysis/block.c @@ -158,8 +158,6 @@ static void g_code_block_init(GCodeBlock *block) static void g_code_block_dispose(GCodeBlock *block) { - g_clear_object(&block->list); - g_clear_object(&block->view); G_OBJECT_CLASS(g_code_block_parent_class)->dispose(G_OBJECT(block)); @@ -666,7 +664,6 @@ void g_block_list_add_block(GBlockList *list, GCodeBlock *block, size_t index) list->blocks[index] = block; block->list = list; - g_object_ref(G_OBJECT(list)); g_code_block_set_index(block, index); diff --git a/src/analysis/db/collection-int.h b/src/analysis/db/collection-int.h index cb0aea6..c2d1282 100644 --- a/src/analysis/db/collection-int.h +++ b/src/analysis/db/collection-int.h @@ -55,6 +55,7 @@ struct _GDbCollection GType type; /* Identifiant GLib équivalent */ const char *name; /* Nom en base de données */ + /* Référence circulaire */ GLoadedBinary *binary; /* Binaire rattaché éventuel */ GList *items; /* Eléments rassemblés */ diff --git a/src/analysis/db/collection.c b/src/analysis/db/collection.c index 0e4f756..9c28c4a 100644 --- a/src/analysis/db/collection.c +++ b/src/analysis/db/collection.c @@ -219,8 +219,6 @@ GDbCollection *g_db_collection_new(uint32_t id, GType type, const char *name) void g_db_collection_link_to_binary(GDbCollection *collec, GLoadedBinary *binary) { - g_object_ref(G_OBJECT(binary)); - collec->binary = binary; } diff --git a/src/analysis/db/items/comment.c b/src/analysis/db/items/comment.c index b879d08..7eb7906 100644 --- a/src/analysis/db/items/comment.c +++ b/src/analysis/db/items/comment.c @@ -301,11 +301,10 @@ static void g_db_comment_dispose(GDbComment *comment) { size_t i; /* Boucle de parcours */ - for (i = 0; i < comment->old_count; i++) - g_object_unref(G_OBJECT(comment->old_inlined[i])); + g_clear_object(&comment->previous); - if (comment->old_inlined != NULL) - free(comment->old_inlined); + for (i = 0; i < comment->old_count; i++) + g_clear_object(&comment->old_inlined[i]); G_OBJECT_CLASS(g_db_comment_parent_class)->dispose(G_OBJECT(comment)); @@ -346,6 +345,9 @@ static void g_db_comment_finalize(GDbComment *comment) unlock_flat_array(&comment->text); + if (comment->old_inlined != NULL) + free(comment->old_inlined); + G_OBJECT_CLASS(g_db_comment_parent_class)->finalize(G_OBJECT(comment)); } diff --git a/src/analysis/disass/area.c b/src/analysis/disass/area.c index 84bf8a4..f1aa002 100644 --- a/src/analysis/disass/area.c +++ b/src/analysis/disass/area.c @@ -348,8 +348,7 @@ static void fini_mem_area(mem_area *area) len = get_mrange_length(&area->range); for (i = 0; i < len; i++) - if (area->instructions[i] != NULL) - g_object_unref(G_OBJECT(area->instructions[i])); + g_clear_object(&area->instructions[i]); free(area->instructions); @@ -681,7 +680,10 @@ static void update_address_as_routine(GBinFormat *format, const vmpa2t *addr) if (!found || (found && wrong_type)) { if (found) + { g_binary_format_remove_symbol(format, symbol); + g_object_unref(G_OBJECT(symbol)); + } init_mrange(&range, addr, 0); diff --git a/src/analysis/disass/block.c b/src/analysis/disass/block.c index 021284e..9fce202 100644 --- a/src/analysis/disass/block.c +++ b/src/analysis/disass/block.c @@ -41,6 +41,7 @@ struct _GBasicBlock { GCodeBlock parent; /* A laisser en premier */ + /* Référence circulaire */ GLoadedBinary *binary; /* Binaire chargé et associé */ GArchInstruction *first; /* Première instruction */ @@ -159,10 +160,8 @@ static void g_basic_block_init(GBasicBlock *block) static void g_basic_block_dispose(GBasicBlock *block) { - g_clear_object(&block->binary); - - g_clear_object(&block->first); - g_clear_object(&block->last); + //g_clear_object(&block->first); + //g_clear_object(&block->last); G_OBJECT_CLASS(g_basic_block_parent_class)->dispose(G_OBJECT(block)); @@ -211,13 +210,12 @@ GCodeBlock *g_basic_block_new(GLoadedBinary *binary, GArchInstruction *first, GA result = g_object_new(G_TYPE_BASIC_BLOCK, NULL); result->binary = binary; - g_object_ref(G_OBJECT(binary)); result->first = first; result->last = last; - g_object_ref(G_OBJECT(first)); - g_object_ref(G_OBJECT(last)); + //g_object_ref(G_OBJECT(first)); + //g_object_ref(G_OBJECT(last)); parent = G_CODE_BLOCK(result); diff --git a/src/analysis/disass/links.c b/src/analysis/disass/links.c index 381aedc..26788db 100644 --- a/src/analysis/disass/links.c +++ b/src/analysis/disass/links.c @@ -128,6 +128,7 @@ void establish_natural_link(GArchInstruction *instr, GArchInstruction *prev) else { no_need = true; + unref_instr_link(other); goto check_done; } break; diff --git a/src/analysis/loading.c b/src/analysis/loading.c index 0ded268..664b8d6 100644 --- a/src/analysis/loading.c +++ b/src/analysis/loading.c @@ -782,6 +782,8 @@ void g_content_explorer_delete_group(GContentExplorer *explorer, wgroup_id_t wid g_work_queue_delete_work_group(queue, group->wid); + g_object_unref(G_OBJECT(group->original)); + for (i = 0; i < group->count; i++) g_object_unref(G_OBJECT(group->contents[i])); @@ -802,8 +804,7 @@ void g_content_explorer_delete_group(GContentExplorer *explorer, wgroup_id_t wid memmove(&explorer->groups[index], &explorer->groups[index + 1], (explorer->count - index - 1) * sizeof(exploring_group)); - explorer->groups = (exploring_group *)realloc(explorer->groups, - --explorer->count * sizeof(exploring_group)); + explorer->groups = realloc(explorer->groups, --explorer->count * sizeof(exploring_group)); /* Sortie */ @@ -839,7 +840,7 @@ void g_content_explorer_populate_group(GContentExplorer *explorer, wgroup_id_t w /* Conservation du résultat */ - group->contents = (GBinContent **)realloc(group->contents, ++group->count * sizeof(GBinContent *)); + group->contents = realloc(group->contents, ++group->count * sizeof(GBinContent *)); group->contents[group->count - 1] = content; g_object_ref(G_OBJECT(content)); @@ -885,7 +886,7 @@ void g_content_explorer_note_detected(GContentExplorer *explorer, wgroup_id_t wi group = g_content_explorer_find_group(explorer, wid); assert(group != NULL); - group->loaded = (GLoadedContent **)realloc(group->loaded, ++group->noted * sizeof(GLoadedContent *)); + group->loaded = realloc(group->loaded, ++group->noted * sizeof(GLoadedContent *)); group->loaded[group->noted - 1] = loaded; g_object_ref(G_OBJECT(loaded)); @@ -923,7 +924,7 @@ GBinContent **g_content_explorer_get_all(GContentExplorer *explorer, wgroup_id_t /* Allocation de la liste finale */ *count = 1 + group->count; - result = (GBinContent **)malloc(*count * sizeof(GBinContent *)); + result = malloc(*count * sizeof(GBinContent *)); /* On regarde déjà du côté de la source */ @@ -1438,7 +1439,7 @@ void g_content_resolver_create_group(GContentResolver *resolver, wgroup_id_t wid if (noted > 0) { group->count = noted; - group->loaded = (GLoadedContent **)realloc(group->loaded, group->count * sizeof(GLoadedContent *)); + group->loaded = realloc(group->loaded, group->count * sizeof(GLoadedContent *)); for (i = 0; i < noted; i++) { @@ -1496,6 +1497,9 @@ void g_content_resolver_delete_group(GContentResolver *resolver, wgroup_id_t wid for (i = 0; i < group->count; i++) g_object_unref(G_OBJECT(group->loaded[i])); + if (group->loaded != NULL) + free(group->loaded); + /* Réorganisation de la liste */ index = group - resolver->groups; @@ -1504,8 +1508,7 @@ void g_content_resolver_delete_group(GContentResolver *resolver, wgroup_id_t wid memmove(&resolver->groups[index], &resolver->groups[index + 1], (resolver->count - index - 1) * sizeof(resolving_group)); - resolver->groups = (resolving_group *)realloc(resolver->groups, - --resolver->count * sizeof(resolving_group)); + resolver->groups = realloc(resolver->groups, --resolver->count * sizeof(resolving_group)); /* Sortie */ @@ -1537,7 +1540,7 @@ void g_content_resolver_add_detected(GContentResolver *resolver, wgroup_id_t wid group = g_content_resolver_find_group(resolver, wid); assert(group != NULL); - group->loaded = (GLoadedContent **)realloc(group->loaded, ++group->count * sizeof(GLoadedContent *)); + group->loaded = realloc(group->loaded, ++group->count * sizeof(GLoadedContent *)); group->loaded[group->count - 1] = loaded; g_object_ref(G_OBJECT(loaded)); @@ -1575,7 +1578,7 @@ GLoadedContent **g_content_resolver_get_all(GContentResolver *resolver, wgroup_i /* Allocation de la liste finale */ *count = group->count; - result = (GLoadedContent **)malloc(*count * sizeof(GLoadedContent *)); + result = malloc(*count * sizeof(GLoadedContent *)); /* On parcourt les éventuels contenus encapsulés découverts */ diff --git a/src/analysis/project.c b/src/analysis/project.c index 4574d88..6156fbc 100644 --- a/src/analysis/project.c +++ b/src/analysis/project.c @@ -67,7 +67,7 @@ struct _GStudyProjectClass /* Signaux */ - void (* contents_available) (GStudyProject, GLoadedContent **, guint); + void (* contents_available) (GStudyProject, GLoadedContent *); void (* content_added) (GStudyProject *, GLoadedContent *); void (* content_removed) (GStudyProject *, GLoadedContent *); @@ -202,13 +202,13 @@ static void g_study_project_class_init(GStudyProjectClass *klass) object->dispose = (GObjectFinalizeFunc/* ! */)g_study_project_dispose; object->finalize = (GObjectFinalizeFunc)g_study_project_finalize; - g_signal_new("contents-available", + g_signal_new("content-available", G_TYPE_STUDY_PROJECT, G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET(GStudyProjectClass, contents_available), NULL, NULL, - g_cclosure_user_marshal_VOID__POINTER_UINT, - G_TYPE_NONE, 2, G_TYPE_POINTER, G_TYPE_UINT); + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, 1, G_TYPE_OBJECT); g_signal_new("content-added", G_TYPE_STUDY_PROJECT, @@ -610,7 +610,14 @@ void on_loaded_content_analyzed(GLoadedContent *content, gboolean success, GStud else log_variadic_message(LMT_ERROR, _("Failed to load '%s'"), desc); - g_object_ref(G_OBJECT(content)); + /** + * Le contenu a normalement été sur-référencé pour ne pas disparaître + * en cours d'analyse. + * + * On revient donc à une situation nominale ici. + */ + + g_object_unref(G_OBJECT(content)); } @@ -655,8 +662,7 @@ void g_study_project_attach_content(GStudyProject *project, GLoadedContent *cont { g_study_project_lock_contents(project); - project->contents = (GLoadedContent **)realloc(project->contents, - ++project->count * sizeof(GLoadedContent *)); + project->contents = realloc(project->contents, ++project->count * sizeof(GLoadedContent *)); project->contents[project->count - 1] = content; g_object_ref(G_OBJECT(content)); @@ -1208,12 +1214,12 @@ static void on_new_content_explored(GContentExplorer *explorer, wgroup_id_t wid, g_object_unref(G_OBJECT(resolver)); for (i = 0; i < count; i++) - g_object_unref(G_OBJECT(available[i])); + g_object_unref(G_OBJECT(available[i])); free(available); for (i = 0; i < noted; i++) - g_object_unref(G_OBJECT(detected[i])); + g_object_unref(G_OBJECT(detected[i])); if (detected != NULL) free(detected); @@ -1241,7 +1247,6 @@ static void on_new_content_resolved(GContentResolver *resolver, wgroup_id_t wid, { GLoadedContent **available; /* Contenus chargés valables */ size_t count; /* Quantité de ces contenus */ - bool keep; /* Conservation finale de liste*/ size_t i; /* Boucle de parcours */ GBinContent *content; /* Contenu brut à manipuler */ const gchar *hash; /* Empreinte d'un contenu */ @@ -1254,8 +1259,6 @@ static void on_new_content_resolved(GContentResolver *resolver, wgroup_id_t wid, { available = g_content_resolver_get_all(resolver, wid, &count); - keep = false; - /* Rechargement à partir d'XML ? */ if (handler->xdoc != NULL) { @@ -1316,25 +1319,21 @@ static void on_new_content_resolved(GContentResolver *resolver, wgroup_id_t wid, /* Découverte(s) initiale(s) ? */ else { - for (i = 0; i < count; i++) - { - /** - * S'il s'agit des résultats de la dernière exploration, - * alors les groupes contenant les éléments chargés vont - * être libéré, potentiellement pendant l'analyse. - * - * On temporise en incrémentant les références. - */ - g_object_ref(G_OBJECT(available[i])); - - } - if (is_batch_mode()) { for (i = 0; i < count; i++) { if (handler->filter == NULL || handler->filter(available[i], handler->data)) { + /** + * S'il s'agit des résultats de la dernière exploration, + * alors les groupes contenant les éléments chargés vont + * être libéré, potentiellement pendant l'analyse. + * + * On temporise en incrémentant les références. + */ + g_object_ref(G_OBJECT(available[i])); + g_signal_connect(available[i], "analyzed", G_CALLBACK(on_loaded_content_analyzed), handler->project); @@ -1349,17 +1348,16 @@ static void on_new_content_resolved(GContentResolver *resolver, wgroup_id_t wid, } else - { - g_signal_emit_by_name(handler->project, "contents-available", available, count); - - keep = true; - - } + for (i = 0; i < count; i++) + { + g_signal_emit_by_name(handler->project, "content-available", available[i]); + g_object_unref(G_OBJECT(available[i])); + } } /* Dans tous les cas... */ - if (available != NULL && !keep) + if (available != NULL) free(available); /* Si c'était la dernière résolution... */ diff --git a/src/analysis/routine.c b/src/analysis/routine.c index 4116044..8b49456 100644 --- a/src/analysis/routine.c +++ b/src/analysis/routine.c @@ -81,6 +81,12 @@ static void g_bin_routine_class_init(GBinRoutineClass *); /* Initialise une instance représentation de routine. */ static void g_bin_routine_init(GBinRoutine *); +/* Procède à la libération totale de la mémoire. */ +static void g_bin_routine_finalize(GBinRoutine *); + +/* Supprime toutes les références externes. */ +static void g_bin_routine_dispose(GBinRoutine *); + /* Fournit une étiquette pour viser une routine. */ static char *g_binary_routine_get_label(const GBinRoutine *); @@ -104,8 +110,14 @@ G_DEFINE_TYPE(GBinRoutine, g_bin_routine, G_TYPE_BIN_SYMBOL); static void g_bin_routine_class_init(GBinRoutineClass *klass) { + GObjectClass *object; /* Version de base de la classe*/ GBinSymbolClass *symbol; /* Autre version de la classe */ + object = G_OBJECT_CLASS(klass); + + object->dispose = (GObjectFinalizeFunc/* ! */)g_bin_routine_dispose; + object->finalize = (GObjectFinalizeFunc)g_bin_routine_finalize; + symbol = G_BIN_SYMBOL_CLASS(klass); symbol->get_label = (get_symbol_label_fc)g_binary_routine_get_label; @@ -133,6 +145,86 @@ static void g_bin_routine_init(GBinRoutine *routine) g_binary_symbol_set_target_type(symbol, STP_ROUTINE); + routine->ret_type = NULL; + + routine->namespace = NULL; + routine->ns_sep = NULL; + routine->name = NULL; + routine->full_name = NULL; + + routine->args = NULL; + routine->args_count = 0; + + routine->locals = NULL; + routine->locals_count = 0; + + routine->blocks = NULL; + +} + + +/****************************************************************************** +* * +* Paramètres : routine = instance d'objet GLib à traiter. * +* * +* Description : Supprime toutes les références externes. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_bin_routine_dispose(GBinRoutine *routine) +{ + size_t i; /* Boucle de parcours */ + + g_clear_object(&routine->ret_type); + + g_clear_object(&routine->namespace); + g_clear_object(&routine->full_name); + + for (i = 0; i < routine->args_count; i++) + g_clear_object(&routine->args[i]); + + for (i = 0; i < routine->locals_count; i++) + g_clear_object(&routine->locals[i]); + + g_clear_object(&routine->blocks); + + G_OBJECT_CLASS(g_bin_routine_parent_class)->dispose(G_OBJECT(routine)); + +} + + +/****************************************************************************** +* * +* Paramètres : routine = instance d'objet GLib à traiter. * +* * +* Description : Procède à la libération totale de la mémoire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_bin_routine_finalize(GBinRoutine *routine) +{ + if (routine->ns_sep != NULL) + free(routine->ns_sep); + + if (routine->name != NULL) + free(routine->name); + + if (routine->args != NULL) + free(routine->args); + + if (routine->locals != NULL) + free(routine->locals); + + G_OBJECT_CLASS(g_bin_routine_parent_class)->finalize(G_OBJECT(routine)); + } @@ -736,8 +828,7 @@ GBlockList *g_binary_routine_get_basic_blocks(const GBinRoutine *routine) void g_binary_routine_set_basic_blocks(GBinRoutine *routine, GBlockList *blocks) { - if (routine->blocks != NULL) - g_object_unref(G_OBJECT(routine->blocks)); + g_clear_object(&routine->blocks); routine->blocks = blocks; |