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/analysis/db | |
parent | 1b5d39bfbc48c33a0ea0924b60e48448c8b45dd4 (diff) |
Rewritten the line buffers using generators and on-demand building to save memory.
Diffstat (limited to 'src/analysis/db')
-rw-r--r-- | src/analysis/db/items/bookmark.c | 4 | ||||
-rw-r--r-- | src/analysis/db/items/comment.c | 335 | ||||
-rw-r--r-- | src/analysis/db/items/comment.h | 9 | ||||
-rw-r--r-- | src/analysis/db/items/move.h | 2 | ||||
-rw-r--r-- | src/analysis/db/items/switcher.c | 5 |
5 files changed, 336 insertions, 19 deletions
diff --git a/src/analysis/db/items/bookmark.c b/src/analysis/db/items/bookmark.c index 086b9f2..18e4bb5 100644 --- a/src/analysis/db/items/bookmark.c +++ b/src/analysis/db/items/bookmark.c @@ -409,6 +409,8 @@ static void g_db_bookmark_build_label(GDbBookmark *bookmark) static bool g_db_bookmark_run(GDbBookmark *bookmark, GLoadedBinary *binary, bool *prev, bool set) { + return false; +#if 0 bool result; /* Bilan à faire remonter */ GCodeBuffer *buffer; /* Tampon de lignes à traiter */ GBufferLine *line; /* Ligne de tampon à marquer */ @@ -437,7 +439,7 @@ static bool g_db_bookmark_run(GDbBookmark *bookmark, GLoadedBinary *binary, bool exit: return result; - +#endif } diff --git a/src/analysis/db/items/comment.c b/src/analysis/db/items/comment.c index 55893d1..3517f38 100644 --- a/src/analysis/db/items/comment.c +++ b/src/analysis/db/items/comment.c @@ -35,7 +35,10 @@ #include "../collection-int.h" #include "../item-int.h" +#include "../../human/asm/lang.h" #include "../../../common/io.h" +#include "../../../common/extstr.h" +#include "../../../glibext/linegen-int.h" @@ -52,6 +55,9 @@ struct _GDbComment rle_string text; /* Contenu du commentaire */ + char **lines; /* Lignes brutes à représenter */ + size_t count; /* Quantité de ces lignes */ + bool inlined; /* Intégration dans une ligne ?*/ union @@ -60,7 +66,9 @@ struct _GDbComment bool before; /* Zone dédiée au dessus ? */ }; - GDbComment **oldies; /* Commentaires d'origine ? */ + GLineGenerator *previous; /* Commentaire remplacé */ + + GLineGenerator **old_inlined; /* Commentaires d'origine ? */ size_t old_count; /* Nombre de places à restaurer*/ }; @@ -112,6 +120,29 @@ static bool g_db_comment_prepare_db_statement(const GDbComment *, bound_value ** /* Charge les valeurs utiles pour un commentaire. */ static bool g_db_comment_load(GDbComment *, const bound_value *, size_t); +/* Définit le commentaire associé à un commentaire. */ +static void g_db_comment_set_text(GDbComment *, const char *); + + + +/* ------------------------ OFFRE DE CAPACITES DE GENERATION ------------------------ */ + + +/* Indique le nombre de ligne prêtes à être générées. */ +static size_t g_db_comment_count_lines(const GDbComment *); + +/* Retrouve l'emplacement correspondant à une position donnée. */ +static void g_db_comment_compute_addr(const GDbComment *, gint, vmpa2t *, size_t, size_t); + +/* Détermine si le conteneur s'inscrit dans une plage donnée. */ +static int g_db_comment_contains_addr(const GDbComment *, const vmpa2t *, size_t, size_t); + +/* Renseigne sur les propriétés liées à un générateur. */ +static BufferLineFlags g_db_comment_get_flags(const GDbComment *, size_t, size_t); + +/* Imprime dans une ligne de rendu le contenu représenté. */ +static void g_db_comment_print(GDbComment *, GBufferLine *, size_t, size_t); + /* ---------------------- DEFINITION DE LA COLLECTION ASSOCIEE ---------------------- */ @@ -138,6 +169,9 @@ static void g_comment_collection_class_init(GCommentCollectionClass *); /* Initialise un commentaire sous forme de zone de texte. */ static void g_comment_collection_init(GCommentCollection *); +/* Procède à l'initialisation de l'interface de génération. */ +static void g_db_comment_interface_init(GLineGeneratorInterface *); + /* Supprime toutes les références externes. */ static void g_comment_collection_dispose(GCommentCollection *); @@ -161,7 +195,8 @@ static GDbItem *g_comment_collection_has_key(GCommentCollection *, va_list); /* Indique le type défini pour un commentaire à l'intérieur d'une zone de texte. */ -G_DEFINE_TYPE(GDbComment, g_db_comment, G_TYPE_DB_ITEM); +G_DEFINE_TYPE_WITH_CODE(GDbComment, g_db_comment, G_TYPE_DB_ITEM, + G_IMPLEMENT_INTERFACE(G_TYPE_LINE_GENERATOR, g_db_comment_interface_init)); /****************************************************************************** @@ -219,6 +254,31 @@ static void g_db_comment_class_init(GDbCommentClass *klass) static void g_db_comment_init(GDbComment *comment) { + comment->lines = NULL; + comment->count = 0; + +} + + +/****************************************************************************** +* * +* Paramètres : iface = interface GLib à initialiser. * +* * +* Description : Procède à l'initialisation de l'interface de génération. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_db_comment_interface_init(GLineGeneratorInterface *iface) +{ + iface->count = (linegen_count_lines_fc)g_db_comment_count_lines; + iface->compute = (linegen_compute_fc)g_db_comment_compute_addr; + iface->contains = (linegen_contains_fc)g_db_comment_contains_addr; + iface->get_flags = (linegen_get_flags_fc)g_db_comment_get_flags; + iface->print = (linegen_print_fc)g_db_comment_print; } @@ -239,11 +299,17 @@ static void g_db_comment_dispose(GDbComment *comment) { size_t i; /* Boucle de parcours */ + for (i = 0; i < comment->count; i++) + free(comment->lines[i]); + + if (comment->lines != NULL) + free(comment->lines); + for (i = 0; i < comment->old_count; i++) - g_object_unref(G_OBJECT(comment->oldies[i])); + g_object_unref(G_OBJECT(comment->old_inlined[i])); - if (comment->oldies != NULL) - free(comment->oldies); + if (comment->old_inlined != NULL) + free(comment->old_inlined); G_OBJECT_CLASS(g_db_comment_parent_class)->dispose(G_OBJECT(comment)); @@ -516,6 +582,134 @@ static void g_db_comment_build_label(GDbComment *comment) static bool g_db_comment_run(GDbComment *comment, GLoadedBinary *binary, bool apply) { bool result; /* Bilan à faire remonter */ + GBufferCache *cache; /* Ensemble de lignes à traiter*/ + size_t index; /* Point d'insertion */ + GArchProcessor *proc; /* Propriétaire d'instructions */ + GArchInstruction *instr; /* Instruction à traiter */ + instr_link_t *sources; /* Instructions diverses liées */ + size_t scount; /* Nbre de sources affichées */ + size_t i; /* Boucle de parcours */ + const mrange_t *range; /* Emplacement d'instruction */ + size_t linked; /* Indice lié à traiter */ + + result = true; + + cache = g_loaded_binary_get_disassembled_cache(binary); + + index = g_buffer_cache_find_index_by_addr(cache, &comment->addr, true); + + index = g_buffer_cache_look_for_flag(cache, index, BLF_HAS_CODE); + + if (comment->inlined) + { + +#define RUN_INLINED_COMMENT(idx, new, old) \ + if (apply) \ + { \ + old = g_buffer_cache_delete_type_at(cache, idx, G_TYPE_DB_COMMENT, false, false); \ + \ + g_buffer_cache_insert_at(cache, idx, G_LINE_GENERATOR(new), false, false); \ + \ + } \ + else \ + { \ + g_buffer_cache_delete_type_at(cache, idx, G_TYPE_DB_COMMENT, false, false); \ + \ + if (old != NULL) \ + { \ + g_buffer_cache_insert_at(cache, idx, old, false, false); \ + g_object_unref(G_OBJECT(old)); \ + } \ + \ + } + + /* Commentaire principal */ + + RUN_INLINED_COMMENT(index, comment, comment->previous); + + /* Renvois répétés */ + + if (comment->repeatable) + { + proc = g_loaded_binary_get_processor(binary); + + instr = g_arch_processor_find_instr_by_address(proc, &comment->addr); + assert(instr != NULL); + + scount = g_arch_instruction_get_sources(instr, &sources); + + if (apply) + { + comment->old_count = scount; + comment->old_inlined = (GLineGenerator **)realloc(comment->old_inlined, + comment->old_count * sizeof(GLineGenerator *)); + } + + for (i = 0; i < scount && result; i++) + { + range = g_arch_instruction_get_range(sources[i].linked); + + /** + * On recherche ici une ligne potentiellement BLF_HAS_CODE ou BLF_IS_LABEL. + * Comme on ne peut pas traiter les deux cas, on prend la première qui vient + * avec BLF_NONE. + */ + + linked = g_buffer_cache_find_index_by_addr(cache, get_mrange_addr(range), true); + assert(linked != g_buffer_cache_count_lines(cache)); + + RUN_INLINED_COMMENT(linked, comment, comment->old_inlined[i]); + + } + + if (!apply) + { + free(comment->old_inlined); + + comment->old_inlined = NULL; + comment->old_count = 0; + + } + + g_object_unref(G_OBJECT(proc)); + + } + + + + } + + else + { + + + + + + + + + + } + + + //void g_buffer_cache_insert_at(GBufferCache *cache, size_t index, GLineGenerator *generator, bool before, bool after) + + //GLineGenerator *g_buffer_cache_delete_type_at(GBufferCache *cache, size_t index, GType type, bool before, bool after) + + + + + g_object_unref(G_OBJECT(cache)); + + return result; + + + + +#if 0 + + bool result; /* Bilan à faire remonter */ GCodeBuffer *buffer; /* Tampon de lignes à traiter */ GBufferLine *line; /* Ligne de tampon à marquer */ GArchProcessor *proc; /* Propriétaire d'instructions */ @@ -658,7 +852,7 @@ static bool g_db_comment_run(GDbComment *comment, GLoadedBinary *binary, bool ap /* TODO g_object_unref(G_OBJECT(buffer));*/ return result; - +#endif } @@ -884,10 +1078,137 @@ const char *g_db_comment_get_text(const GDbComment *comment) * * ******************************************************************************/ -void g_db_comment_set_text(GDbComment *comment, const char *text) +static void g_db_comment_set_text(GDbComment *comment, const char *text) { + GCodingLanguage *lang; /* Langage de sortie préféré */ + set_rle_string(&comment->text, text); + lang = g_asm_language_new(); + + comment->lines = strtoka(text, "\n", &comment->count); + + g_coding_language_encapsulate_comments(lang, &comment->lines, &comment->count); + + g_object_unref(G_OBJECT(lang)); + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* OFFRE DE CAPACITES DE GENERATION */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : comment = 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_db_comment_count_lines(const GDbComment *comment) +{ + return comment->count; + +} + + +/****************************************************************************** +* * +* Paramètres : comment = 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 : - * +* * +******************************************************************************/ + +static void g_db_comment_compute_addr(const GDbComment *comment, gint x, vmpa2t *addr, size_t index, size_t repeat) +{ + copy_vmpa(addr, &comment->addr); + +} + + +/****************************************************************************** +* * +* Paramètres : comment = 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_db_comment_contains_addr(const GDbComment *comment, const vmpa2t *addr, size_t index, size_t repeat) +{ + int result; /* Conclusion à retourner */ + + result = cmp_vmpa(addr, &comment->addr); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : comment = 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_db_comment_get_flags(const GDbComment *comment, size_t index, size_t repeat) +{ + return BLF_NONE; + +} + + +/****************************************************************************** +* * +* Paramètres : comment = 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_db_comment_print(GDbComment *comment, GBufferLine *line, size_t index, size_t repeat) +{ + g_buffer_line_append_text(line, BLC_COMMENTS, SL(comment->lines[repeat]), RTT_COMMENT, NULL); + } diff --git a/src/analysis/db/items/comment.h b/src/analysis/db/items/comment.h index c5bd335..16046bc 100644 --- a/src/analysis/db/items/comment.h +++ b/src/analysis/db/items/comment.h @@ -69,15 +69,6 @@ const vmpa2t *g_db_comment_get_address(GDbComment *); /* Fournit le commentaire associé à un commentaire. */ const char *g_db_comment_get_text(const GDbComment *); -/* Définit le commentaire associé à un commentaire. */ -void g_db_comment_set_text(GDbComment *, const char *); - - - - - - - /* ---------------------- DEFINITION DE LA COLLECTION ASSOCIEE ---------------------- */ diff --git a/src/analysis/db/items/move.h b/src/analysis/db/items/move.h index a9d6d8d..115bdc8 100644 --- a/src/analysis/db/items/move.h +++ b/src/analysis/db/items/move.h @@ -96,4 +96,4 @@ GMoveCollection *g_move_collection_new(void); -#endif /* _ANALYSIS_DB_ITEMS_SWITCH_H */ +#endif /* _ANALYSIS_DB_ITEMS_MOVE_H */ diff --git a/src/analysis/db/items/switcher.c b/src/analysis/db/items/switcher.c index 748c934..3d5841c 100644 --- a/src/analysis/db/items/switcher.c +++ b/src/analysis/db/items/switcher.c @@ -496,6 +496,9 @@ static void g_db_switcher_build_label(GDbSwitcher *switcher) static bool g_db_switcher_run(GDbSwitcher *switcher, GLoadedBinary *binary, ImmOperandDisplay *old, ImmOperandDisplay new) { + return false; + +#if 0 bool result; /* Bilan à faire remonter */ GArchProcessor *proc; /* Propriétaire d'instructions */ GArchInstruction *instr; /* Instruction à traiter */ @@ -568,7 +571,7 @@ static bool g_db_switcher_run(GDbSwitcher *switcher, GLoadedBinary *binary, ImmO g_object_unref(G_OBJECT(proc)); return result; - +#endif } |