From 0becef388e9a68ab716583758ade15f8d8ca0cf9 Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Thu, 21 Jun 2018 23:18:35 +0200
Subject: Limited the routine size to the containing segment.

---
 src/analysis/disass/limit.c | 40 ++++++++++++++++++++++++++++------------
 1 file changed, 28 insertions(+), 12 deletions(-)

diff --git a/src/analysis/disass/limit.c b/src/analysis/disass/limit.c
index 4fb219a..103f878 100644
--- a/src/analysis/disass/limit.c
+++ b/src/analysis/disass/limit.c
@@ -24,6 +24,9 @@
 #include "limit.h"
 
 
+#include <assert.h>
+
+
 
 /******************************************************************************
 *                                                                             *
@@ -45,8 +48,9 @@ void compute_routine_limit(GBinSymbol *symbol, const vmpa2t *next, GArchProcesso
     const mrange_t *range;                  /* Emplacement courant         */
     vmpa2t addr;                            /* Adresse à conserver         */
     GArchInstruction *start;                /* Première instruction        */
-    phys_t diff;                            /* Taille définie par déduction*/
     GBinPortion *portion;                   /* Conteneur avec limites      */
+    phys_t pdiff;                           /* Différence avec ces limites */
+    phys_t diff;                            /* Taille définie par déduction*/
     mrange_t new;                           /* Nouvel emplacement taillé   */
 
     range = g_binary_symbol_get_range(symbol);
@@ -70,25 +74,37 @@ void compute_routine_limit(GBinSymbol *symbol, const vmpa2t *next, GArchProcesso
 
     g_object_unref(G_OBJECT(start));
 
+    /* Dans tous les cas, on va se référer à la portion contenante... */
+
+    portion = g_binary_portion_find_at_addr(portions, &addr, (GdkRectangle []) { });
+    assert(portion != NULL);
+
+    range = g_binary_portion_get_range(portion);
+
+    pdiff = compute_vmpa_diff(&addr, get_mrange_addr(range));
+    pdiff = get_mrange_length(range) - pdiff;
+
+    g_object_unref(G_OBJECT(portion));
+
     /* Si on peut se raccrocher à la prochaine adresse... */
     if (next != NULL)
-        diff = compute_vmpa_diff(&addr, next);
-
-    /* Sinon on va jusqu'à la fin de la zone ! */
-    else
     {
-        portion = g_binary_portion_find_at_addr(portions, &addr, (GdkRectangle []) { });
-        if (portion == NULL) goto crl_skip;
-
-        range = g_binary_portion_get_range(portion);
+        diff = compute_vmpa_diff(&addr, next);
 
-        diff = compute_vmpa_diff(&addr, get_mrange_addr(range));
-        diff = get_mrange_length(range) - diff;
+        /**
+         * On considère qu'un symbole ne peut pas déborder d'un segment
+         * sur un autre.
+         */
 
-        g_object_unref(G_OBJECT(portion));
+        if (diff > pdiff)
+            diff = pdiff;
 
     }
 
+    /* Sinon on va jusqu'à la fin de la zone ! */
+    else
+        diff = pdiff;
+
     init_mrange(&new, &addr, diff);
 
     g_binary_symbol_set_range(symbol, &new);
-- 
cgit v0.11.2-87-g4458