From b0c6ffacf5c6c45c047172e348c737cb85fb5b36 Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Mon, 8 May 2017 12:15:50 +0200
Subject: Merged characters intro strings when possible in the disassembled
 code.

---
 ChangeLog      |   5 +++
 src/arch/raw.c | 107 ++++++++++++++++++++++++++++-----------------------------
 2 files changed, 57 insertions(+), 55 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 12f44fb..123b47e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,10 @@
 17-05-08  Cyrille Bagard <nocbos@gmail.com>
 
+	* src/arch/raw.c:
+	Merge characters intro strings when possible in the disassembled code.
+
+17-05-08  Cyrille Bagard <nocbos@gmail.com>
+
 	* src/format/dex/class.c:
 	Ensure a Dex routine is not abstract nor native before adding a symbol into the disassembled code.
 
diff --git a/src/arch/raw.c b/src/arch/raw.c
index da9ee88..9cd77de 100644
--- a/src/arch/raw.c
+++ b/src/arch/raw.c
@@ -495,12 +495,13 @@ static void g_raw_instruction_print(GRawInstruction *instr, GBufferLine *line, s
     phys_t max_displayed_len;               /* Quantité de code affichée   */
     const char *key;                        /* Mot clef principal          */
     size_t klen;                            /* Taille de ce mot clef       */
-    size_t count;                           /* Nombre d'opérandes en place */
     char *string;                           /* Chaîne reconstituée         */
     size_t iter;                            /* Tête d'écriture             */
     bool first;                             /* Mémorise une énumération    */
+    size_t count;                           /* Nombre d'opérandes en place */
     size_t i;                               /* Boucle de parcours          */
     GArchOperand *op;                       /* Opérande à manipuler        */
+    GImmOperand *imm;                       /* Version opérande de valeur  */
     char byte;                              /* Octet à afficher (ou pas)   */
     bool status;                            /* Bilan d'une récupération    */
 
@@ -536,50 +537,61 @@ static void g_raw_instruction_print(GRawInstruction *instr, GBufferLine *line, s
     if (instr->is_padding)
         g_buffer_line_append_text(line, BLC_ASSEMBLY, "...", 3, RTT_RAW, NULL);
 
-    else if (instr->is_string)
+    else
     {
-        g_arch_instruction_lock_operands(base);
-
-        count = _g_arch_instruction_count_operands(base);
+        string = NULL;
+        iter = 0;
 
-        string = (char *)calloc(count + 3, sizeof(char));
+        first = true;
 
-        strcpy(string, "\"");
-        iter = 1;
+        g_arch_instruction_lock_operands(base);
 
-        first = true;
+        count = _g_arch_instruction_count_operands(base);
 
         for (i = 0; i < count; i++)
         {
             op = _g_arch_instruction_get_operand(base, i);
 
-            status = g_imm_operand_get_value(G_IMM_OPERAND(op), MDS_8_BITS, &byte);
+            if (!G_IS_IMM_OPERAND(op))
+                goto grip_fallback;
+
+            imm = G_IMM_OPERAND(op);
+
+            if (g_imm_operand_get_size(imm) != MDS_8_BITS)
+                goto grip_fallback;
+
+            if (!instr->is_string && g_imm_operand_get_display(imm) != IOD_CHAR)
+                goto grip_fallback;
+
+            status = g_imm_operand_get_value(imm, MDS_8_BITS, &byte);
             assert(status);
 
             /* Si le caractère doit apparaître en hexadécimal... */
+
             if (!isprint(byte))
+                goto grip_fallback;
+
+            /* Impression de l'octet */
+
+            if (string == NULL)
             {
-                /* Si une chaîne précède */
-                if (iter > 1)
-                {
-                    if (!first)
-                    {
-                        g_buffer_line_append_text(line, BLC_ASSEMBLY, ",", 1, RTT_PUNCT, NULL);
-                        g_buffer_line_append_text(line, BLC_ASSEMBLY, " ", 1, RTT_RAW, NULL);
-                    }
-                    else
-                        first = false;
+                string = (char *)calloc(count + 3, sizeof(char));
 
-                    string[iter++] = '"';
+                strcpy(string, "\"");
+                iter = 1;
 
-                    g_buffer_line_append_text(line, BLC_ASSEMBLY, string, iter, RTT_STRING, NULL);
+            }
 
-                    iter = 1;
+            string[iter++] = byte;
 
-                }
+            continue;
+
+ grip_fallback:
 
-                /* Impression de l'octet */
+            /* Si une chaîne précède */
 
+            if (string != NULL && iter > 1)
+            {
                 if (!first)
                 {
                     g_buffer_line_append_text(line, BLC_ASSEMBLY, ",", 1, RTT_PUNCT, NULL);
@@ -588,20 +600,16 @@ static void g_raw_instruction_print(GRawInstruction *instr, GBufferLine *line, s
                 else
                     first = false;
 
-                g_arch_operand_print(op, line, 0/*, syntax*/);
+                string[iter++] = '"';
 
-            }
+                g_buffer_line_append_text(line, BLC_ASSEMBLY, string, iter, RTT_STRING, NULL);
 
-            else
-                string[iter++] = byte;
+                iter = 1;
 
-        }
+            }
 
-        g_arch_instruction_unlock_operands(base);
+            /* Intégration en tant qu'opérande classique */
 
-        /* Si une chaîne reste encore */
-        if (iter > 1)
-        {
             if (!first)
             {
                 g_buffer_line_append_text(line, BLC_ASSEMBLY, ",", 1, RTT_PUNCT, NULL);
@@ -610,42 +618,31 @@ static void g_raw_instruction_print(GRawInstruction *instr, GBufferLine *line, s
             else
                 first = false;
 
-            string[iter++] = '"';
-
-            g_buffer_line_append_text(line, BLC_ASSEMBLY, string, iter, RTT_STRING, NULL);
+            g_arch_operand_print(op, line, 0/*syntax*/);
 
         }
 
-        free(string);
-
-    }
+        /* Si au final une chaîne traine encore */
 
-    else
-    {
-        g_arch_instruction_lock_operands(base);
-
-        count = _g_arch_instruction_count_operands(base);
-
-        if (count > 0)
+        if (string != NULL && iter > 1)
         {
-            op = _g_arch_instruction_get_operand(base, 0);
-            g_arch_operand_print(op, line, 0/*syntax*/);
-
-            for (i = 1; i < count; i++)
+            if (!first)
             {
                 g_buffer_line_append_text(line, BLC_ASSEMBLY, ",", 1, RTT_PUNCT, NULL);
                 g_buffer_line_append_text(line, BLC_ASSEMBLY, " ", 1, RTT_RAW, NULL);
+            }
 
-                op = _g_arch_instruction_get_operand(base, i);
-
-                g_arch_operand_print(op, line, 0/*syntax*/);
+            string[iter++] = '"';
 
-            }
+            g_buffer_line_append_text(line, BLC_ASSEMBLY, string, iter, RTT_STRING, NULL);
 
         }
 
         g_arch_instruction_unlock_operands(base);
 
+        if (string != NULL)
+            free(string);
+
     }
 
 }
-- 
cgit v0.11.2-87-g4458