From 17f591f2230ac66394467d5e5eefe71cb259637d Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Tue, 5 Feb 2019 23:03:38 +0100 Subject: Fixed a huge number of memory leaks. --- configure.ac | 2 +- plugins/arm/context.c | 5 +- plugins/dwarf/format.c | 3 +- plugins/elf/format.c | 2 + plugins/elf/loading.c | 2 + plugins/elf/strings.c | 8 +++ plugins/elf/symbols.c | 9 +++- plugins/lnxsyscalls/hops_armv7.c | 5 ++ plugins/pychrysalide/format/format.c | 3 ++ plugins/readelf/strtab.c | 8 +++ src/analysis/block-int.h | 1 + src/analysis/block.c | 3 -- src/analysis/db/collection-int.h | 1 + src/analysis/db/collection.c | 2 - src/analysis/db/items/comment.c | 10 ++-- src/analysis/disass/area.c | 6 ++- src/analysis/disass/block.c | 12 ++--- src/analysis/disass/links.c | 1 + src/analysis/loading.c | 23 +++++---- src/analysis/project.c | 62 ++++++++++++----------- src/analysis/routine.c | 95 +++++++++++++++++++++++++++++++++++- src/arch/context.c | 11 ++++- src/arch/instruction.c | 21 +++----- src/arch/link.c | 1 - src/arch/processor.c | 16 +++++- src/arch/target.c | 11 ++--- src/common/xml.c | 2 + src/format/debuggable.c | 2 - src/format/executable.c | 3 +- src/format/format.c | 26 ++++++++-- src/format/strsym.c | 2 +- src/glibext/gbinportion.c | 8 +++ src/gui/editor.c | 30 ++++-------- 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); } -- cgit v0.11.2-87-g4458