summaryrefslogtreecommitdiff
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
parentff187d24b7441e88e1f0361d59b0f6f55851791f (diff)
Fixed a huge number of memory leaks.
-rw-r--r--configure.ac2
-rw-r--r--plugins/arm/context.c5
-rw-r--r--plugins/dwarf/format.c3
-rw-r--r--plugins/elf/format.c2
-rw-r--r--plugins/elf/loading.c2
-rw-r--r--plugins/elf/strings.c8
-rw-r--r--plugins/elf/symbols.c9
-rw-r--r--plugins/lnxsyscalls/hops_armv7.c5
-rw-r--r--plugins/pychrysalide/format/format.c3
-rw-r--r--plugins/readelf/strtab.c8
-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
-rw-r--r--src/arch/context.c11
-rw-r--r--src/arch/instruction.c21
-rw-r--r--src/arch/link.c1
-rw-r--r--src/arch/processor.c16
-rw-r--r--src/arch/target.c11
-rw-r--r--src/common/xml.c2
-rw-r--r--src/format/debuggable.c2
-rw-r--r--src/format/executable.c3
-rw-r--r--src/format/format.c26
-rw-r--r--src/format/strsym.c2
-rw-r--r--src/glibext/gbinportion.c8
-rw-r--r--src/gui/editor.c30
33 files changed, 276 insertions, 120 deletions
diff --git a/configure.ac b/configure.ac
index 4e2967e..3043e7e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -349,7 +349,7 @@ AC_SUBST(LIBPYGOBJECT_LIBS)
AC_CONFIG_FILES([stamp-h po/Makefile.in], [echo timestamp > stamp-h])
-AC_CONFIG_COMMANDS([marshal], [echo -e "VOID:UINT64\nVOID:INT,UINT64,INT\nVOID:OBJECT,OBJECT\nVOID:ENUM,OBJECT\nVOID:ENUM,ENUM\nVOID:BOOLEAN,UINT64\nVOID:BOOLEAN,ULONG,ULONG\nVOID:INT,INT\nVOID:OBJECT,BOOLEAN\nVOID:ULONG,BOOLEAN\nVOID:POINTER,UINT" > src/glibext/chrysamarshal.list])
+AC_CONFIG_COMMANDS([marshal], [echo -e "VOID:UINT64\nVOID:INT,UINT64,INT\nVOID:OBJECT,OBJECT\nVOID:ENUM,OBJECT\nVOID:ENUM,ENUM\nVOID:BOOLEAN,UINT64\nVOID:BOOLEAN,ULONG,ULONG\nVOID:INT,INT\nVOID:OBJECT,BOOLEAN\nVOID:ULONG,BOOLEAN" > src/glibext/chrysamarshal.list])
AC_CONFIG_FILES([Makefile
doc/Makefile
diff --git a/plugins/arm/context.c b/plugins/arm/context.c
index 6b62760..8f6ab52 100644
--- a/plugins/arm/context.c
+++ b/plugins/arm/context.c
@@ -140,6 +140,9 @@ static void g_arm_context_dispose(GArmContext *ctx)
static void g_arm_context_finalize(GArmContext *ctx)
{
+ if (ctx->areas != NULL)
+ free(ctx->areas);
+
G_OBJECT_CLASS(g_arm_context_parent_class)->finalize(G_OBJECT(ctx));
}
@@ -240,7 +243,7 @@ void _g_arm_context_define_encoding(GArmContext *ctx, virt_t addr, unsigned int
/* Sinon on redivise... */
else
{
- ctx->areas = (disass_arm_area *)realloc(ctx->areas, ++ctx->acount * sizeof(disass_arm_area));
+ ctx->areas = realloc(ctx->areas, ++ctx->acount * sizeof(disass_arm_area));
memmove(&ctx->areas[selected + 1], &ctx->areas[selected],
(ctx->acount - selected - 1) * sizeof(disass_arm_area));
diff --git a/plugins/dwarf/format.c b/plugins/dwarf/format.c
index 96ce831..e071f1c 100644
--- a/plugins/dwarf/format.c
+++ b/plugins/dwarf/format.c
@@ -216,8 +216,7 @@ GDbgFormat *g_dwarf_format_new(GExeFormat *parent)
result = g_object_new(G_TYPE_DWARF_FORMAT, NULL);
- G_DBG_FORMAT(result)->executable = parent;
- g_object_ref(G_OBJECT(parent));
+ g_debuggable_format_attach_executable(G_DBG_FORMAT(result), parent);
content = G_BIN_FORMAT(parent)->content;
diff --git a/plugins/elf/format.c b/plugins/elf/format.c
index d6bdc5e..08472e4 100644
--- a/plugins/elf/format.c
+++ b/plugins/elf/format.c
@@ -541,6 +541,8 @@ static bool g_elf_format_get_main_address(GElfFormat *format, vmpa2t *addr)
copy_vmpa(addr, get_mrange_addr(range));
+ g_object_unref(G_OBJECT(symbol));
+
}
return result;
diff --git a/plugins/elf/loading.c b/plugins/elf/loading.c
index eb992b9..73e75f0 100644
--- a/plugins/elf/loading.c
+++ b/plugins/elf/loading.c
@@ -496,6 +496,8 @@ static void g_elf_loading_process(GElfLoading *loading, GtkStatusStack *status)
{
ret = loading->callback_1(loading, format, symbol);
+ g_object_unref(G_OBJECT(symbol));
+
if (!ret)
{
log_variadic_message(LMT_ERROR, _("Error while applying ELF relocation %zu!"), processed);
diff --git a/plugins/elf/strings.c b/plugins/elf/strings.c
index f6be4a8..fe37a0d 100644
--- a/plugins/elf/strings.c
+++ b/plugins/elf/strings.c
@@ -345,6 +345,12 @@ static bool do_elf_string_loading(GElfLoading *loading, GElfFormat *format, phys
g_raw_instruction_mark_as_string(G_RAW_INSTRUCTION(instr), true);
+ /**
+ * Comme g_preload_info_add_instruction() peut consommer l'instruction
+ * et qu'on réutilise cette dernière ensuite avec g_arch_instruction_get_range()...
+ */
+ g_object_ref(G_OBJECT(instr));
+
inserted = g_preload_info_add_instruction(base->info, instr);
result |= inserted;
@@ -373,6 +379,8 @@ static bool do_elf_string_loading(GElfLoading *loading, GElfFormat *format, phys
}
+ g_object_unref(G_OBJECT(instr));
+
/* Conclusion */
skip_first:
diff --git a/plugins/elf/symbols.c b/plugins/elf/symbols.c
index b6f05f6..5ddc99c 100644
--- a/plugins/elf/symbols.c
+++ b/plugins/elf/symbols.c
@@ -195,7 +195,10 @@ static void register_elf_entry_point(GElfFormat *format, virt_t vaddr, phys_t le
/* Comptabilisation en tant que symbole */
if (g_binary_format_find_symbol_at(G_BIN_FORMAT(format), &addr, &symbol))
+ {
+ g_object_unref(G_OBJECT(symbol));
g_object_unref(G_OBJECT(routine));
+ }
else
{
@@ -552,11 +555,13 @@ static bool do_elf_symbol_loading(GElfLoading *loading, GElfFormat *format, bool
{
g_binary_symbol_set_status(symbol, status);
+ /*
if (new != NULL)
{
g_object_ref(G_OBJECT(symbol));
*new = symbol;
}
+ */
g_binary_format_add_symbol(base, symbol);
@@ -749,6 +754,8 @@ static bool do_elf_global_symbol_loading(GElfLoading *loading, GElfFormat *forma
result = do_elf_symbol_loading(loading, format, false, iter, &symbol);
+ //g_clear_object(&symbol);
+
return result;
}
@@ -1048,7 +1055,7 @@ static bool load_elf_relocations(GElfFormat *format, const elf_phdr *dynamic, el
{
result &= g_elf_loading_get_status(loadings[i]);
- g_object_ref(G_OBJECT(loadings[i]));
+ g_object_unref(G_OBJECT(loadings[i]));
}
diff --git a/plugins/lnxsyscalls/hops_armv7.c b/plugins/lnxsyscalls/hops_armv7.c
index d706a10..cde092c 100644
--- a/plugins/lnxsyscalls/hops_armv7.c
+++ b/plugins/lnxsyscalls/hops_armv7.c
@@ -148,11 +148,16 @@ static bool resolve_armv7_linux_syscall_number(tracked_path *exec, GArchProcesso
op = g_arch_instruction_get_operand(instr, 1);
if (!G_IS_IMM_OPERAND(op))
+ {
+ g_object_unref(G_OBJECT(op));
goto ralsn_exit;
+ }
*nr = g_imm_operand_get_raw_value(G_IMM_OPERAND(op));
result = true;
+ g_object_unref(G_OBJECT(op));
+
}
ralsn_exit:
diff --git a/plugins/pychrysalide/format/format.c b/plugins/pychrysalide/format/format.c
index e285116..82cb575 100644
--- a/plugins/pychrysalide/format/format.c
+++ b/plugins/pychrysalide/format/format.c
@@ -243,7 +243,10 @@ static PyObject *py_binary_format_find_symbol_by_label(PyObject *self, PyObject
found = g_binary_format_find_symbol_by_label(format, PyUnicode_DATA(label), &symbol);
if (found)
+ {
result = pygobject_new(G_OBJECT(symbol));
+ g_object_unref(G_OBJECT(symbol));
+ }
else
{
result = Py_None;
diff --git a/plugins/readelf/strtab.c b/plugins/readelf/strtab.c
index 7645dec..277d391 100644
--- a/plugins/readelf/strtab.c
+++ b/plugins/readelf/strtab.c
@@ -106,6 +106,12 @@ static void parse_elf_string_table(GElfFormat *format, GPreloadInfo *info, const
g_raw_instruction_mark_as_string(G_RAW_INSTRUCTION(instr), true);
+ /**
+ * Comme g_preload_info_add_instruction() peut consommer l'instruction
+ * et qu'on réutilise cette dernière ensuite avec g_arch_instruction_get_range()...
+ */
+ g_object_ref(G_OBJECT(instr));
+
inserted = g_preload_info_add_instruction(info, instr);
if (inserted)
@@ -127,6 +133,8 @@ static void parse_elf_string_table(GElfFormat *format, GPreloadInfo *info, const
}
+ g_object_unref(G_OBJECT(instr));
+
/* Conclusion */
cut = (data[end - 1] == '\0');
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;
diff --git a/src/arch/context.c b/src/arch/context.c
index cedec33..3b78161 100644
--- a/src/arch/context.c
+++ b/src/arch/context.c
@@ -144,7 +144,7 @@ static void g_proc_context_dispose(GProcContext *ctx)
size_t i; /* Boucle de parcours */
for (i = 0; i < ctx->items_count; i++)
- g_object_unref(G_OBJECT(ctx->items[i]));
+ g_clear_object(&ctx->items[i]);
g_mutex_clear(&ctx->items_mutex);
@@ -167,6 +167,15 @@ static void g_proc_context_dispose(GProcContext *ctx)
static void g_proc_context_finalize(GProcContext *ctx)
{
+ DisassPriorityLevel i; /* Boucle de parcours */
+
+ for (i = 0; i < DPL_COUNT; i++)
+ if (ctx->drop_points[i] != NULL)
+ free(ctx->drop_points[i]);
+
+ if (ctx->extra_symbols != NULL)
+ free(ctx->extra_symbols);
+
if (ctx->items != NULL)
free(ctx->items);
diff --git a/src/arch/instruction.c b/src/arch/instruction.c
index 1d1ccaf..8e9d3d3 100644
--- a/src/arch/instruction.c
+++ b/src/arch/instruction.c
@@ -607,15 +607,11 @@ bool _g_arch_instruction_replace_operand(GArchInstruction *instr, GArchOperand *
count = _g_arch_instruction_count_operands(instr);
- for (i = 0; i < count; i++)
+ for (i = 0; i < count && !result; i++)
{
op = _g_arch_instruction_get_operand(instr, i);
- if (op == old)
- {
- result = true;
- break;
- }
+ result = (op == old);
g_object_unref(G_OBJECT(op));
@@ -623,7 +619,7 @@ bool _g_arch_instruction_replace_operand(GArchInstruction *instr, GArchOperand *
if (result)
{
- rpl_item_in_flat_array(instr->operands, i, &new, sizeof(GArchOperand *));
+ rpl_item_in_flat_array(instr->operands, i - 1, &new, sizeof(GArchOperand *));
g_object_unref(G_OBJECT(old));
@@ -654,24 +650,23 @@ bool _g_arch_instruction_detach_operand(GArchInstruction *instr, GArchOperand *t
size_t i; /* Boucle de parcours */
GArchOperand *op; /* Opérande à manipuler */
+ result = false;
+
count = _g_arch_instruction_count_operands(instr);
- for (i = 0; i < count; i++)
+ for (i = 0; i < count && !result; i++)
{
op = _g_arch_instruction_get_operand(instr, i);
- if (op == target)
- break;
+ result = (op == target);
g_object_unref(G_OBJECT(op));
}
- result = (i < count);
-
if (result)
{
- rem_item_from_flat_array(&instr->operands, i, sizeof(GArchOperand *));
+ rem_item_from_flat_array(&instr->operands, i - 1, sizeof(GArchOperand *));
g_object_unref(G_OBJECT(target));
diff --git a/src/arch/link.c b/src/arch/link.c
index f09621e..7eaa1d9 100644
--- a/src/arch/link.c
+++ b/src/arch/link.c
@@ -138,7 +138,6 @@ void handle_branch_as_link(GArchInstruction *instr, GArchProcessor *proc, GProcC
}
- range = g_arch_instruction_get_range(instr);
compute_mrange_end_addr(range, &next);
target = g_arch_processor_find_instr_by_address(proc, &next);
diff --git a/src/arch/processor.c b/src/arch/processor.c
index 05e3206..dccd12e 100644
--- a/src/arch/processor.c
+++ b/src/arch/processor.c
@@ -190,8 +190,18 @@ static void g_arch_processor_dispose(GArchProcessor *proc)
size_t i; /* Boucle de parcours */
for (i = 0; i < proc->instr_count; i++)
+ {
+ /**
+ * Pour éviter un cycle de maintien des références, on détruit tous
+ * les liens depuis l'extérieur !
+ */
+ if (proc->instructions[i] != NULL)
+ g_arch_instruction_delete_all_links(proc->instructions[i]);
+
g_clear_object(&proc->instructions[i]);
+ }
+
g_mutex_clear(&proc->mutex);
g_mutex_clear(&proc->error_mutex);
@@ -230,6 +240,9 @@ static void g_arch_processor_finalize(GArchProcessor *proc)
}
+ if (proc->coverages != NULL)
+ free(proc->coverages);
+
G_OBJECT_CLASS(g_arch_processor_parent_class)->finalize(G_OBJECT(proc));
}
@@ -974,8 +987,7 @@ static void g_arch_processor_add_new_coverage(GArchProcessor *proc, GArchInstruc
{
proc->cov_allocated += COV_ALLOC_BLOCK;
- proc->coverages = (instr_coverage *)realloc(proc->coverages,
- proc->cov_allocated * sizeof(instr_coverage));
+ proc->coverages = realloc(proc->coverages, proc->cov_allocated * sizeof(instr_coverage));
}
diff --git a/src/arch/target.c b/src/arch/target.c
index 64b12dd..d3bd89a 100644
--- a/src/arch/target.c
+++ b/src/arch/target.c
@@ -51,6 +51,7 @@ struct _GTargetOperand
vmpa2t addr; /* Adresse de l'élément visé */
bool strict; /* Résolution stricte */
+ /* Référence circulaire */
GBinSymbol *symbol; /* Eventuel symbole associé */
phys_t diff; /* Position dans le symbole */
@@ -206,9 +207,6 @@ static void g_target_operand_targetable_interface_init(GTargetableOperandInterfa
static void g_target_operand_dispose(GTargetOperand *operand)
{
- if (operand->symbol != NULL)
- g_object_unref(G_OBJECT(operand->symbol));
-
G_OBJECT_CLASS(g_target_operand_parent_class)->dispose(G_OBJECT(operand));
}
@@ -505,9 +503,6 @@ bool g_target_operand_resolve(GTargetOperand *operand, GBinFormat *format, bool
const mrange_t *range; /* Couverture du symbole */
#endif
- if (operand->symbol != NULL)
- g_object_unref(G_OBJECT(operand->symbol));
-
operand->strict = strict;
result = g_binary_format_resolve_symbol(format, &operand->addr, strict, &operand->symbol, &operand->diff);
@@ -553,6 +548,10 @@ bool g_target_operand_resolve(GTargetOperand *operand, GBinFormat *format, bool
}
+ /* Référence circulaire */
+ if (operand->symbol != NULL)
+ g_object_unref(operand->symbol);
+
return result;
}
diff --git a/src/common/xml.c b/src/common/xml.c
index 0bd4d86..aaed2ea 100644
--- a/src/common/xml.c
+++ b/src/common/xml.c
@@ -1037,6 +1037,8 @@ xmlNodePtr ensure_node_exist(xmlDocPtr xdoc, xmlXPathContextPtr context, const c
iter = get_node_from_xpath(context, iter_path);
+ free(iter_path);
+
if (iter == NULL) break;
else last = iter;
diff --git a/src/format/debuggable.c b/src/format/debuggable.c
index 571163b..7020c38 100644
--- a/src/format/debuggable.c
+++ b/src/format/debuggable.c
@@ -125,6 +125,4 @@ void g_debuggable_format_attach_executable(GDbgFormat *format, GExeFormat *execu
{
format->executable = executable;
- g_object_ref(G_OBJECT(executable));
-
}
diff --git a/src/format/executable.c b/src/format/executable.c
index cda2e3a..00d685c 100644
--- a/src/format/executable.c
+++ b/src/format/executable.c
@@ -181,8 +181,7 @@ void g_exe_format_add_debug_info(GExeFormat *format, GDbgFormat *info)
else
log_variadic_message(LMT_INFO, _("Found debug information: %s"), desc);
- format->debugs = (GDbgFormat **)realloc(format->debugs,
- ++format->debugs_count * sizeof(GDbgFormat *));
+ format->debugs = realloc(format->debugs, ++format->debugs_count * sizeof(GDbgFormat *));
format->debugs[format->debugs_count - 1] = info;
diff --git a/src/format/format.c b/src/format/format.c
index cd71a21..ab4864f 100644
--- a/src/format/format.c
+++ b/src/format/format.c
@@ -156,10 +156,19 @@ static void g_binary_format_init(GBinFormat *format)
static void g_binary_format_dispose(GBinFormat *format)
{
- g_clear_object(&format->demangler);
+ size_t i; /* Boucle de parcours */
+
+ g_clear_object(&format->content);
+
+ g_rw_lock_clear(&format->pt_lock);
g_clear_object(&format->info);
+ g_clear_object(&format->demangler);
+
+ for (i = 0; i < format->sym_count; i++)
+ g_clear_object(&format->symbols[i]);
+
g_rw_lock_clear(&format->syms_lock);
g_mutex_clear(&format->error_mutex);
@@ -185,6 +194,15 @@ static void g_binary_format_finalize(GBinFormat *format)
{
size_t i; /* Boucle de parcours */
+ if (format->entry_points != NULL)
+ free(format->entry_points);
+
+ if (format->extra_points != NULL)
+ free(format->extra_points);
+
+ if (format->symbols != NULL)
+ free(format->symbols);
+
if (format->errors != NULL)
{
for (i = 0; i < format->error_count; i++)
@@ -386,8 +404,7 @@ void g_binary_format_register_code_point(GBinFormat *format, virt_t pt, bool ent
if (entry)
{
- format->entry_points = (virt_t *)realloc(format->entry_points,
- ++format->ep_count * sizeof(virt_t));
+ format->entry_points = realloc(format->entry_points, ++format->ep_count * sizeof(virt_t));
format->entry_points[format->ep_count - 1] = pt;
@@ -398,8 +415,7 @@ void g_binary_format_register_code_point(GBinFormat *format, virt_t pt, bool ent
{
format->xp_allocated += EXTRA_POINT_BLOCK;
- format->extra_points = (virt_t *)realloc(format->extra_points,
- format->xp_allocated * sizeof(virt_t));
+ format->extra_points = realloc(format->extra_points, format->xp_allocated * sizeof(virt_t));
}
diff --git a/src/format/strsym.c b/src/format/strsym.c
index 6feb8a1..4e8479e 100644
--- a/src/format/strsym.c
+++ b/src/format/strsym.c
@@ -193,7 +193,7 @@ static void g_string_symbol_feeder_interface_init(GProxyFeederInterface *iface)
static void g_string_symbol_dispose(GStrSymbol *symbol)
{
if (symbol->has_content)
- g_object_unref(G_OBJECT(symbol->content));
+ g_clear_object(&symbol->content);
G_OBJECT_CLASS(g_string_symbol_parent_class)->dispose(G_OBJECT(symbol));
diff --git a/src/glibext/gbinportion.c b/src/glibext/gbinportion.c
index e020506..0074713 100644
--- a/src/glibext/gbinportion.c
+++ b/src/glibext/gbinportion.c
@@ -202,6 +202,11 @@ static void g_binary_portion_interface_init(GLineGeneratorInterface *iface)
static void g_binary_portion_dispose(GBinPortion *portion)
{
+ size_t i; /* Boucle de parcours */
+
+ for (i = 0; i < portion->count; i++)
+ g_clear_object(&portion->subs[i]);
+
G_OBJECT_CLASS(g_binary_portion_parent_class)->dispose(G_OBJECT(portion));
}
@@ -238,6 +243,9 @@ static void g_binary_portion_finalize(GBinPortion *portion)
if (portion->text != NULL)
free(portion->text);
+ if (portion->subs != NULL)
+ free(portion->subs);
+
G_OBJECT_CLASS(g_binary_portion_parent_class)->finalize(G_OBJECT(portion));
}
diff --git a/src/gui/editor.c b/src/gui/editor.c
index 58dda53..627df95 100644
--- a/src/gui/editor.c
+++ b/src/gui/editor.c
@@ -131,7 +131,7 @@ static void notify_editor_project_change(GStudyProject *, bool);
static gboolean scroll_for_the_first_time(GtkWidget *, GdkEvent *, GLoadedContent *);
/* Présente une possibilité de sélection des contenus chargés. */
-static void on_editor_contents_available(GStudyProject *, GLoadedContent **, guint, void *);
+static void on_editor_content_available(GStudyProject *, GLoadedContent *, void *);
/* Affiche le contenu qui vient de rejoindre un projet donné. */
static void on_editor_loaded_content_added(GStudyProject *, GLoadedContent *, void *);
@@ -912,8 +912,8 @@ static void notify_editor_project_change(GStudyProject *project, bool new)
if (new)
{
- g_signal_connect_to_main(project, "contents-available", G_CALLBACK(on_editor_contents_available), NULL,
- g_cclosure_user_marshal_VOID__POINTER_UINT);
+ g_signal_connect_to_main(project, "content-available", G_CALLBACK(on_editor_content_available), NULL,
+ g_cclosure_marshal_VOID__OBJECT);
g_signal_connect_to_main(project, "content-added", G_CALLBACK(on_editor_loaded_content_added), NULL,
g_cclosure_marshal_VOID__OBJECT);
@@ -946,10 +946,9 @@ static void notify_editor_project_change(GStudyProject *project, bool new)
/******************************************************************************
* *
-* Paramètres : project = project impliqué dans l'opération. *
-* contents = nouveaux contenus à éventuellement charger. *
-* count = taille de la liste fournie. *
-* unused = adresse non utilisée ici. *
+* Paramètres : project = project impliqué dans l'opération. *
+* content = nouveau contenu à éventuellement charger. *
+* unused = adresse non utilisée ici. *
* *
* Description : Présente une possibilité de sélection des contenus chargés. *
* *
@@ -959,22 +958,13 @@ static void notify_editor_project_change(GStudyProject *project, bool new)
* *
******************************************************************************/
-static void on_editor_contents_available(GStudyProject *project, GLoadedContent **contents, guint count, void *unused)
+static void on_editor_content_available(GStudyProject *project, GLoadedContent *content, void *unused)
{
- guint i; /* Boucle de parcours */
-
- for (i = 0; i < count; i++)
- {
- g_signal_connect(contents[i], "analyzed", G_CALLBACK(on_loaded_content_analyzed), project);
+ g_object_ref(G_OBJECT(content));
- g_loaded_content_analyze(contents[i], true);
+ g_signal_connect(content, "analyzed", G_CALLBACK(on_loaded_content_analyzed), project);
- g_object_unref(G_OBJECT(contents[i]));
-
- }
-
- if (contents != NULL)
- free(contents);
+ g_loaded_content_analyze(content, true);
}