diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2016-12-30 10:38:52 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2016-12-30 10:38:52 (GMT) |
commit | 932ea7c83c07d3982fee605c6dd9895fd2753874 (patch) | |
tree | 766ad53bab9e3e3005334c30e823493de8e84168 /src/glibext/generators/rborder.c | |
parent | 1b5d39bfbc48c33a0ea0924b60e48448c8b45dd4 (diff) |
Rewritten the line buffers using generators and on-demand building to save memory.
Diffstat (limited to 'src/glibext/generators/rborder.c')
-rw-r--r-- | src/glibext/generators/rborder.c | 361 |
1 files changed, 361 insertions, 0 deletions
diff --git a/src/glibext/generators/rborder.c b/src/glibext/generators/rborder.c new file mode 100644 index 0000000..ff34dfb --- /dev/null +++ b/src/glibext/generators/rborder.c @@ -0,0 +1,361 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * prologue.c - génération à la volée de délimitations de routines + * + * Copyright (C) 2016 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 <http://www.gnu.org/licenses/>. + */ + + +#include "rborder.h" + + +#include <assert.h> +#include <malloc.h> +#include <string.h> + + +#include "../gbufferline.h" +#include "../linegen-int.h" +#include "../linesegment.h" + + + +/* Tampon pour générateur de délimitations de routines (instance) */ +struct _GBorderGenerator +{ + GObject parent; /* A laisser en premier */ + + GCodingLanguage *lang; /* Traduction de la sortie */ + + vmpa2t addr; /* Position de la limite */ + bool start; /* Début ou fin de routine ? */ + + MemoryDataSize msize; /* Taille du bus d'adresses */ + +}; + +/* Tampon pour générateur de délimitations de routines (classe) */ +struct _GBorderGeneratorClass +{ + GObjectClass parent; /* A laisser en premier */ + +}; + + +#define ROUTINE_INTRO_MSG "--------------- BEGIN OF PROCEDURE ---------------" + +#define ROUTINE_OUTRO_MSG "---------------- END OF PROCEDURE ----------------" + + +/* Procède à l'initialisation d'une classe de générateur. */ +static void g_border_generator_class_init(GBorderGeneratorClass *); + +/* Procède à l'initialisation d'un générateur de délimitations. */ +static void g_border_generator_init(GBorderGenerator *); + +/* Procède à l'initialisation de l'interface de génération. */ +static void g_border_generator_interface_init(GLineGeneratorInterface *); + +/* Supprime toutes les références externes. */ +static void g_border_generator_dispose(GBorderGenerator *); + +/* Procède à la libération totale de la mémoire. */ +static void g_border_generator_finalize(GBorderGenerator *); + +/* Indique le nombre de ligne prêtes à être générées. */ +static size_t g_border_generator_count_lines(const GBorderGenerator *); + +/* Retrouve l'emplacement correspondant à une position donnée. */ +static void g_border_generator_compute_addr(const GBorderGenerator *, gint, vmpa2t *, size_t, size_t); + +/* Détermine si le conteneur s'inscrit dans une plage donnée. */ +static int g_border_generator_contains_addr(const GBorderGenerator *, const vmpa2t *, size_t, size_t); + +/* Renseigne sur les propriétés liées à un générateur. */ +static BufferLineFlags g_border_generator_get_flags(const GBorderGenerator *, size_t, size_t); + +/* Imprime dans une ligne de rendu le contenu représenté. */ +static void g_border_generator_print(GBorderGenerator *, GBufferLine *, size_t, size_t); + + + +/* Détermine le type du générateur de délimitations de routines à la volée. */ +G_DEFINE_TYPE_WITH_CODE(GBorderGenerator, g_border_generator, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE(G_TYPE_LINE_GENERATOR, g_border_generator_interface_init)); + + +/****************************************************************************** +* * +* Paramètres : class = classe de composant GLib à initialiser. * +* * +* Description : Procède à l'initialisation d'une classe de générateur. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_border_generator_class_init(GBorderGeneratorClass *class) +{ + GObjectClass *object; /* Autre version de la classe */ + + object = G_OBJECT_CLASS(class); + + object->dispose = (GObjectFinalizeFunc/* ! */)g_border_generator_dispose; + object->finalize = (GObjectFinalizeFunc)g_border_generator_finalize; + +} + + +/****************************************************************************** +* * +* Paramètres : generator = composant GLib à initialiser. * +* * +* Description : Procède à l'initialisation d'un générateur de délimitations. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_border_generator_init(GBorderGenerator *generator) +{ + +} + + +/****************************************************************************** +* * +* Paramètres : iface = interface GLib à initialiser. * +* * +* Description : Procède à l'initialisation de l'interface de génération. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_border_generator_interface_init(GLineGeneratorInterface *iface) +{ + iface->count = (linegen_count_lines_fc)g_border_generator_count_lines; + iface->compute = (linegen_compute_fc)g_border_generator_compute_addr; + iface->contains = (linegen_contains_fc)g_border_generator_contains_addr; + iface->get_flags = (linegen_get_flags_fc)g_border_generator_get_flags; + iface->print = (linegen_print_fc)g_border_generator_print; + +} + + +/****************************************************************************** +* * +* Paramètres : generator = instance d'objet GLib à traiter. * +* * +* Description : Supprime toutes les références externes. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_border_generator_dispose(GBorderGenerator *generator) +{ + g_object_unref(G_OBJECT(generator->lang)); + + G_OBJECT_CLASS(g_border_generator_parent_class)->dispose(G_OBJECT(generator)); + +} + + +/****************************************************************************** +* * +* Paramètres : generator = instance d'objet GLib à traiter. * +* * +* Description : Procède à la libération totale de la mémoire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_border_generator_finalize(GBorderGenerator *generator) +{ + G_OBJECT_CLASS(g_border_generator_parent_class)->finalize(G_OBJECT(generator)); + +} + + +/****************************************************************************** +* * +* Paramètres : lang = trauducteur pour l'impression finale. * +* addr = position correspondant à la délimitation à marquer. * +* start = indique le type de délimitation observée. * +* msize = taille des adresses représentées. * +* * +* Description : Crée un nouveau générateur de délimitations de routines. * +* * +* Retour : Composant GLib créé. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GBorderGenerator *g_border_generator_new(GCodingLanguage *lang, const vmpa2t *addr, bool start, MemoryDataSize msize) +{ + GBorderGenerator *result; /* Composant à retourner */ + + result = g_object_new(G_TYPE_BORDER_GENERATOR, NULL); + + result->lang = lang; + g_object_ref(G_OBJECT(lang)); + + copy_vmpa(&result->addr, addr); + result->start = start; + + result->msize = msize; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : generator = générateur à consulter. * +* * +* Description : Indique le nombre de ligne prêtes à être générées. * +* * +* Retour : Nombre de lignes devant apparaître au final. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static size_t g_border_generator_count_lines(const GBorderGenerator *generator) +{ + return 3; + +} + + +/****************************************************************************** +* * +* Paramètres : generator = générateur à consulter. * +* x = position géographique sur la ligne concernée. * +* addr = position en mémoire à analyser. * +* index = indice de cette même ligne dans le tampon global.* +* repeat = indice d'utilisations successives du générateur. * +* * +* Description : Retrouve l'emplacement correspondant à une position donnée. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_border_generator_compute_addr(const GBorderGenerator *generator, gint x, vmpa2t *addr, size_t index, size_t repeat) +{ + copy_vmpa(addr, &generator->addr); + +} + + +/****************************************************************************** +* * +* Paramètres : generator = générateur à consulter. * +* addr = position en mémoire à analyser. * +* index = indice de cette même ligne dans le tampon global.* +* repeat = indice d'utilisations successives du générateur. * +* * +* Description : Détermine si le conteneur s'inscrit dans une plage donnée. * +* * +* Retour : Bilan de la détermination, utilisable en comparaisons. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static int g_border_generator_contains_addr(const GBorderGenerator *generator, const vmpa2t *addr, size_t index, size_t repeat) +{ + return cmp_vmpa(addr, &generator->addr); + +} + + +/****************************************************************************** +* * +* Paramètres : generator = générateur à consulter. * +* index = indice de cette même ligne dans le tampon global.* +* repeat = indice d'utilisations successives du générateur. * +* * +* Description : Renseigne sur les propriétés liées à un générateur. * +* * +* Retour : Propriétés particulières associées. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static BufferLineFlags g_border_generator_get_flags(const GBorderGenerator *generator, size_t index, size_t repeat) +{ + return BLF_NONE; + +} + + +/****************************************************************************** +* * +* Paramètres : generator = générateur à utiliser pour l'impression. * +* line = ligne de rendu à compléter. * +* index = indice de cette même ligne dans le tampon global.* +* repeat = indice d'utilisations successives du générateur. * +* * +* Description : Imprime dans une ligne de rendu le contenu représenté. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_border_generator_print(GBorderGenerator *generator, GBufferLine *line, size_t index, size_t repeat) +{ + char *text; /* Texte principal à insérer */ + + assert(repeat < 3); + + g_buffer_line_fill_vmpa(line, &generator->addr, generator->msize, generator->msize); + + if (repeat == 1) + { + text = strdup(generator->start ? ROUTINE_INTRO_MSG : ROUTINE_OUTRO_MSG); + g_coding_language_encapsulate_comment(generator->lang, &text); + + g_buffer_line_start_merge_at(line, BLC_ASSEMBLY_HEAD); + g_buffer_line_append_text(line, BLC_ASSEMBLY_HEAD, SL(text), RTT_COMMENT, NULL); + + free(text); + + } + +} |