From 5c1636199a06965c549f748014d582dcb85ba7df Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Fri, 13 Mar 2015 22:29:55 +0000
Subject: Updated and improved without testing the old process of computing
 limits for routines.

git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@490 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
---
 ChangeLog                   |  10 ++++
 src/analysis/disass/area.c  |   3 +-
 src/analysis/disass/limit.c | 133 ++++++++++++++++++--------------------------
 src/analysis/disass/limit.h |   3 +-
 4 files changed, 68 insertions(+), 81 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index d0967b0..81df404 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+15-03-13  Cyrille Bagard <nocbos@gmail.com>
+
+	* src/analysis/disass/area.c:
+	Free allocated memory as expected.
+
+	* src/analysis/disass/limit.c:
+	* src/analysis/disass/limit.h:
+	Update and improve without testing the old process of computing limits
+	for routines.
+
 15-03-11  Cyrille Bagard <nocbos@gmail.com>
 
 	* src/analysis/disass/macro.c:
diff --git a/src/analysis/disass/area.c b/src/analysis/disass/area.c
index bd99402..916918e 100644
--- a/src/analysis/disass/area.c
+++ b/src/analysis/disass/area.c
@@ -1249,7 +1249,8 @@ mem_area *compute_memory_areas(GExeFormat *format, phys_t bin_length, size_t *co
 
 
 
-    //free
+    if (exe_ranges != NULL)
+        free(exe_ranges);
 
     //exit(0);
 
diff --git a/src/analysis/disass/limit.c b/src/analysis/disass/limit.c
index 6d5bc35..bb2c865 100644
--- a/src/analysis/disass/limit.c
+++ b/src/analysis/disass/limit.c
@@ -28,129 +28,104 @@
 
 
 
-/* Cherche l'adresse de fin d'une routine. */
-static vmpa_t find_best_ending_address_for_routine(GArchInstruction *, size_t, const vmpa_t *, const off_t *, size_t);
+/* Recherche la zone correspond à une adresse donnée. */
+static const mrange_t *find_x_range_for_addr(const mrange_t *, size_t, const vmpa2t *);
 
 
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : list      = ensemble d'instructions désassemblées.           *
-*                routines  = prototypes existants à insérer.                  *
-*                count     = quantité de ces prototypes.                      *
-*                statusbar = barre de statut avec progression à mettre à jour.*
-*                id        = identifiant du message affiché à l'utilisateur.  *
+*  Paramètres  : ranges = liste de zones offrant une exécution et disponibles.*
+*                count  = taille de cette liste.                              *
 *                                                                             *
-*  Description : S'assure que toutes les routines ont une taille définie.     *
+*  Description : Recherche la zone correspond à une adresse donnée.           *
 *                                                                             *
-*  Retour      : -                                                            *
+*  Retour      : Zone trouvée ou NULL si aucune ne correspond.                *
 *                                                                             *
 *  Remarques   : -                                                            *
 *                                                                             *
 ******************************************************************************/
 
-void limit_all_routines(GArchInstruction *list, GBinRoutine **routines, size_t count, GtkExtStatusBar *statusbar, bstatus_id_t id)
+static const mrange_t *find_x_range_for_addr(const mrange_t *ranges, size_t count, const vmpa2t *addr)
 {
+    const mrange_t *result;                 /* Zone à retourner            */
     size_t i;                               /* Boucle de parcours          */
-    vmpa_t *starts;                         /* Adresses de départ          */
-    off_t *lengths;                         /* Tailles des routines        */
-    GArchInstruction *instr;                /* Instr. de départ / arrivée  */
-
-    if (count == 0) return;
-
-    starts = (vmpa_t *)calloc(count, sizeof(vmpa_t));
-    lengths = (off_t *)calloc(count, sizeof(off_t));
-
-    for (i = 0; i < count; i++)
-    {
-        starts[i] = g_binary_routine_get_address(routines[i]);
-        lengths[i] = g_binary_routine_get_size(routines[i]);
-
-        gtk_extended_status_bar_update_activity(statusbar, id, (i + 1) * 1.0 / (count * 2));
-
-    }
-
-    for (i = 0; i < count; i++)
-    {
-        /* Instruction de départ */
-
-        instr = g_arch_instruction_find_by_address(list, starts[i], true);
-        g_binary_routine_set_instructions(routines[i], instr);
-
-        if (lengths[i] > 0) goto lar_next;
-
-        /* Si le symbole est hors du code analysé (routine de PLT par exemple) */
-        if (instr == NULL) goto lar_next;
-
-        /* Taille de la routine */
 
-        lengths[i] = find_best_ending_address_for_routine(instr, i, starts, lengths, count);
-        lengths[i] -= starts[i];
+    result = NULL;
 
-        /////////g_binary_routine_set_size(routines[i], lengths[i]);
+    for (i = 0; i < count && result == NULL; i++)
+        if (mrange_contains_addr(&ranges[i], addr))
+            result = &ranges[i];
 
- lar_next:
-
-        gtk_extended_status_bar_update_activity(statusbar, id, (i + 1 + count) * 1.0 / (count * 2));
-
-    }
-
-    free(starts);
-    free(lengths);
+    return result;
 
 }
 
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : first   = première instruction de la routine courante.       *
-*                index   = indice de la routine traitée dans la liste.        *
-*                starts  = adresse de départ des autres routines.             *
-*                lengths = taille des différentes routines, valides ou nulles.*
-*                count   = quantité de routines présentes.                    *
+*  Paramètres  : list      = ensemble d'instructions désassemblées.           *
+*                routines  = prototypes existants à insérer.                  *
+*                count     = quantité de ces prototypes.                      *
+*                statusbar = barre de statut avec progression à mettre à jour.*
+*                id        = identifiant du message affiché à l'utilisateur.  *
 *                                                                             *
-*  Description : Cherche l'adresse de fin d'une routine.                      *
+*  Description : S'assure que toutes les routines ont une taille définie.     *
 *                                                                             *
-*  Retour      : Plus grande adresse de dernière instruction de routine.      *
+*  Retour      : -                                                            *
 *                                                                             *
 *  Remarques   : -                                                            *
 *                                                                             *
 ******************************************************************************/
 
-static vmpa_t find_best_ending_address_for_routine(GArchInstruction *first, size_t index, const vmpa_t *starts, const off_t *lengths, size_t count)
+void limit_all_routines(GExeFormat *format, GBinRoutine **routines, size_t count, GtkExtStatusBar *statusbar, bstatus_id_t id)
 {
-    vmpa_t result;                          /* Haute adresse à remonter    */
-    GArchInstruction *iter;                 /* Boucle de parcours #1       */
-    vmpa_t candidate;                       /* Candidat potentiel          */
-    size_t i;                               /* Boucle de parcours #2       */
+    mrange_t *exe_ranges;                   /* Liste de zones exécutables  */
+    size_t exe_count;                       /* Nombre de ces zones         */
+    size_t i;                               /* Boucle de parcours          */
+    const mrange_t *range;                  /* Emplacement courant         */
+    vmpa2t addr;                            /* Adresse à conserver         */
+    phys_t diff;                            /* Taille définie par déduction*/
+    mrange_t new;                           /* Nouvel emplacement taillé   */
 
-    result = starts[index];
+    exe_ranges = g_exe_format_get_x_ranges(format, &exe_count);
 
-    for (iter = first;
-         iter != NULL;
-         iter = g_arch_instruction_get_next_iter(first, iter, VMPA_MAX))
+    for (i = 0; i < count; i++)
     {
-        g_arch_instruction_get_location(iter, NULL, NULL, &candidate);
+        //gtk_extended_status_bar_update_activity(statusbar, id, (i + 1) * 1.0 / count);
+
+        range = g_binary_routine_get_range(routines[i]);
+        if (get_mrange_length(range) > 0) continue;
+
+        copy_vmpa(&addr, get_mrange_addr(range));
 
-        /* Regarde si on n'empiète pas sur une autre routine */
+        /* Si on peut se raccrocher à la routine suivante... */
+        if ((i + 1) < count)
+        {
+            range = g_binary_routine_get_range(routines[i + 1]);
+
+            diff = compute_vmpa_diff(&addr, get_mrange_addr(range));
 
-        for (i = 0; i < count; i++)
+        }
+
+        /* Sinon on va jusqu'à la fin de la zone ! */
+        else
         {
-            if (i == index) continue;
+            range = find_x_range_for_addr(exe_ranges, exe_count, &addr);
+            if (range == NULL) continue;
 
-            if (starts[i] <= candidate && candidate < (starts[i] + lengths[i]))
-                break;
+            diff = compute_vmpa_diff(&addr, get_mrange_addr(range));
+            diff = get_mrange_length(range) - diff;
 
         }
 
-        if (i != count) break;
-        else result = candidate;
+        init_mrange(&new, &addr, diff);
 
-        /* Retour de fonction ? */
-        if (g_arch_instruction_is_return(iter)) break;
+        g_binary_routine_set_range(routines[i], &new);
 
     }
 
-    return result;
+    if (exe_ranges != NULL)
+        free(exe_ranges);
 
 }
diff --git a/src/analysis/disass/limit.h b/src/analysis/disass/limit.h
index d768765..92c7df4 100644
--- a/src/analysis/disass/limit.h
+++ b/src/analysis/disass/limit.h
@@ -26,12 +26,13 @@
 
 
 #include "../routine.h"
+#include "../../format/executable.h"
 #include "../../gtkext/gtkextstatusbar.h"
 
 
 
 /* S'assure que toutes les routines ont une taille définie. */
-void limit_all_routines(GArchInstruction *, GBinRoutine **, size_t, GtkExtStatusBar *, bstatus_id_t);
+void limit_all_routines(GExeFormat *, GBinRoutine **, size_t, GtkExtStatusBar *, bstatus_id_t);
 
 
 
-- 
cgit v0.11.2-87-g4458