summaryrefslogtreecommitdiff
path: root/src/analysis
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2019-02-05 22:03:38 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2019-02-05 22:03:38 (GMT)
commit17f591f2230ac66394467d5e5eefe71cb259637d (patch)
tree1664e994b2904e5e9009027fc57749a11667365b /src/analysis
parentff187d24b7441e88e1f0361d59b0f6f55851791f (diff)
Fixed a huge number of memory leaks.
Diffstat (limited to 'src/analysis')
-rw-r--r--src/analysis/block-int.h1
-rw-r--r--src/analysis/block.c3
-rw-r--r--src/analysis/db/collection-int.h1
-rw-r--r--src/analysis/db/collection.c2
-rw-r--r--src/analysis/db/items/comment.c10
-rw-r--r--src/analysis/disass/area.c6
-rw-r--r--src/analysis/disass/block.c12
-rw-r--r--src/analysis/disass/links.c1
-rw-r--r--src/analysis/loading.c23
-rw-r--r--src/analysis/project.c62
-rw-r--r--src/analysis/routine.c95
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;