/* Chrysalide - Outil d'analyse de fichiers binaires * cmerge.c - fusion des conditions successives * * Copyright (C) 2013 Cyrille Bagard * * This file is part of Chrysalide. * * Chrysalide is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * Chrysalide is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Foobar. If not, see . */ #include "cmerge.h" #include "../../decomp/expr/block.h" #include "../../decomp/expr/comp.h" #include "../../decomp/expr/cond.h" #include "../../decomp/instr/ite.h" /* Recherche des conditions successives pouvant être fusionnées. */ static bool track_branch_conditions(GDecInstruction *, GDecInstruction *, DecInstrVisitFlags, void *); /****************************************************************************** * * * Paramètres : instr = instruction visitée. * * parent = instruction parente. * * flags = moments des appels réalisés en retour. * * data = adresse non utilisée ici. * * * * Description : Recherche des conditions successives pouvant être fusionnées.* * * * Retour : true afin d'aller jusqu'au terme du parcours. * * * * Remarques : - * * * ******************************************************************************/ static bool track_branch_conditions(GDecInstruction *instr, GDecInstruction *parent, DecInstrVisitFlags flags, void *data) { GDecInstruction *true_branch; /* Branche 'vrai' */ GDecInstruction *false_branch; /* Branche 'faux' */ GDecInstruction *first; /* Première sous-instruction */ GCondExpression *sub_cond; /* Expression conditionnelle */ GCondExpression *top_cond; /* Expression conditionnelle */ if (!G_IS_ITE_INSTRUCTION(instr)) goto tbc_done; g_ite_instruction_get_branches(G_ITE_INSTRUCTION(instr), &true_branch, &false_branch); if (false_branch != NULL) goto tbc_done; /* count(block) == 1 */ first = g_expr_block_get_item(G_EXPR_BLOCK(true_branch), 0); if (!G_IS_ITE_INSTRUCTION(first)) goto tbc_done; printf("got one!\n"); /* Récupération des informations inférieures */ sub_cond = g_ite_instruction_get_condition(G_ITE_INSTRUCTION(first)); g_object_ref(G_OBJECT(sub_cond)); g_ite_instruction_get_branches(G_ITE_INSTRUCTION(first), &true_branch, &false_branch); if (true_branch != NULL) g_object_ref(G_OBJECT(true_branch)); if (false_branch != NULL) g_object_ref(G_OBJECT(false_branch)); /* Reconstitution d'une nouvelle instruction */ top_cond = g_ite_instruction_get_condition(G_ITE_INSTRUCTION(instr)); //g_cond_expression_add_condition(top_cond, sub_cond, COT_AND); //g_ite_instruction_set_branches(G_ITE_INSTRUCTION(instr), true_branch, false_branch); printf("got one!\n"); /* GDecExpression *g_ite_instruction_get_condition(const GITEInstruction *instr) GDecExpression *g_cond_expression_get_expression(const GCondExpression *cond) void g_cond_expression_set_expression(GCondExpression *cond, GDecExpression *exp) */ tbc_done: return true; } /****************************************************************************** * * * Paramètres : instr = instructions à traiter. * * * * Description : Fusionne les conditions qui s'enchaînent. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ void merge_lonely_conditions(GDecInstruction *instr) { return; g_dec_instruction_visit(instr, (dec_instr_visitor_cb)track_branch_conditions, DVF_EXIT, NULL); }