From 9283ead0b063e526fdcab00bcf86e2f10387a78f Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Fri, 18 Jun 2021 00:26:46 +0200
Subject: Update the storage format for type memory.

---
 plugins/pychrysalide/analysis/storage/tpmem.c | 52 +++++++--------
 src/analysis/storage/tpmem.c                  | 91 +++++++++------------------
 src/analysis/storage/tpmem.h                  |  8 +--
 3 files changed, 59 insertions(+), 92 deletions(-)

diff --git a/plugins/pychrysalide/analysis/storage/tpmem.c b/plugins/pychrysalide/analysis/storage/tpmem.c
index 8df20b2..491ee68 100644
--- a/plugins/pychrysalide/analysis/storage/tpmem.c
+++ b/plugins/pychrysalide/analysis/storage/tpmem.c
@@ -52,8 +52,8 @@ static int py_type_memory_init(PyObject *, PyObject *, PyObject *);
 /* -------------------------- TAMPON POUR CODE DESASSEMBLE -------------------------- */
 
 
-/* Apprend tous les types mémorisés dans un flux. */
-static PyObject *py_type_memory_read_types(PyObject *, PyObject *);
+/* Apprend tous les types mémorisés dans un tampon. */
+static PyObject *py_type_memory_load_types(PyObject *, PyObject *);
 
 /* Crée une nouvelle instance d'objet à partir de son type. */
 static PyObject *py_type_memory_create_object(PyObject *, PyObject *);
@@ -61,8 +61,8 @@ static PyObject *py_type_memory_create_object(PyObject *, PyObject *);
 /* Sauvegarde le type d'un objet instancié. */
 static PyObject *py_type_memory_store_object_gtype(PyObject *, PyObject *);
 
-/* Enregistre tous les types mémorisés dans un flux. */
-static PyObject *py_type_memory_write_types(PyObject *, PyObject *);
+/* Enregistre tous les types mémorisés dans un tampon. */
+static PyObject *py_type_memory_store_types(PyObject *, PyObject *);
 
 
 
@@ -178,7 +178,7 @@ static int py_type_memory_init(PyObject *self, PyObject *args, PyObject *kwds)
 *  Paramètres  : self = classe représentant une mémorisation de types.        *
 *                args = arguments fournis à l'appel.                          *
 *                                                                             *
-*  Description : Apprend tous les types mémorisés dans un flux.               *
+*  Description : Apprend tous les types mémorisés dans un tampon.             *
 *                                                                             *
 *  Retour      : Bilan de l'opération.                                        *
 *                                                                             *
@@ -186,36 +186,36 @@ static int py_type_memory_init(PyObject *self, PyObject *args, PyObject *kwds)
 *                                                                             *
 ******************************************************************************/
 
-static PyObject *py_type_memory_read_types(PyObject *self, PyObject *args)
+static PyObject *py_type_memory_load_types(PyObject *self, PyObject *args)
 {
     PyObject *result;                       /* Bilan à retourner           */
-    int fd;                                 /* Flux ouvert en lecture      */
+    packed_buffer_t *pbuf;                  /* Tampon à consulter          */
     int ret;                                /* Bilan de lecture des args.  */
     GTypeMemory *tpmem;                     /* Mémorisation native         */
     bool status;                            /* Bilan de l'opération        */
 
-#define TYPE_MEMORY_READ_TYPES_METHOD PYTHON_METHOD_DEF         \
+#define TYPE_MEMORY_LOAD_TYPES_METHOD PYTHON_METHOD_DEF         \
 (                                                               \
-    read_types, "$self, fd",                                    \
+    load_types, "$self, pbuf",                                  \
     METH_VARARGS, py_type_memory,                               \
-    "Read types from a stream.\n"                               \
+    "Read types from a buffer.\n"                               \
     "\n"                                                        \
     "This operation is usually handled internally by the"       \
     " Chrysalide's core.\n"                                     \
     "\n"                                                        \
-    "The *fd* parameter is an integer representing a valid"     \
-    " identifier for a file descriptor opened for reading."     \
+    "The *pbuf* parameter is a pychrysalide.common.PackedBuffer"\
+    " instance providing buffered data to read."                \
     "\n"                                                        \
     "The result is a boolean value indicating the status of"    \
     " the operation: True for success, False for failure."      \
 )
 
-    ret = PyArg_ParseTuple(args, "i", &fd);
+    ret = PyArg_ParseTuple(args, "O&", convert_to_packed_buffer, &pbuf);
     if (!ret) return NULL;
 
     tpmem = G_TYPE_MEMORY(pygobject_get(self));
 
-    status = g_type_memory_read_types(tpmem, fd);
+    status = g_type_memory_load_types(tpmem, pbuf);
 
     result = status ? Py_True : Py_False;
     Py_INCREF(result);
@@ -330,7 +330,7 @@ static PyObject *py_type_memory_store_object_gtype(PyObject *self, PyObject *arg
 *  Paramètres  : self = classe représentant une mémorisation de types.        *
 *                args = arguments fournis à l'appel.                          *
 *                                                                             *
-*  Description : Enregistre tous les types mémorisés dans un flux.            *
+*  Description : Enregistre tous les types mémorisés dans un tampon.          *
 *                                                                             *
 *  Retour      : Bilan de l'opération.                                        *
 *                                                                             *
@@ -338,36 +338,36 @@ static PyObject *py_type_memory_store_object_gtype(PyObject *self, PyObject *arg
 *                                                                             *
 ******************************************************************************/
 
-static PyObject *py_type_memory_write_types(PyObject *self, PyObject *args)
+static PyObject *py_type_memory_store_types(PyObject *self, PyObject *args)
 {
     PyObject *result;                       /* Bilan à retourner           */
-    int fd;                                 /* Flux ouvert en lecture      */
+    packed_buffer_t *pbuf;                  /* Tampon à consulter          */
     int ret;                                /* Bilan de lecture des args.  */
     GTypeMemory *tpmem;                     /* Mémorisation native         */
     bool status;                            /* Bilan de l'opération        */
 
-#define TYPE_MEMORY_WRITE_TYPES_METHOD PYTHON_METHOD_DEF        \
+#define TYPE_MEMORY_STORE_TYPES_METHOD PYTHON_METHOD_DEF        \
 (                                                               \
-    write_types, "$self, fd",                                   \
+    store_types, "$self, pbuf",                                 \
     METH_VARARGS, py_type_memory,                               \
-    "Write types into a stream.\n"                              \
+    "Write types into a buffer.\n"                              \
     "\n"                                                        \
     "This operation is usually handled internally by the"       \
     " Chrysalide's core.\n"                                     \
     "\n"                                                        \
-    "The *fd* parameter is an integer representing a valid"     \
-    " identifier for a file descriptor opened for writing."     \
+    "The *pbuf* parameter is a pychrysalide.common.PackedBuffer"\
+    " instance providing buffered data to read."                \
     "\n"                                                        \
     "The result is a boolean value indicating the status of"    \
     " the operation: True for success, False for failure."      \
 )
 
-    ret = PyArg_ParseTuple(args, "i", &fd);
+    ret = PyArg_ParseTuple(args, "O&", convert_to_packed_buffer, &pbuf);
     if (!ret) return NULL;
 
     tpmem = G_TYPE_MEMORY(pygobject_get(self));
 
-    status = g_type_memory_write_types(tpmem, fd);
+    status = g_type_memory_store_types(tpmem, pbuf);
 
     result = status ? Py_True : Py_False;
     Py_INCREF(result);
@@ -392,10 +392,10 @@ static PyObject *py_type_memory_write_types(PyObject *self, PyObject *args)
 PyTypeObject *get_python_type_memory_type(void)
 {
     static PyMethodDef py_type_memory_methods[] = {
-        TYPE_MEMORY_READ_TYPES_METHOD,
+        TYPE_MEMORY_LOAD_TYPES_METHOD,
         TYPE_MEMORY_CREATE_OBJECT_METHOD,
         TYPE_MEMORY_STORE_OBJECT_GTYPE_METHOD,
-        TYPE_MEMORY_WRITE_TYPES_METHOD,
+        TYPE_MEMORY_STORE_TYPES_METHOD,
         { NULL }
     };
 
diff --git a/src/analysis/storage/tpmem.c b/src/analysis/storage/tpmem.c
index 58585cd..cda8223 100644
--- a/src/analysis/storage/tpmem.c
+++ b/src/analysis/storage/tpmem.c
@@ -28,6 +28,7 @@
 #include <stdint.h>
 
 
+#include "../db/misc/rlestr.h"
 #include "../../arch/operands/target.h"
 #include "../../core/logs.h"
 
@@ -219,9 +220,9 @@ GTypeMemory *g_type_memory_new(void)
 /******************************************************************************
 *                                                                             *
 *  Paramètres  : tpmem = mémoire à compléter.                                 *
-*                fd    = flux ouvert en lecture.                              *
+*                pbuf  = zone tampon à lire.                                  *
 *                                                                             *
-*  Description : Apprend tous les types mémorisés dans un flux.               *
+*  Description : Apprend tous les types mémorisés dans un tampon.             *
 *                                                                             *
 *  Retour      : Bilan de l'opération.                                        *
 *                                                                             *
@@ -229,64 +230,45 @@ GTypeMemory *g_type_memory_new(void)
 *                                                                             *
 ******************************************************************************/
 
-bool g_type_memory_read_types(GTypeMemory *tpmem, int fd)
+bool g_type_memory_load_types(GTypeMemory *tpmem, packed_buffer_t *pbuf)
 {
     bool result;                            /* Bilan à enregistrer         */
-    packed_buffer_t pbuf;                   /* Tampon des données à écrire */
-    uint64_t i;                             /* Boucle de parcours          */
-    unsigned char len;                      /* Taille d'un nom de type     */
-    char *name;                             /* Désignation d'un type       */
-
-    init_packed_buffer(&pbuf);
+    uleb128_t count;                        /* Nombre d'éléments détectés  */
+    uleb128_t i;                            /* Boucle de parcours          */
+    rle_string str;                         /* Chaîne à charger            */
 
-    result = read_packed_buffer(&pbuf, fd);
+    result = unpack_uleb128(&count, pbuf);
 
     if (result)
     {
         g_mutex_lock(&tpmem->mutex);
 
-        result = extract_packed_buffer(&pbuf, &tpmem->count, sizeof(uint64_t), true);
+        tpmem->count = count;
 
-        if (result)
-        {
-            assert(tpmem->gtypes == NULL);
-            tpmem->gtypes = calloc(tpmem->count, sizeof(gtype_ref_info_t));
-        }
+        assert(tpmem->gtypes == NULL);
+        tpmem->gtypes = calloc(count, sizeof(gtype_ref_info_t));
 
         for (i = 0; i < tpmem->count && result; i++)
         {
-            result = extract_packed_buffer(&pbuf, &len, sizeof(unsigned char), false);
-
-            if (result)
-            {
-                name = malloc(len);
+            result = unpack_rle_string(&str, pbuf);
+            if (!result) break;
 
-                result = extract_packed_buffer(&pbuf, name, len, false);
+            tpmem->gtypes[i].gtype = g_type_from_name(get_rle_string(&str));
+            result = (tpmem->gtypes[i].gtype != 0);
 
-                if (result)
-                {
-                    tpmem->gtypes[i].gtype = g_type_from_name(name);
-                    result = (tpmem->gtypes[i].gtype != 0);
+            if (!result)
+                log_variadic_message(LMT_ERROR, "Unknown type: '%s'", get_rle_string(&str));
 
-                    if (!result)
-                        log_variadic_message(LMT_ERROR, "Unknown type: '%s'", name);
+            else
+                tpmem->gtypes[i].gclass = g_type_class_ref(tpmem->gtypes[i].gtype);
 
-                }
-
-                if (result)
-                    tpmem->gtypes[i].gclass = g_type_class_ref(tpmem->gtypes[i].gtype);
-
-                free(name);
-
-            }
+            exit_rle_string(&str);
 
         }
 
-        g_mutex_unlock(&tpmem->mutex);
-
     }
 
-    exit_packed_buffer(&pbuf);
+    g_mutex_unlock(&tpmem->mutex);
 
     return result;
 
@@ -399,9 +381,9 @@ bool g_type_memory_store_object_gtype(GTypeMemory *tpmem, GObject *obj, packed_b
 /******************************************************************************
 *                                                                             *
 *  Paramètres  : tpmem = mémoire à consulter.                                 *
-*                fd    = flux ouvert en écriture.                             *
+*                pbuf  = zone tampon à remplir.                               *
 *                                                                             *
-*  Description : Enregistre tous les types mémorisés dans un flux.            *
+*  Description : Enregistre tous les types mémorisés dans un tampon.          *
 *                                                                             *
 *  Retour      : Bilan de l'opération.                                        *
 *                                                                             *
@@ -409,46 +391,31 @@ bool g_type_memory_store_object_gtype(GTypeMemory *tpmem, GObject *obj, packed_b
 *                                                                             *
 ******************************************************************************/
 
-bool g_type_memory_write_types(GTypeMemory *tpmem, int fd)
+bool g_type_memory_store_types(GTypeMemory *tpmem, packed_buffer_t *pbuf)
 {
     bool result;                            /* Bilan à enregistrer         */
-    packed_buffer_t pbuf;                   /* Tampon des données à écrire */
     uint64_t i;                             /* Boucle de parcours          */
     const gchar *name;                      /* Désignation d'un type       */
-    size_t len;                             /* Taille de ce nom            */
-
-    init_packed_buffer(&pbuf);
+    rle_string str;                         /* Chaîne à conserver          */
 
     g_mutex_lock(&tpmem->mutex);
 
-    result = extend_packed_buffer(&pbuf, &tpmem->count, sizeof(uint64_t), true);
+    result = pack_uleb128((uleb128_t []){ tpmem->count }, pbuf);
 
     for (i = 0; i < tpmem->count && result; i++)
     {
         name = g_type_name(tpmem->gtypes[i].gtype);
-        len = strlen(name) + 1;
 
-        if (len > (2 << (sizeof(unsigned char) * 8 - 1)))
-        {
-            log_variadic_message(LMT_ERROR, "Type name too long: '%s' (%zu bytes)", name, len);
-            result = false;
-            break;
-        }
+        init_static_rle_string(&str, name);
 
-        result = extend_packed_buffer(&pbuf, (unsigned char []) { len }, sizeof(unsigned char), false);
+        result = pack_rle_string(&str, pbuf);
 
-        if (result)
-            result = extend_packed_buffer(&pbuf, name, len, false);
+        exit_rle_string(&str);
 
     }
 
-    if (result)
-        result = write_packed_buffer(&pbuf, fd);
-
     g_mutex_unlock(&tpmem->mutex);
 
-    exit_packed_buffer(&pbuf);
-
     return result;
 
 }
diff --git a/src/analysis/storage/tpmem.h b/src/analysis/storage/tpmem.h
index ff14265..34cbde6 100644
--- a/src/analysis/storage/tpmem.h
+++ b/src/analysis/storage/tpmem.h
@@ -53,8 +53,8 @@ GType g_type_memory_get_type(void);
 /* Crée une mémoire pour types d'objets. */
 GTypeMemory *g_type_memory_new(void);
 
-/* Apprend tous les types mémorisés dans un flux. */
-bool g_type_memory_read_types(GTypeMemory *, int);
+/* Apprend tous les types mémorisés dans un tampon. */
+bool g_type_memory_load_types(GTypeMemory *, packed_buffer_t *);
 
 /* Crée une nouvelle instance d'objet à partir de son type. */
 GObject *g_type_memory_create_object(GTypeMemory *, packed_buffer_t *);
@@ -62,8 +62,8 @@ GObject *g_type_memory_create_object(GTypeMemory *, packed_buffer_t *);
 /* Sauvegarde le type d'un objet instancié. */
 bool g_type_memory_store_object_gtype(GTypeMemory *, GObject *, packed_buffer_t *);
 
-/* Enregistre tous les types mémorisés dans un flux. */
-bool g_type_memory_write_types(GTypeMemory *, int);
+/* Enregistre tous les types mémorisés dans un tampon. */
+bool g_type_memory_store_types(GTypeMemory *, packed_buffer_t *);
 
 
 
-- 
cgit v0.11.2-87-g4458