diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2014-08-05 20:19:08 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2014-08-05 20:19:08 (GMT) |
commit | 56ee4d3ecddeee05f11083fcc1595e3756b91790 (patch) | |
tree | 5ec6e5449214093280629047c36016a0de09cbeb /src | |
parent | a2eb5483fe74923e488013b2d8b94ded6340499e (diff) |
Defined the first steps for a new disassembling approach.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@387 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'src')
29 files changed, 920 insertions, 175 deletions
diff --git a/src/analysis/decomp/decompiler.c b/src/analysis/decomp/decompiler.c index 3700405..aa2fc84 100644 --- a/src/analysis/decomp/decompiler.c +++ b/src/analysis/decomp/decompiler.c @@ -73,20 +73,20 @@ static void build_decomp_prologue(GCodeBuffer *buffer, const char *filename) output = g_java_output_new(); line = g_lang_output_start_comments(output, buffer); - if (line != NULL) g_buffer_line_start_merge_at(line, BLC_ADDRESS); + if (line != NULL) g_buffer_line_start_merge_at(line, BLC_PHYSICAL); /* Introduction */ line = g_lang_output_continue_comments(output, buffer, SL(_("Binary data decompiled by Chrysalide"))); - g_buffer_line_start_merge_at(line, BLC_ADDRESS); + g_buffer_line_start_merge_at(line, BLC_PHYSICAL); line = g_lang_output_continue_comments(output, buffer, SL(_("Chrysalide is free software - © 2008-2012 Cyrille Bagard"))); - g_buffer_line_start_merge_at(line, BLC_ADDRESS); + g_buffer_line_start_merge_at(line, BLC_PHYSICAL); line = g_lang_output_continue_comments(output, buffer, NULL, 0); - g_buffer_line_start_merge_at(line, BLC_ADDRESS); + g_buffer_line_start_merge_at(line, BLC_PHYSICAL); /* Fichier */ @@ -99,19 +99,19 @@ static void build_decomp_prologue(GCodeBuffer *buffer, const char *filename) snprintf(content, len, "%s%s", _("File: "), filename); line = g_lang_output_continue_comments(output, buffer, content, len - 1); - g_buffer_line_start_merge_at(line, BLC_ADDRESS); + g_buffer_line_start_merge_at(line, BLC_PHYSICAL); free(content); /* Ligne de séparation */ line = g_lang_output_continue_comments(output, buffer, NULL, 0); - g_buffer_line_start_merge_at(line, BLC_ADDRESS); + g_buffer_line_start_merge_at(line, BLC_PHYSICAL); /* Conclusion */ line = g_lang_output_end_comments(output, buffer); - if (line != NULL) g_buffer_line_start_merge_at(line, BLC_ADDRESS); + if (line != NULL) g_buffer_line_start_merge_at(line, BLC_PHYSICAL); g_object_unref(G_OBJECT(output)); diff --git a/src/analysis/disass/disassembler.c b/src/analysis/disass/disassembler.c index 8020e02..9344089 100644 --- a/src/analysis/disass/disassembler.c +++ b/src/analysis/disass/disassembler.c @@ -191,9 +191,149 @@ static GDelayedDisassembly *g_delayed_disassembly_new(GLoadedBinary *binary, GBi * Remarques : - * * * ******************************************************************************/ +#include "../../arch/vmpa.h" +#include <time.h> + +#include <sys/time.h> +#include <sys/resource.h> static void g_delayed_disassembly_process(GDelayedDisassembly *disass, GtkExtStatusBar *statusbar) { + + + unsigned int valid; /* Instructions traduites */ + unsigned int db; /* Instructions non décodées */ + unsigned int valid_sum; /* Instructions traduites */ + unsigned int instr_sum; /* Instructions totales */ + size_t i; /* Boucle de parcours */ + + GBinRoutine **routines; /* Liste des routines trouvées */ + size_t routines_count; /* Nombre de ces routines */ + bstatus_id_t id; /* Identifiant de statut */ + + + + vmpa2t base; + + + + clock_t begin, end; + double time_spent; + + + struct rusage usage; + unsigned long ustart; + unsigned long uend; + + + + /* Première étape */ + + id = gtk_extended_status_bar_push(statusbar, _("Disassembling..."), true); + + + init_vmpa(&base, 0, 0); + + + + begin = clock(); + + getrusage(RUSAGE_THREAD, &usage); + ustart = usage.ru_utime.tv_sec * 1000000 + usage.ru_utime.tv_usec; + ustart += usage.ru_stime.tv_sec * 1000000 + usage.ru_stime.tv_usec; + + + *disass->instrs = load_raw_binary(disass->binary, &base, 100, statusbar, id); + + /* + *disass->instrs = disassemble_binary_parts(disass->binary, disass->parts, disass->count, + statusbar, id); + */ + + + + getrusage(RUSAGE_THREAD, &usage); + uend = usage.ru_utime.tv_sec * 1000000 + usage.ru_utime.tv_usec; + uend += usage.ru_stime.tv_sec * 1000000 + usage.ru_stime.tv_usec; + + + end = clock(); + + time_spent = (double)(end - begin) / CLOCKS_PER_SEC; + + printf("[[ TIME ]] Disassembly :: %.2g (%.2g)\n", time_spent, (uend - ustart) / 1000000.0); + + + + + gtk_extended_status_bar_remove(statusbar, id); + + + run_plugins_on_binary(disass->binary, PGA_BINARY_DISASSEMBLED, true); + + + + + + + /* Septième étape */ + + id = gtk_extended_status_bar_push(statusbar, _("Printing disassembled code..."), true); + + qsort(routines, routines_count, sizeof(GBinRoutine *), (__compar_fn_t)g_binary_routine_compare); + + + begin = clock(); + + + getrusage(RUSAGE_THREAD, &usage); + ustart = usage.ru_utime.tv_sec * 1000000 + usage.ru_utime.tv_usec; + ustart += usage.ru_stime.tv_sec * 1000000 + usage.ru_stime.tv_usec; + + + print_disassembled_instructions(disass->buffer, disass->format, *disass->instrs, + routines, routines_count, statusbar, id); + + + + + + getrusage(RUSAGE_THREAD, &usage); + uend = usage.ru_utime.tv_sec * 1000000 + usage.ru_utime.tv_usec; + uend += usage.ru_stime.tv_sec * 1000000 + usage.ru_stime.tv_usec; + + + end = clock(); + + time_spent = (double)(end - begin) / CLOCKS_PER_SEC; + + printf("[[ TIME ]] Printing :: %.2g (%.2g)\n", time_spent, (uend - ustart) / 1000000.0); + + + gtk_extended_status_bar_remove(statusbar, id); + + run_plugins_on_binary(disass->binary, PGA_BINARY_PRINTED, true); + + + +} + + +/****************************************************************************** +* * +* Paramètres : disass = analyse à mener. * +* statusbar = barre de statut à tenir informée. * +* * +* Description : Assure le désassemblage en différé. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_delayed_disassembly_process_old(GDelayedDisassembly *disass, GtkExtStatusBar *statusbar) +{ #ifdef DEBUG unsigned int valid; /* Instructions traduites */ unsigned int db; /* Instructions non décodées */ @@ -339,20 +479,20 @@ static void build_disass_prologue(GCodeBuffer *buffer, const char *filename, con output = g_asm_output_new(); line = g_lang_output_start_comments(output, buffer); - if (line != NULL) g_buffer_line_start_merge_at(line, BLC_ADDRESS); + if (line != NULL) g_buffer_line_start_merge_at(line, BLC_PHYSICAL); /* Introduction */ line = g_lang_output_continue_comments(output, buffer, SL(_("Disassembly generated by Chrysalide"))); - g_buffer_line_start_merge_at(line, BLC_ADDRESS); + g_buffer_line_start_merge_at(line, BLC_PHYSICAL); line = g_lang_output_continue_comments(output, buffer, SL(_("Chrysalide is free software - © 2008-2014 Cyrille Bagard"))); - g_buffer_line_start_merge_at(line, BLC_ADDRESS); + g_buffer_line_start_merge_at(line, BLC_PHYSICAL); line = g_lang_output_continue_comments(output, buffer, NULL, 0); - g_buffer_line_start_merge_at(line, BLC_ADDRESS); + g_buffer_line_start_merge_at(line, BLC_PHYSICAL); /* Fichier */ @@ -362,7 +502,7 @@ static void build_disass_prologue(GCodeBuffer *buffer, const char *filename, con snprintf(content, len, "%s%s", _("File: "), filename); line = g_lang_output_continue_comments(output, buffer, content, len - 1); - g_buffer_line_start_merge_at(line, BLC_ADDRESS); + g_buffer_line_start_merge_at(line, BLC_PHYSICAL); free(content); @@ -381,19 +521,19 @@ static void build_disass_prologue(GCodeBuffer *buffer, const char *filename, con g_checksum_free(checksum); line = g_lang_output_continue_comments(output, buffer, content, len - 1); - g_buffer_line_start_merge_at(line, BLC_ADDRESS); + g_buffer_line_start_merge_at(line, BLC_PHYSICAL); free(content); /* Ligne de séparation */ line = g_lang_output_continue_comments(output, buffer, NULL, 0); - g_buffer_line_start_merge_at(line, BLC_ADDRESS); + g_buffer_line_start_merge_at(line, BLC_PHYSICAL); /* Conclusion */ line = g_lang_output_end_comments(output, buffer); - if (line != NULL) g_buffer_line_start_merge_at(line, BLC_ADDRESS); + if (line != NULL) g_buffer_line_start_merge_at(line, BLC_PHYSICAL); g_object_unref(G_OBJECT(output)); diff --git a/src/analysis/disass/fetch.c b/src/analysis/disass/fetch.c index 17eea6a..4686fe2 100644 --- a/src/analysis/disass/fetch.c +++ b/src/analysis/disass/fetch.c @@ -23,6 +23,117 @@ #include "fetch.h" + +#include "../../arch/artificial.h" + + + + + + + + +/****************************************************************************** +* * +* Paramètres : binary = représentation de binaire chargé. * +* parts = parties binaires à désassembler. * +* count = nombre de parties à traiter. * +* statusbar = barre de statut avec progression à mettre à jour.* +* id = identifiant du message affiché à l'utilisateur. * +* * +* Description : Procède au désassemblage basique d'un contenu binaire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +GArchInstruction *load_raw_binary(const GLoadedBinary *binary, const vmpa2t *base, off_t end, GtkExtStatusBar *statusbar, bstatus_id_t id) +{ + GArchInstruction *result; /* Liste d'instr. à renvoyer */ + GBinFormat *format; /* Format du fichier binaire */ + GArchProcessor *proc; /* Architecture du binaire */ + off_t bin_length; /* Taille des données à lire */ + bin_t *bin_data; /* Données binaires à lire */ + vmpa2t *pos; /* Boucle de parcours */ + vmpa2t *prev; /* Boucle de parcours */ + off_t old_phy; /* Ancienne position physique */ + GArchInstruction *instr; /* Instruction décodée */ + off_t new_phy; /* Nouvelle position physique */ + + result = NULL; + + format = G_BIN_FORMAT(g_loaded_binary_get_format(binary)); + proc = get_arch_processor_from_format(G_EXE_FORMAT(format)); + bin_data = g_loaded_binary_get_data(binary, &bin_length); + + end = bin_length; + + pos = local_dup_vmpa(base); + prev = local_dup_vmpa(base); + + old_phy = get_phy_addr(prev); + + while (old_phy < end) + { + instr = g_db_instruction_new_from_data(bin_data, pos, end, proc); + if (instr == NULL) break; + + new_phy = get_phy_addr(pos); + + g_arch_instruction_set_location(instr, prev, new_phy - old_phy); + g_arch_instruction_add_to_list(&result, instr); + + copy_vmpa(prev, pos); + old_phy = get_phy_addr(prev); + + //done += (new_phy - old_phy); + //gtk_extended_status_bar_update_activity(statusbar, id, done * 1.0 / sum); + + } + + return result; + +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #ifdef DEBUG # include "../../arch/artificial.h" #endif @@ -139,3 +250,14 @@ GArchInstruction *disassemble_binary_parts(const GLoadedBinary *binary, GBinPart return result; } + + + + + + + + + + + diff --git a/src/analysis/disass/fetch.h b/src/analysis/disass/fetch.h index 87f3134..ff62ce8 100644 --- a/src/analysis/disass/fetch.h +++ b/src/analysis/disass/fetch.h @@ -30,6 +30,13 @@ #include "../../gtkext/gtkextstatusbar.h" + + +GArchInstruction *load_raw_binary(const GLoadedBinary *binary, const vmpa2t *base, off_t end, GtkExtStatusBar *statusbar, bstatus_id_t id); + + + + /* Procède au désassemblage basique d'un contenu binaire. */ GArchInstruction *disassemble_binary_parts(const GLoadedBinary *, GBinPart **, size_t, GtkExtStatusBar *, bstatus_id_t); diff --git a/src/analysis/disass/output.c b/src/analysis/disass/output.c index fd7efce..97f9989 100644 --- a/src/analysis/disass/output.c +++ b/src/analysis/disass/output.c @@ -76,6 +76,7 @@ void print_disassembled_instructions(GCodeBuffer *buffer, const GExeFormat *form iter != NULL; iter = g_arch_instruction_get_next_iter(instrs, iter, VMPA_MAX)) { +#if 0 g_arch_instruction_get_location(iter, NULL, NULL, &iaddr); /* Ajout des prototypes de fonction */ @@ -87,10 +88,11 @@ void print_disassembled_instructions(GCodeBuffer *buffer, const GExeFormat *form g_binary_routine_output_info(routines[i], output, buffer); } +#endif g_arch_instruction_print(iter, buffer, msize, content, ASX_INTEL); - gtk_extended_status_bar_update_activity(statusbar, id, (iaddr - start) * 1.0 / (end - start)); + //gtk_extended_status_bar_update_activity(statusbar, id, (iaddr - start) * 1.0 / (end - start)); } diff --git a/src/arch/arm/v456/instruction.c b/src/arch/arm/v456/instruction.c index 3ba3c54..b5df0f8 100644 --- a/src/arch/arm/v456/instruction.c +++ b/src/arch/arm/v456/instruction.c @@ -180,7 +180,7 @@ static void g_armv456_instruction_init(GArmV456Instruction *instr) parent = G_ARCH_INSTRUCTION(instr); - parent->get_text = (get_instruction_text_fc)g_armv456_get_instruction_text; + //parent->get_text = (get_instruction_text_fc)g_armv456_get_instruction_text; /* parent->get_rw_regs = (get_instruction_rw_regs_fc)g_armv456_instruction_get_rw_registers; diff --git a/src/arch/artificial.c b/src/arch/artificial.c index 6fbd6d9..4131e5f 100644 --- a/src/arch/artificial.c +++ b/src/arch/artificial.c @@ -57,8 +57,14 @@ static void g_db_instruction_class_init(GDbInstructionClass *); /* Initialise une instance d'opérande d'architecture. */ static void g_db_instruction_init(GDbInstruction *); -/* Traduit une instruction en version humainement lisible. */ -static const char *g_db_instruction_get_text(const GDbInstruction *, const GExeFormat *, AsmSyntax); +/* Supprime toutes les références externes. */ +static void g_db_instruction_dispose(GDbInstruction *); + +/* Procède à la libération totale de la mémoire. */ +static void g_db_instruction_finalize(GDbInstruction *); + +/* Fournit le nom humain de l'instruction manipulée. */ +static const char *g_db_instruction_get_keyword(const GDbInstruction *, AsmSyntax); /* Informe sur une éventuelle référence à une autre instruction. */ static InstructionLinkType g_db_instruction_get_link(const GDbInstruction *, vmpa_t *); @@ -91,6 +97,17 @@ G_DEFINE_TYPE(GDbInstruction, g_db_instruction, G_TYPE_ARCH_INSTRUCTION); static void g_db_instruction_class_init(GDbInstructionClass *klass) { + GObjectClass *object; /* Autre version de la classe */ + GArchInstructionClass *instr; /* Encore une autre vision... */ + + object = G_OBJECT_CLASS(klass); + + object->dispose = (GObjectFinalizeFunc/* ! */)g_db_instruction_dispose; + object->finalize = (GObjectFinalizeFunc)g_db_instruction_finalize; + + instr = G_ARCH_INSTRUCTION_CLASS(klass); + + instr->get_key = (get_instruction_keyword_fc)g_db_instruction_get_keyword; } @@ -113,7 +130,6 @@ static void g_db_instruction_init(GDbInstruction *instr) parent = G_ARCH_INSTRUCTION(instr); - parent->get_text = (get_instruction_text_fc)g_db_instruction_get_text; parent->get_link = (get_instruction_link_fc)g_db_instruction_get_link; parent->is_return = (is_instruction_return_fc)g_db_instruction_is_return; @@ -122,6 +138,44 @@ static void g_db_instruction_init(GDbInstruction *instr) /****************************************************************************** * * +* Paramètres : instr = instance d'objet GLib à traiter. * +* * +* Description : Supprime toutes les références externes. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_db_instruction_dispose(GDbInstruction *instr) +{ + G_OBJECT_CLASS(g_db_instruction_parent_class)->dispose(G_OBJECT(instr)); + +} + + +/****************************************************************************** +* * +* Paramètres : instr = instance d'objet GLib à traiter. * +* * +* Description : Procède à la libération totale de la mémoire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_db_instruction_finalize(GDbInstruction *instr) +{ + G_OBJECT_CLASS(g_db_instruction_parent_class)->finalize(G_OBJECT(instr)); + +} + + +/****************************************************************************** +* * * Paramètres : data = flux de données à analyser. * * pos = position courante dans ce flux. [OUT] * * end = limite des données à analyser. * @@ -136,16 +190,26 @@ static void g_db_instruction_init(GDbInstruction *instr) * * ******************************************************************************/ -GArchInstruction *g_db_instruction_new_from_data(const bin_t *data, off_t *pos, off_t end, vmpa_t addr, const GArchProcessor *proc) +GArchInstruction *g_db_instruction_new_from_data(const bin_t *data, vmpa2t *address, off_t end, const GArchProcessor *proc) { GArchInstruction *result; /* Instruction à retourner */ + off_t pos; + off_t old; GArchOperand *operand; /* Octet non décodé à afficher */ result = g_object_new(G_TYPE_DB_INSTRUCTION, NULL); + pos = get_phy_addr(address); + old = pos; + operand = g_imm_operand_new_from_data(g_arch_processor_get_instruction_size(proc), - data, pos, end, + data, &pos, end, g_arch_processor_get_endianness(proc)); + + address->physical += (pos - old); + + /* FIXME : essayer une taille plus petite en cas d'échec (on peut être en bout de binaire) */ + if (operand == NULL) goto gdinfd_error; g_imm_operand_pad(G_IMM_OPERAND(operand), true); @@ -169,15 +233,15 @@ GArchInstruction *g_db_instruction_new_from_data(const bin_t *data, off_t *pos, * format = format du binaire manipulé. * * syntax = type de représentation demandée. * * * -* Description : Traduit une instruction en version humainement lisible. * +* Description : Fournit le nom humain de l'instruction manipulée. * * * -* Retour : Chaîne de caractères à libérer de la mémoire. * +* Retour : Mot clef de bas niveau. * * * * Remarques : - * * * ******************************************************************************/ -static const char *g_db_instruction_get_text(const GDbInstruction *instr, const GExeFormat *format, AsmSyntax syntax) +static const char *g_db_instruction_get_keyword(const GDbInstruction *instr, AsmSyntax syntax) { return "db"; diff --git a/src/arch/artificial.h b/src/arch/artificial.h index b341644..65eb4fe 100644 --- a/src/arch/artificial.h +++ b/src/arch/artificial.h @@ -30,6 +30,7 @@ #include "archbase.h" #include "processor.h" +#include "vmpa.h" @@ -53,7 +54,7 @@ typedef struct _GDbInstructionClass GDbInstructionClass; GType g_db_instruction_get_type(void); /* Crée une instruction de type 'db' à partir de données. */ -GArchInstruction *g_db_instruction_new_from_data(const bin_t *, off_t *, off_t, vmpa_t, const GArchProcessor *); +GArchInstruction *g_db_instruction_new_from_data(const bin_t *, vmpa2t *, off_t, const GArchProcessor *); #ifdef DEBUG diff --git a/src/arch/dalvik/instruction.c b/src/arch/dalvik/instruction.c index 83e0e6c..c0c6675 100644 --- a/src/arch/dalvik/instruction.c +++ b/src/arch/dalvik/instruction.c @@ -39,6 +39,12 @@ static void g_dalvik_instruction_class_init(GDalvikInstructionClass *); /* Initialise une instance d'opérande d'architecture Dalvik. */ static void g_dalvik_instruction_init(GDalvikInstruction *); +/* Supprime toutes les références externes. */ +static void g_dalvik_instruction_dispose(GDalvikInstruction *); + +/* Procède à la libération totale de la mémoire. */ +static void g_dalvik_instruction_finalize(GDalvikInstruction *); + /* Liste les registres lus et écrits par l'instruction. */ static void g_dalvik_instruction_get_rw_registers(const GDalvikInstruction *, GArchRegister ***, size_t *, GArchRegister ***, size_t *); @@ -321,8 +327,8 @@ static dalvik_instruction _instructions[DOP_COUNT] = { }; -/* Traduit une instruction en version humainement lisible. */ -static const char *dalvik_get_instruction_text(const GDalvikInstruction *, const GExeFormat *, AsmSyntax); +/* Fournit le nom humain de l'instruction manipulée. */ +static const char *dalvik_get_instruction_keyword(const GDalvikInstruction *, AsmSyntax); /* Informe sur une éventuelle référence à une autre instruction. */ static InstructionLinkType dalvik_get_instruction_link(const GDalvikInstruction *, vmpa_t *); @@ -354,6 +360,17 @@ G_DEFINE_TYPE(GDalvikInstruction, g_dalvik_instruction, G_TYPE_ARCH_INSTRUCTION) static void g_dalvik_instruction_class_init(GDalvikInstructionClass *klass) { + GObjectClass *object; /* Autre version de la classe */ + GArchInstructionClass *instr; /* Encore une autre vision... */ + + object = G_OBJECT_CLASS(klass); + + object->dispose = (GObjectFinalizeFunc/* ! */)g_dalvik_instruction_dispose; + object->finalize = (GObjectFinalizeFunc)g_dalvik_instruction_finalize; + + instr = G_ARCH_INSTRUCTION_CLASS(klass); + + instr->get_key = (get_instruction_keyword_fc)dalvik_get_instruction_keyword; } @@ -377,7 +394,6 @@ static void g_dalvik_instruction_init(GDalvikInstruction *instr) parent = G_ARCH_INSTRUCTION(instr); parent->get_rw_regs = (get_instruction_rw_regs_fc)g_dalvik_instruction_get_rw_registers; - parent->get_text = (get_instruction_text_fc)dalvik_get_instruction_text; parent->get_link = (get_instruction_link_fc)dalvik_get_instruction_link; parent->is_return = (is_instruction_return_fc)dalvik_instruction_is_return; parent->decomp = (decomp_instr_fc)dalvik_instruction_decompile; @@ -387,6 +403,44 @@ static void g_dalvik_instruction_init(GDalvikInstruction *instr) /****************************************************************************** * * +* Paramètres : instr = instance d'objet GLib à traiter. * +* * +* Description : Supprime toutes les références externes. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_dalvik_instruction_dispose(GDalvikInstruction *instr) +{ + G_OBJECT_CLASS(g_dalvik_instruction_parent_class)->dispose(G_OBJECT(instr)); + +} + + +/****************************************************************************** +* * +* Paramètres : instr = instance d'objet GLib à traiter. * +* * +* Description : Procède à la libération totale de la mémoire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_dalvik_instruction_finalize(GDalvikInstruction *instr) +{ + G_OBJECT_CLASS(g_dalvik_instruction_parent_class)->finalize(G_OBJECT(instr)); + +} + + +/****************************************************************************** +* * * Paramètres : type = type d'instruction à représenter. * * * * Description : Crée une instruction pour l'architecture Dalvik. * @@ -517,18 +571,17 @@ DalvikOpcodes dalvik_guess_next_instruction(const bin_t *data, off_t pos, off_t /****************************************************************************** * * * Paramètres : instr = instruction à traiter. * -* format = format du binaire manipulé. * * syntax = type de représentation demandée. * * * -* Description : Traduit une instruction en version humainement lisible. * +* Description : Fournit le nom humain de l'instruction manipulée. * * * -* Retour : Chaîne de caractères à libérer de la mémoire. * +* Retour : Mot clef de bas niveau. * * * * Remarques : - * * * ******************************************************************************/ -static const char *dalvik_get_instruction_text(const GDalvikInstruction *instr, const GExeFormat *format, AsmSyntax syntax) +static const char *dalvik_get_instruction_keyword(const GDalvikInstruction *instr, AsmSyntax syntax) { return _instructions[instr->type].keyword; diff --git a/src/arch/dalvik/pseudo/fill.c b/src/arch/dalvik/pseudo/fill.c index 702f4b9..acb8551 100644 --- a/src/arch/dalvik/pseudo/fill.c +++ b/src/arch/dalvik/pseudo/fill.c @@ -56,6 +56,12 @@ static void g_dalvik_fill_instr_class_init(GDalvikFillInstrClass *); /* Initialise une instance d'opérande d'architecture. */ static void g_dalvik_fill_instr_init(GDalvikFillInstr *); +/* Supprime toutes les références externes. */ +static void g_dalvik_fill_instr_dispose(GDalvikFillInstr *); + +/* Procède à la libération totale de la mémoire. */ +static void g_dalvik_fill_instr_finalize(GDalvikFillInstr *); + /* Ajoute à un tampon GLib le contenu de l'instance spécifiée. */ static void g_dalvik_fill_instr_print(const GDalvikFillInstr *, GCodeBuffer *, MemoryDataSize, const bin_t *, AsmSyntax); @@ -79,6 +85,17 @@ G_DEFINE_TYPE(GDalvikFillInstr, g_dalvik_fill_instr, G_TYPE_DALVIK_INSTRUCTION); static void g_dalvik_fill_instr_class_init(GDalvikFillInstrClass *klass) { + GObjectClass *object; /* Autre version de la classe */ + GArchInstructionClass *instr; /* Encore une autre vision... */ + + object = G_OBJECT_CLASS(klass); + + object->dispose = (GObjectFinalizeFunc/* ! */)g_dalvik_fill_instr_dispose; + object->finalize = (GObjectFinalizeFunc)g_dalvik_fill_instr_finalize; + + instr = G_ARCH_INSTRUCTION_CLASS(klass); + + instr->print = (print_instruction_fc)g_dalvik_fill_instr_print; } @@ -97,11 +114,44 @@ static void g_dalvik_fill_instr_class_init(GDalvikFillInstrClass *klass) static void g_dalvik_fill_instr_init(GDalvikFillInstr *instr) { - GArchInstruction *parent; /* Instance parente */ - parent = G_ARCH_INSTRUCTION(instr); +} + + +/****************************************************************************** +* * +* Paramètres : instr = instance d'objet GLib à traiter. * +* * +* Description : Supprime toutes les références externes. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ - parent->print = (print_instruction_fc)g_dalvik_fill_instr_print; +static void g_dalvik_fill_instr_dispose(GDalvikFillInstr *instr) +{ + G_OBJECT_CLASS(g_dalvik_fill_instr_parent_class)->dispose(G_OBJECT(instr)); + +} + + +/****************************************************************************** +* * +* Paramètres : instr = instance d'objet GLib à traiter. * +* * +* Description : Procède à la libération totale de la mémoire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_dalvik_fill_instr_finalize(GDalvikFillInstr *instr) +{ + G_OBJECT_CLASS(g_dalvik_fill_instr_parent_class)->finalize(G_OBJECT(instr)); } @@ -179,13 +229,20 @@ static void g_dalvik_fill_instr_print(const GDalvikFillInstr *instr, GCodeBuffer base = G_ARCH_INSTRUCTION(instr); + line = NULL; + + +#if 0 + line = g_code_buffer_append_new_line(buffer, base->address); /* Adresse virtuelle ou physique */ len = vmpa_to_string(base->address, msize, address); - g_buffer_line_insert_text(line, BLC_ADDRESS, address, len, RTT_RAW); + g_buffer_line_insert_text(line, BLC_PHYSICAL, address, len, RTT_RAW); + + /* TODO ... */ /* Code brut */ @@ -204,6 +261,8 @@ static void g_dalvik_fill_instr_print(const GDalvikFillInstr *instr, GCodeBuffer free(bin_code); +#endif + /* Instruction proprement dite */ key = "<fill-array>"; diff --git a/src/arch/dalvik/pseudo/switch.c b/src/arch/dalvik/pseudo/switch.c index c97c82b..169c5bf 100644 --- a/src/arch/dalvik/pseudo/switch.c +++ b/src/arch/dalvik/pseudo/switch.c @@ -55,6 +55,12 @@ static void g_dalvik_switch_instr_class_init(GDalvikSwitchInstrClass *); /* Initialise une instance d'opérande d'architecture. */ static void g_dalvik_switch_instr_init(GDalvikSwitchInstr *); +/* Supprime toutes les références externes. */ +static void g_dalvik_switch_instr_dispose(GDalvikSwitchInstr *); + +/* Procède à la libération totale de la mémoire. */ +static void g_dalvik_switch_instr_finalize(GDalvikSwitchInstr *); + /* Ajoute à un tampon GLib le contenu de l'instance spécifiée. */ static void g_dalvik_switch_instr_print(const GDalvikSwitchInstr *, GCodeBuffer *, MemoryDataSize, const bin_t *, AsmSyntax); @@ -78,6 +84,17 @@ G_DEFINE_TYPE(GDalvikSwitchInstr, g_dalvik_switch_instr, G_TYPE_DALVIK_INSTRUCTI static void g_dalvik_switch_instr_class_init(GDalvikSwitchInstrClass *klass) { + GObjectClass *object; /* Autre version de la classe */ + GArchInstructionClass *instr; /* Encore une autre vision... */ + + object = G_OBJECT_CLASS(klass); + + object->dispose = (GObjectFinalizeFunc/* ! */)g_dalvik_switch_instr_dispose; + object->finalize = (GObjectFinalizeFunc)g_dalvik_switch_instr_finalize; + + instr = G_ARCH_INSTRUCTION_CLASS(klass); + + instr->print = (print_instruction_fc)g_dalvik_switch_instr_print; } @@ -96,11 +113,44 @@ static void g_dalvik_switch_instr_class_init(GDalvikSwitchInstrClass *klass) static void g_dalvik_switch_instr_init(GDalvikSwitchInstr *instr) { - GArchInstruction *parent; /* Instance parente */ - parent = G_ARCH_INSTRUCTION(instr); +} + + +/****************************************************************************** +* * +* Paramètres : instr = instance d'objet GLib à traiter. * +* * +* Description : Supprime toutes les références externes. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_dalvik_switch_instr_dispose(GDalvikSwitchInstr *instr) +{ + G_OBJECT_CLASS(g_dalvik_switch_instr_parent_class)->dispose(G_OBJECT(instr)); + +} - parent->print = (print_instruction_fc)g_dalvik_switch_instr_print; + +/****************************************************************************** +* * +* Paramètres : instr = instance d'objet GLib à traiter. * +* * +* Description : Procède à la libération totale de la mémoire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_dalvik_switch_instr_finalize(GDalvikSwitchInstr *instr) +{ + G_OBJECT_CLASS(g_dalvik_switch_instr_parent_class)->finalize(G_OBJECT(instr)); } @@ -182,13 +232,19 @@ static void g_dalvik_switch_instr_print(const GDalvikSwitchInstr *instr, GCodeBu base = G_ARCH_INSTRUCTION(instr); + line = NULL; + + +#if 0 line = g_code_buffer_append_new_line(buffer, base->address); /* Adresse virtuelle ou physique */ len = vmpa_to_string(base->address, msize, address); - g_buffer_line_insert_text(line, BLC_ADDRESS, address, len, RTT_RAW); + g_buffer_line_insert_text(line, BLC_PHYSICAL, address, len, RTT_RAW); + + /* TODO ... */ /* Code brut */ @@ -207,6 +263,8 @@ static void g_dalvik_switch_instr_print(const GDalvikSwitchInstr *instr, GCodeBu free(bin_code); +#endif + /* Instruction proprement dite */ key = "<fill-array>"; diff --git a/src/arch/instruction-int.h b/src/arch/instruction-int.h index 98f1eea..076eec2 100644 --- a/src/arch/instruction-int.h +++ b/src/arch/instruction-int.h @@ -39,7 +39,7 @@ typedef void (* get_instruction_rw_regs_fc) (const GArchInstruction *, GArchRegi typedef void (* print_instruction_fc) (const GArchInstruction *, GCodeBuffer *, MemoryDataSize, const bin_t *, AsmSyntax); /* Traduit une instruction en version humainement lisible. */ -typedef const char * (* get_instruction_text_fc) (const GArchInstruction *, const GExeFormat *, AsmSyntax); +typedef const char * (* get_instruction_keyword_fc) (const GArchInstruction *, AsmSyntax); /* Informe sur une éventuelle référence à une autre instruction. */ typedef InstructionLinkType (* get_instruction_link_fc) (const GArchInstruction *, vmpa_t *); @@ -55,6 +55,7 @@ struct _GArchInstruction DL_LIST_ITEM(flow); /* Maillon de liste chaînée */ + vmpa2t address2; /* Position associée */ off_t offset; /* Position physique de départ */ off_t length; /* Taille de l'instruction */ @@ -72,8 +73,8 @@ struct _GArchInstruction size_t to_count; /* Nombre de ces destinations */ get_instruction_rw_regs_fc get_rw_regs; /* Liste des registres liés */ - print_instruction_fc print; /* Imprime l'ensemble */ - get_instruction_text_fc get_text; /* Texte humain équivalent */ + //print_instruction_fc print; /* Imprime l'ensemble */ + //get_instruction_keyword_fc get_key; /* Texte humain équivalent */ get_instruction_link_fc get_link; /* Référence à une instruction */ is_instruction_return_fc is_return; /* Retour de fonction ou pas ? */ decomp_instr_fc decomp; /* Procédure de décompilation */ @@ -86,6 +87,9 @@ struct _GArchInstructionClass { GObjectClass parent; /* A laisser en premier */ + print_instruction_fc print; /* Imprime l'ensemble */ + get_instruction_keyword_fc get_key; /* Texte humain équivalent */ + }; diff --git a/src/arch/instruction.c b/src/arch/instruction.c index 72911bf..3a62a90 100644 --- a/src/arch/instruction.c +++ b/src/arch/instruction.c @@ -39,6 +39,12 @@ static void g_arch_instruction_class_init(GArchInstructionClass *); /* Initialise une instance d'opérande d'architecture. */ static void g_arch_instruction_init(GArchInstruction *); +/* Supprime toutes les références externes. */ +static void g_arch_instruction_dispose(GArchInstruction *); + +/* Procède à la libération totale de la mémoire. */ +static void g_arch_instruction_finalize(GArchInstruction *); + /* --------------------- CONVERSIONS DU FORMAT DES INSTRUCTIONS --------------------- */ @@ -67,6 +73,17 @@ G_DEFINE_TYPE(GArchInstruction, g_arch_instruction, G_TYPE_OBJECT); static void g_arch_instruction_class_init(GArchInstructionClass *klass) { + GObjectClass *object; /* Autre version de la classe */ + GArchInstructionClass *instr; /* Encore une autre vision... */ + + object = G_OBJECT_CLASS(klass); + + object->dispose = (GObjectFinalizeFunc/* ! */)g_arch_instruction_dispose; + object->finalize = (GObjectFinalizeFunc)g_arch_instruction_finalize; + + instr = G_ARCH_INSTRUCTION_CLASS(klass); + + instr->print = (print_instruction_fc)_g_arch_instruction_print; } @@ -92,10 +109,47 @@ static void g_arch_instruction_init(GArchInstruction *instr) /****************************************************************************** * * +* Paramètres : instr = instance d'objet GLib à traiter. * +* * +* Description : Supprime toutes les références externes. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_arch_instruction_dispose(GArchInstruction *instr) +{ + G_OBJECT_CLASS(g_arch_instruction_parent_class)->dispose(G_OBJECT(instr)); + +} + + +/****************************************************************************** +* * +* Paramètres : instr = instance d'objet GLib à traiter. * +* * +* Description : Procède à la libération totale de la mémoire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_arch_instruction_finalize(GArchInstruction *instr) +{ + G_OBJECT_CLASS(g_arch_instruction_parent_class)->finalize(G_OBJECT(instr)); + +} + + +/****************************************************************************** +* * * Paramètres : instr = instruction quelconque à modifier. * -* offset = position physique dans le code binaire. * +* address = adresse virtuelle et/ou position physique. * * length = taille de l'instruction. * -* address = adresse virtuelle ou position physique. * * * * Description : Définit la localisation d'une instruction. * * * @@ -105,12 +159,15 @@ static void g_arch_instruction_init(GArchInstruction *instr) * * ******************************************************************************/ -void g_arch_instruction_set_location(GArchInstruction *instr, off_t offset, off_t length, vmpa_t address) +void g_arch_instruction_set_location(GArchInstruction *instr, const vmpa2t *address, off_t length) { - instr->offset = offset; - instr->length = length; + copy_vmpa(&instr->address2, address); + + /* FIXME */ + instr->offset = get_phy_addr(address); + instr->address = get_virt_addr(address); - instr->address = address; + instr->length = length; } @@ -578,6 +635,7 @@ size_t g_arch_instruction_compute_group_index(GArchInstruction **iter, GArchInst /****************************************************************************** * * * Paramètres : instr = instruction d'assemblage à consulter. * +* syntax = type de représentation demandée. * * * * Description : Fournit le nom humain de l'instruction manipulée. * * * @@ -587,9 +645,9 @@ size_t g_arch_instruction_compute_group_index(GArchInstruction **iter, GArchInst * * ******************************************************************************/ -const char *g_arch_instruction_get_keyword(const GArchInstruction *instr) +const char *g_arch_instruction_get_keyword(const GArchInstruction *instr, AsmSyntax syntax) { - return instr->get_text(instr, NULL/* FIXME */, 0/* FIXME */); + G_ARCH_INSTRUCTION_GET_CLASS(instr)->get_key(instr, syntax); } @@ -611,42 +669,17 @@ const char *g_arch_instruction_get_keyword(const GArchInstruction *instr) static void _g_arch_instruction_print(const GArchInstruction *instr, GCodeBuffer *buffer, MemoryDataSize msize, const bin_t *content, AsmSyntax syntax) { GBufferLine *line; /* Ligne de destination */ - char address[VMPA_MAX_SIZE]; /* Adresse au format texte */ - size_t len; /* Taille de l'élément inséré */ - char *bin_code; /* Tampon du code binaire */ - off_t i; /* Boucle de parcours #1 */ const char *key; /* Mot clef principal */ size_t klen; /* Taille de ce mot clef */ - size_t j; /* Boucle de parcours #2 */ - - line = g_code_buffer_append_new_line(buffer, instr->address); - - /* Adresse virtuelle ou physique */ - - len = vmpa_to_string(instr->address, msize, address); - - g_buffer_line_insert_text(line, BLC_ADDRESS, address, len, RTT_RAW); - - /* Code brut */ - - bin_code = (char *)calloc(instr->length * 3, sizeof(char)); - - for (i = 0; i < instr->length; i++) - { - if ((i + 1) < instr->length) - snprintf(&bin_code[i * (2 + 1)], 4, "%02hhx ", content[instr->offset + i]); - else - snprintf(&bin_code[i * (2 + 1)], 3, "%02hhx", content[instr->offset + i]); - } + size_t i; /* Boucle de parcours */ - g_buffer_line_insert_text(line, BLC_BINARY, - bin_code, instr->length * 3 - 1, RTT_RAW_CODE); + line = g_code_buffer_append_new_line(buffer, &instr->address2); - free(bin_code); + g_buffer_line_fill_for_instr(line, msize/* TODO ! */, msize, content, instr->length, true); /* Instruction proprement dite */ - key = instr->get_text(instr, NULL/* FIXME */, 0/* FIXME */); + key = g_arch_instruction_get_keyword(instr, syntax); klen = strlen(key); g_buffer_line_insert_text(line, BLC_ASSEMBLY_HEAD, key, klen, RTT_INSTRUCTION); @@ -655,12 +688,12 @@ static void _g_arch_instruction_print(const GArchInstruction *instr, GCodeBuffer { g_arch_operand_print(instr->operands[0], line, syntax); - for (j = 1; j < instr->operands_count; j++) + for (i = 1; i < instr->operands_count; i++) { g_buffer_line_insert_text(line, BLC_ASSEMBLY, ",", 1, RTT_PUNCT); g_buffer_line_insert_text(line, BLC_ASSEMBLY, " ", 1, RTT_RAW); - g_arch_operand_print(instr->operands[j], line, syntax); + g_arch_operand_print(instr->operands[i], line, syntax); } @@ -685,11 +718,7 @@ static void _g_arch_instruction_print(const GArchInstruction *instr, GCodeBuffer void g_arch_instruction_print(const GArchInstruction *instr, GCodeBuffer *buffer, MemoryDataSize msize, const bin_t *content, AsmSyntax syntax) { - if (instr->print != NULL) - instr->print(instr, buffer, msize, content, syntax); - - else - _g_arch_instruction_print(instr, buffer, msize, content, syntax); + G_ARCH_INSTRUCTION_GET_CLASS(instr)->print(instr, buffer, msize, content, syntax); } diff --git a/src/arch/instruction.h b/src/arch/instruction.h index 06a29bf..a059161 100644 --- a/src/arch/instruction.h +++ b/src/arch/instruction.h @@ -30,6 +30,7 @@ #include "immediate.h" #include "register.h" +#include "vmpa.h" #include "../analysis/type.h" #include "../decomp/context.h" #include "../decomp/instruction.h" @@ -37,10 +38,12 @@ -#define G_TYPE_ARCH_INSTRUCTION g_arch_instruction_get_type() -#define G_ARCH_INSTRUCTION(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_arch_instruction_get_type(), GArchInstruction)) -#define G_IS_ARCH_INSTRUCTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_arch_instruction_get_type())) -#define G_ARCH_INSTRUCTION_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE((inst), g_arch_instruction_get_type(), GArchInstructionIface)) +#define G_TYPE_ARCH_INSTRUCTION g_arch_instruction_get_type() +#define G_ARCH_INSTRUCTION(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_arch_instruction_get_type(), GArchInstruction)) +#define G_IS_ARCH_INSTRUCTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_arch_instruction_get_type())) +#define G_ARCH_INSTRUCTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_ARCH_INSTRUCTION, GArchInstructionClass)) +#define G_IS_ARCH_INSTRUCTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_ARCH_INSTRUCTION)) +#define G_ARCH_INSTRUCTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_ARCH_INSTRUCTION, GArchInstructionClass)) /* Définition générique d'une instruction d'architecture (instance) */ @@ -54,7 +57,7 @@ typedef struct _GArchInstructionClass GArchInstructionClass; GType g_arch_instruction_get_type(void); /* Définit la localisation d'une instruction. */ -void g_arch_instruction_set_location(GArchInstruction *, off_t, off_t, vmpa_t); +void g_arch_instruction_set_location(GArchInstruction *, const vmpa2t *, off_t); /* Fournit la localisation d'une instruction. */ void g_arch_instruction_get_location(const GArchInstruction *, off_t *, off_t *, vmpa_t *); @@ -139,7 +142,7 @@ size_t g_arch_instruction_compute_group_index(GArchInstruction **, GArchInstruct /* Fournit le nom humain de l'instruction manipulée. */ -const char *g_arch_instruction_get_keyword(const GArchInstruction *); +const char *g_arch_instruction_get_keyword(const GArchInstruction *, AsmSyntax); /* Ajoute à un tampon GLib le contenu de l'instance spécifiée. */ void g_arch_instruction_print(const GArchInstruction *, GCodeBuffer *, MemoryDataSize, const bin_t *, AsmSyntax); diff --git a/src/arch/jvm/instruction.c b/src/arch/jvm/instruction.c index bfb6fc1..c2daaf5 100644 --- a/src/arch/jvm/instruction.c +++ b/src/arch/jvm/instruction.c @@ -199,7 +199,7 @@ static void g_jvm_instruction_init(GJvmInstruction *instr) parent = G_ARCH_INSTRUCTION(instr); - parent->get_text = (get_instruction_text_fc)jvm_get_instruction_text; + //parent->get_text = (get_instruction_text_fc)jvm_get_instruction_text; } diff --git a/src/arch/mips/instruction.c b/src/arch/mips/instruction.c index b3ef65d..93c32e7 100644 --- a/src/arch/mips/instruction.c +++ b/src/arch/mips/instruction.c @@ -177,7 +177,7 @@ static void g_mips_instruction_init(GMipsInstruction *instr) parent = G_ARCH_INSTRUCTION(instr); - parent->get_text = (get_instruction_text_fc)mips_get_instruction_text; + //parent->get_text = (get_instruction_text_fc)mips_get_instruction_text; } diff --git a/src/arch/processor.c b/src/arch/processor.c index 8ca58a7..48d0924 100644 --- a/src/arch/processor.c +++ b/src/arch/processor.c @@ -259,7 +259,7 @@ GArchInstruction *g_arch_processor_decode_instruction(const GArchProcessor *proc skipped = (result == SKIPPED_INSTR); *pos = old_pos; - result = g_db_instruction_new_from_data(data, pos, end, addr, proc); + result = NULL;// changed !!! g_db_instruction_new_from_data(data, pos, end, addr, proc); #ifdef DEBUG /* FIXME */ if (skipped) @@ -267,7 +267,7 @@ GArchInstruction *g_arch_processor_decode_instruction(const GArchProcessor *proc #endif } - g_arch_instruction_set_location(result, old_pos, *pos - old_pos, addr); + //g_arch_instruction_set_location(result, old_pos, *pos - old_pos, addr); return result; diff --git a/src/arch/vmpa.c b/src/arch/vmpa.c index c6972af..4ee0b99 100644 --- a/src/arch/vmpa.c +++ b/src/arch/vmpa.c @@ -26,6 +26,7 @@ #include <inttypes.h> #include <malloc.h> +#include <string.h> #include "../common/io.h" @@ -35,6 +36,76 @@ + +#if 0 +/****************************************************************************** +* * +* Paramètres : src = définition à copier. * +* * +* Description : Crée la copie d'un adressage mémoire en local. * +* * +* Retour : Adressage alloué sur la pile. * +* * +* Remarques : - * +* * +******************************************************************************/ + +inline vmpa2t *local_dup_vmpa(const vmpa2t *src) +{ + vmpa2t *result; /* Adressage à retourner */ + + result = alloca(sizeof(vmpa2t)); + + copy_vmpa(result, src); + + return result; + +} +#endif + + +/****************************************************************************** +* * +* Paramètres : dest = structure de destination pour la copie. * +* src = structure de source pour la copie. * +* * +* Description : Copie la définition d'un adressage dans un autre. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void copy_vmpa(vmpa2t *dest, const vmpa2t *src) +{ + dest->physical = src->physical; + dest->virtual= src->virtual; + + dest->last_phys_size = src->last_phys_size; + dest->last_virt_size = src->last_virt_size; + + strncpy(dest->phys_cache, src->phys_cache, VMPA_MAX_SIZE); + dest->phys_cache[VMPA_MAX_SIZE - 1] = '\0'; + + strncpy(dest->virt_cache, src->virt_cache, VMPA_MAX_SIZE); + dest->virt_cache[VMPA_MAX_SIZE - 1] = '\0'; + +} + + + + + + + + + + + + + + /****************************************************************************** * * * Paramètres : phy = position dans la mémoire physique. * @@ -164,6 +235,7 @@ bool send_vmpa(const vmpa2t *addr, int fd, int flags) * * * Paramètres : addr = adresse virtuelle ou physique à traiter. * * msize = taille de cette adresse, réelle ou désirée. * +* length = transmission de la taille du résultat ou NULL. [OUT]* * * * Description : Transforme une adresse physique en chaîne de caractères. * * * @@ -173,39 +245,45 @@ bool send_vmpa(const vmpa2t *addr, int fd, int flags) * * ******************************************************************************/ -const char *vmpa2_phy_to_string(vmpa2t *addr, MemoryDataSize msize) +const char *vmpa2_phys_to_string(vmpa2t *addr, MemoryDataSize msize, size_t *length) { - if (addr->phy_cache[0] == '\0' || addr->last_phy_size != msize) + size_t ret; /* Retour de l'impression */ + + if (addr->phys_cache[0] == '\0' || addr->last_phys_size != msize) { switch (msize) { case MDS_8_BITS: - snprintf(addr->phy_cache, VMPA_MAX_SIZE,"0x%02" PRIx64, addr->physical); + ret = snprintf(addr->phys_cache, VMPA_MAX_SIZE,"0x%02" PRIx64, addr->physical); break; case MDS_16_BITS: - snprintf(addr->phy_cache, VMPA_MAX_SIZE, "0x%04" PRIx64, addr->physical); + ret = snprintf(addr->phys_cache, VMPA_MAX_SIZE, "0x%04" PRIx64, addr->physical); break; case MDS_32_BITS: - snprintf(addr->phy_cache, VMPA_MAX_SIZE, "0x%08" PRIx64, addr->physical); + ret = snprintf(addr->phys_cache, VMPA_MAX_SIZE, "0x%08" PRIx64, addr->physical); break; case MDS_64_BITS: - snprintf(addr->phy_cache, VMPA_MAX_SIZE, "0x%016" PRIx64, addr->physical); + ret = snprintf(addr->phys_cache, VMPA_MAX_SIZE, "0x%016" PRIx64, addr->physical); break; default: - snprintf(addr->phy_cache, VMPA_MAX_SIZE, "???"); + ret = snprintf(addr->phys_cache, VMPA_MAX_SIZE, "???"); break; } - addr->last_phy_size = msize; + addr->last_phys_size = msize; + addr->last_phys_len = ret; } - return addr->phy_cache; + if (length != NULL) + *length = addr->last_phys_size; + + return addr->phys_cache; } @@ -214,6 +292,7 @@ const char *vmpa2_phy_to_string(vmpa2t *addr, MemoryDataSize msize) * * * Paramètres : addr = adresse virtuelle ou physique à traiter. * * msize = taille de cette adresse, réelle ou désirée. * +* length = transmission de la taille du résultat ou NULL. [OUT]* * * * Description : Transforme une adresse virtuelle en chaîne de caractères. * * * @@ -223,38 +302,44 @@ const char *vmpa2_phy_to_string(vmpa2t *addr, MemoryDataSize msize) * * ******************************************************************************/ -const char *vmpa2_virt_to_string(vmpa2t *addr, MemoryDataSize msize) +const char *vmpa2_virt_to_string(vmpa2t *addr, MemoryDataSize msize, size_t *length) { + size_t ret; /* Retour de l'impression */ + if (addr->virt_cache[0] == '\0' || addr->last_virt_size != msize) { switch (msize) { case MDS_8_BITS: - snprintf(addr->virt_cache, VMPA_MAX_SIZE,"0x%02" PRIx64, addr->virtual); + ret = snprintf(addr->virt_cache, VMPA_MAX_SIZE,"0x%02" PRIx64, addr->virtual); break; case MDS_16_BITS: - snprintf(addr->virt_cache, VMPA_MAX_SIZE, "0x%04" PRIx64, addr->virtual); + ret = snprintf(addr->virt_cache, VMPA_MAX_SIZE, "0x%04" PRIx64, addr->virtual); break; case MDS_32_BITS: - snprintf(addr->virt_cache, VMPA_MAX_SIZE, "0x%08" PRIx64, addr->virtual); + ret = snprintf(addr->virt_cache, VMPA_MAX_SIZE, "0x%08" PRIx64, addr->virtual); break; case MDS_64_BITS: - snprintf(addr->virt_cache, VMPA_MAX_SIZE, "0x%016" PRIx64, addr->virtual); + ret = snprintf(addr->virt_cache, VMPA_MAX_SIZE, "0x%016" PRIx64, addr->virtual); break; default: - snprintf(addr->virt_cache, VMPA_MAX_SIZE, "???"); + ret = snprintf(addr->virt_cache, VMPA_MAX_SIZE, "???"); break; } addr->last_virt_size = msize; + addr->last_virt_len = ret; } + if (length != NULL) + *length = addr->last_virt_size; + return addr->virt_cache; } diff --git a/src/arch/vmpa.h b/src/arch/vmpa.h index 5df9b8a..461780c 100644 --- a/src/arch/vmpa.h +++ b/src/arch/vmpa.h @@ -25,6 +25,7 @@ #define _ARCH_VMPA_H +#include <alloca.h> #include <limits.h> #include <stdbool.h> #include <stdint.h> @@ -50,9 +51,11 @@ struct _vmpa2_t off_t physical; /* Position physique */ uint64_t virtual; /* Adresse virtuelle */ - MemoryDataSize last_phy_size; /* Dernière taille demandée #1 */ + MemoryDataSize last_phys_size; /* Dernière taille demandée #1 */ MemoryDataSize last_virt_size; /* Dernière taille demandée #2 */ - char phy_cache[VMPA_MAX_SIZE]; /* Impression physique cachée */ + size_t last_phys_len; /* Dernière taille fournie #1 */ + size_t last_virt_len; /* Dernière taille fournie #2 */ + char phys_cache[VMPA_MAX_SIZE]; /* Impression physique cachée */ char virt_cache[VMPA_MAX_SIZE]; /* Impression virtuelle cachée */ }; @@ -66,6 +69,30 @@ typedef struct _vmpa2_t vmpa2_t; typedef struct _vmpa2_t vmpa2t; + + +/* Crée la copie d'un adressage mémoire en local. */ +//inline vmpa2t *local_dup_vmpa(const vmpa2t *) __attribute__((always_inline)); + + + +#define local_dup_vmpa(src) \ + ({ \ + vmpa2t *__result; \ + __result = alloca(sizeof(vmpa2t)); \ + copy_vmpa(__result, src); \ + __result; \ + }) + + + +/* Copie la définition d'un adressage dans un autre. */ +void copy_vmpa(vmpa2t *, const vmpa2t *); + + + + + /* Initialise une localisation dans l'espace mémoire/physique. */ void init_vmpa(vmpa2t *, off_t, uint64_t); @@ -81,6 +108,11 @@ vmpa2t *make_vmpa(off_t, uint64_t); +#define get_phy_addr(a) a->physical +#define get_virt_addr(a) a->virtual + + + /* Lit la définition d'une adresse depuis un flux réseau. */ bool recv_vmpa(vmpa2t *, int, int); @@ -89,10 +121,10 @@ bool recv_vmpa(vmpa2t *, int, int); bool send_vmpa(const vmpa2t *, int, int); /* Transforme une adresse physique en chaîne de caractères. */ -const char *vmpa2_phy_to_string(vmpa2t *, MemoryDataSize); +const char *vmpa2_phys_to_string(vmpa2t *, MemoryDataSize, size_t *); /* Transforme une adresse virtuelle en chaîne de caractères. */ -const char *vmpa2_virt_to_string(vmpa2t *, MemoryDataSize); +const char *vmpa2_virt_to_string(vmpa2t *, MemoryDataSize, size_t *); diff --git a/src/arch/x86/instruction.c b/src/arch/x86/instruction.c index 789aab2..0450d96 100644 --- a/src/arch/x86/instruction.c +++ b/src/arch/x86/instruction.c @@ -494,7 +494,7 @@ static void g_x86_instruction_init(GX86Instruction *instr) parent = G_ARCH_INSTRUCTION(instr); - parent->get_text = (get_instruction_text_fc)x86_get_instruction_text; + //parent->get_text = (get_instruction_text_fc)x86_get_instruction_text; parent->get_link = (get_instruction_link_fc)x86_get_instruction_link; parent->is_return = (is_instruction_return_fc)x86_instruction_is_return; diff --git a/src/dialogs/export.c b/src/dialogs/export.c index 25d62a7..2f572a5 100644 --- a/src/dialogs/export.c +++ b/src/dialogs/export.c @@ -243,7 +243,7 @@ static bool export_buffer_line(GCodeBuffer *buffer, GBufferLine *line, struct _e else g_buffer_line_export(line, export->fd, export->type, - export->addr, export->code, export->content); + true/* FIX%E */, export->addr, export->code, export->content); return true; diff --git a/src/glibext/gbufferline.c b/src/glibext/gbufferline.c index 63804a5..201c64b 100644 --- a/src/glibext/gbufferline.c +++ b/src/glibext/gbufferline.c @@ -80,7 +80,7 @@ struct _GBufferLine { GObject parent; /* A laisser en premier */ - vmpa_t addr; /* Adresse geographique */ + const vmpa2t *addr; /* Emplacement geographique */ BufferLineColumn main_column; /* Colonne principale */ buffer_line_column columns[BLC_COUNT]; /* Répartition du texte */ @@ -343,7 +343,7 @@ static void g_buffer_line_init(GBufferLine *line) { BufferLineColumn i; /* Boucle de parcours */ - for (i = BLC_ADDRESS; i < BLC_COUNT; i++) + for (i = 0; i < BLC_COUNT; i++) reset_column(&line->columns[i]); line->merge_start = BLC_COUNT; @@ -354,7 +354,7 @@ static void g_buffer_line_init(GBufferLine *line) /****************************************************************************** * * -* Paramètres : addr = adresse où va se situer la ligne. * +* Paramètres : addr = emplacement où va se situer la ligne. * * main = colonne à référencer comme étant la principale. * * * * Description : Crée une nouvelle représentation de fragments de texte. * @@ -365,7 +365,7 @@ static void g_buffer_line_init(GBufferLine *line) * * ******************************************************************************/ -GBufferLine *g_buffer_line_new(vmpa_t addr, BufferLineColumn main) +GBufferLine *g_buffer_line_new(const vmpa2t *addr, BufferLineColumn main) { GBufferLine *result; /* Composant à retourner */ @@ -393,7 +393,66 @@ GBufferLine *g_buffer_line_new(vmpa_t addr, BufferLineColumn main) vmpa_t g_buffer_line_get_address(const GBufferLine *line) { - return line->addr; + return 0/* FIXME line->addr*/; + +} + + +/****************************************************************************** +* * +* Paramètres : line = ligne à venir compléter. * +* psize = taille souhaitée de l'impression des positions. * +* vsize = taille souhaitée de l'impression des adresses. * +* content = contenu binaire global. * +* length = taille de l'extrait de code à afficher. * +* full = la portion est assez courte pour être entière ? * +* * +* Description : Construit le tronc commun d'une ligne d'instruction. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_buffer_line_fill_for_instr(GBufferLine *line, MemoryDataSize psize, MemoryDataSize vsize, const bin_t *content, off_t length, bool full) +{ + size_t len; /* Taille de l'élément inséré */ + char *address; /* Adresse au format texte */ + char *bin_code; /* Tampon du code binaire */ + off_t start; /* Début de traitement */ + off_t end; /* Limite de traitement */ + off_t i; /* Boucle de parcours #1 */ + char *iter; /* Boucle de parcours #2 */ + int ret; /* Progression dans l'écriture */ + + /* Adresse physique puis virtuelle */ + + address = vmpa2_phys_to_string(line->addr, psize, &len); + g_buffer_line_insert_text(line, BLC_PHYSICAL, address, len, RTT_RAW); + + address = vmpa2_virt_to_string(line->addr, vsize, &len); + g_buffer_line_insert_text(line, BLC_VIRTUAL, address, len, RTT_RAW); + + /* Code brut */ + + bin_code = (char *)calloc(length * 3 + 3, sizeof(char)); + + start = get_phy_addr(line->addr); + end = start + length; + + for (i = start, iter = bin_code; i < end; i++, iter += ret) + { + if ((i + 1) < end) + ret = snprintf(iter, 4, "%02hhx ", content[i]); + else + ret = snprintf(iter, 6, "%02hhx%s", content[i], full ? "" : "..."); + + } + + g_buffer_line_insert_text(line, BLC_BINARY, bin_code, iter - bin_code, RTT_RAW_CODE); + + free(bin_code); } @@ -441,7 +500,7 @@ GBufferSegment *g_buffer_line_get_segment_at(const GBufferLine *line, const gint result = NULL; - for (i = BLC_ADDRESS; i < BLC_COUNT; i++) + for (i = 0; i < BLC_COUNT; i++) { /* FIXME : addr/code */ @@ -470,7 +529,8 @@ GBufferSegment *g_buffer_line_get_segment_at(const GBufferLine *line, const gint * caret = position du curseur à faire évoluer. * * ctrl = indique la demande d'un parcours rapide. * * dir = direction du parcours. * -* addr = indique si les positions doivent être affichées. * +* phys = indique si les positions doivent être affichées. * +* virt = indique si les adresses doivent être affichées. * * code = indique si le code binaire doit être affiché. * * * * Description : Déplace le curseur au sein d'une vue de tampon. * @@ -481,9 +541,11 @@ GBufferSegment *g_buffer_line_get_segment_at(const GBufferLine *line, const gint * * ******************************************************************************/ -bool g_buffer_line_move_caret(const GBufferLine *line, GdkRectangle *caret, bool ctrl, GdkScrollDirection dir, bool addr, bool code) +bool g_buffer_line_move_caret(const GBufferLine *line, GdkRectangle *caret, bool ctrl, GdkScrollDirection dir, bool phys, bool virt, bool code) { + /* TODO : utiliser les arguments booléens */ + caret->x += (dir == GDK_SCROLL_RIGHT ? 10 : -10); return true; @@ -512,7 +574,7 @@ GSList *g_buffer_line_highlight_all_same_segments(const GBufferLine *line, GSLis { BufferLineColumn i; /* Boucle de parcours */ - for (i = BLC_ADDRESS; i < BLC_COUNT; i++) + for (i = 0; i < BLC_COUNT; i++) list = highlight_all_same_segments(&line->columns[i], list, ref); return list; @@ -621,7 +683,8 @@ gint g_buffer_line_get_column_width(GBufferLine *line, BufferLineColumn index) * * * Paramètres : line = ligne à venir compléter. * * merge = précise la première colonne marquant la fusion. [OUT]* -* addr = indique si les positions doivent être affichées. * +* phys = indique si les positions doivent être affichées. * +* virt = indique si les adresses doivent être affichées. * * code = indique si le code binaire doit être affiché. * * * * Description : Fournit la dernière largeur d'une ligne avec fusion. * @@ -632,12 +695,14 @@ gint g_buffer_line_get_column_width(GBufferLine *line, BufferLineColumn index) * * ******************************************************************************/ -gint g_buffer_line_get_merge_width(GBufferLine *line, BufferLineColumn *merge, bool addr, bool code) +gint g_buffer_line_get_merge_width(GBufferLine *line, BufferLineColumn *merge, bool phys, bool virt, bool code) { gint result; /* Largeur à retourner */ result = 0; + /* TODO : wtf ?! quelle est l'utilité des arguments booléens ? */ + *merge = line->merge_start; if (line->merge_start < BLC_COUNT) @@ -678,7 +743,8 @@ void g_buffer_line_start_merge_at(GBufferLine *line, BufferLineColumn start) * max_widths = largeurs de colonne à respecter. * * x_init = abscisse du point d'impression de départ. * * y = ordonnée du point d'impression. * -* addr = indique si les positions doivent être affichées.* +* phys = indique si les positions doivent être affichées.* +* virt = indique si les adresses doivent être affichées. * * code = indique si le code binaire doit être affiché. * * * * Description : Imprime la ligne de texte représentée. * @@ -689,7 +755,7 @@ void g_buffer_line_start_merge_at(GBufferLine *line, BufferLineColumn start) * * ******************************************************************************/ -void g_buffer_line_draw(GBufferLine *line, cairo_t *cairo, const gint max_widths[BLC_COUNT], gint x_init, gint y, bool addr, bool code) +void g_buffer_line_draw(GBufferLine *line, cairo_t *cairo, const gint max_widths[BLC_COUNT], gint x_init, gint y, bool phys, bool virt, bool code) { GBufferLineClass *class; /* Stockage de briques de base */ gint x; /* Point de départ d'impression*/ @@ -702,9 +768,10 @@ void g_buffer_line_draw(GBufferLine *line, cairo_t *cairo, const gint max_widths x = x_init; - for (i = BLC_ADDRESS; i < BLC_COUNT; i++) + for (i = 0; i < BLC_COUNT; i++) { - if (i == BLC_ADDRESS && !addr) continue; + if (i == BLC_PHYSICAL && !phys) continue; + if (i == BLC_VIRTUAL && !virt) continue; if (i == BLC_BINARY && !code) continue; draw_segments_of_column(&line->columns[i], cairo, x, y); @@ -723,7 +790,8 @@ void g_buffer_line_draw(GBufferLine *line, cairo_t *cairo, const gint max_widths * Paramètres : line = ligne de texte à manipuler. * * fd = flux ouvert en écriture. * * type = type d'exportation attendue. * -* addr = indique si les positions doivent être affichées. * +* phys = indique si les positions doivent être affichées. * +* virt = indique si les adresses doivent être affichées. * * code = indique si le code binaire doit être affiché. * * content = indique si le gros du contenu doit être affiché. * * * @@ -735,15 +803,16 @@ void g_buffer_line_draw(GBufferLine *line, cairo_t *cairo, const gint max_widths * * ******************************************************************************/ -void g_buffer_line_export(GBufferLine *line, int fd, BufferExportType type, bool addr, bool code, bool content) +void g_buffer_line_export(GBufferLine *line, int fd, BufferExportType type, bool phys, bool virt, bool code, bool content) { BufferLineColumn i; /* Boucle de parcours */ - for (i = BLC_ADDRESS; i < BLC_COUNT; i++) + for (i = 0; i < BLC_COUNT; i++) { - if (i == BLC_ADDRESS && !addr) continue; + if (i == BLC_PHYSICAL && !phys) continue; + if (i == BLC_VIRTUAL && !virt) continue; if (i == BLC_BINARY && !code) continue; - if (!(i == BLC_ADDRESS || i == BLC_BINARY) && !content) continue; + if (!(i == BLC_PHYSICAL || i == BLC_VIRTUAL || i == BLC_BINARY) && !content) continue; dprintf(fd, "TODO\n"); diff --git a/src/glibext/gbufferline.h b/src/glibext/gbufferline.h index 7d48cf3..fa64fe1 100644 --- a/src/glibext/gbufferline.h +++ b/src/glibext/gbufferline.h @@ -31,6 +31,7 @@ #include "gbuffersegment.h" #include "../arch/archbase.h" +#include "../arch/vmpa.h" @@ -53,7 +54,8 @@ typedef struct _GBufferLineClass GBufferLineClass; /* Désignation des colonnes d'une ligne */ typedef enum _BufferLineColumn { - BLC_ADDRESS, /* Adresse virtuelle */ + BLC_PHYSICAL, /* Position physique */ + BLC_VIRTUAL, /* Adresse virtuelle */ BLC_BINARY, /* Contenu sous forme binaire */ BLC_ASSEMBLY_HEAD, /* Instruction pour assembleur */ BLC_ASSEMBLY, /* Code pour assembleur */ @@ -81,16 +83,19 @@ typedef enum _BufferLineColumn GType g_buffer_line_get_type(void); /* Crée une nouvelle représentation de fragments de texte. */ -GBufferLine *g_buffer_line_new(vmpa_t, BufferLineColumn); +GBufferLine *g_buffer_line_new(const vmpa2t *, BufferLineColumn); /* Indique l'adresse à laquelle se situe la ligne. */ vmpa_t g_buffer_line_get_address(const GBufferLine *); +/* Construit le tronc commun d'une ligne d'instruction. */ +void g_buffer_line_fill_for_instr(GBufferLine *, MemoryDataSize, MemoryDataSize, const bin_t *, off_t, bool); + /* Ajoute un fragment de texte à une colonne de ligne. */ void g_buffer_line_add_segment(GBufferLine *, BufferLineColumn, GBufferSegment *) __attribute__ ((deprecated)); /* Déplace le curseur au sein d'une vue de tampon. */ -bool g_buffer_line_move_caret(const GBufferLine *, GdkRectangle *, bool, GdkScrollDirection, bool, bool); +bool g_buffer_line_move_caret(const GBufferLine *, GdkRectangle *, bool, GdkScrollDirection, bool, bool, bool); /* Donne le segment présent à une abscisse donnée. */ GBufferSegment *g_buffer_line_get_segment_at(const GBufferLine *, const gint [BLC_COUNT], gint *, bool); @@ -108,16 +113,16 @@ char *g_buffer_line_get_text(const GBufferLine *); gint g_buffer_line_get_column_width(GBufferLine *, BufferLineColumn); /* Fournit la dernière largeur d'une ligne avec fusion. */ -gint g_buffer_line_get_merge_width(GBufferLine *, BufferLineColumn *, bool, bool); +gint g_buffer_line_get_merge_width(GBufferLine *, BufferLineColumn *, bool, bool, bool); /* Définit la colonne à partir de laquelle la fusion opère. */ void g_buffer_line_start_merge_at(GBufferLine *, BufferLineColumn); /* Imprime la ligne de texte représentée. */ -void g_buffer_line_draw(GBufferLine *, cairo_t *, const gint [BLC_COUNT], gint, gint, bool, bool); +void g_buffer_line_draw(GBufferLine *, cairo_t *, const gint [BLC_COUNT], gint, gint, bool, bool, bool); /* Exporte la ligne de texte représentée. */ -void g_buffer_line_export(GBufferLine *, int, BufferExportType, bool, bool, bool); +void g_buffer_line_export(GBufferLine *, int, BufferExportType, bool, bool, bool, bool); diff --git a/src/glibext/gcodebuffer.c b/src/glibext/gcodebuffer.c index 5be632c..708a089 100644 --- a/src/glibext/gcodebuffer.c +++ b/src/glibext/gcodebuffer.c @@ -182,7 +182,7 @@ static void g_buffer_view_reset_required_height(GBufferView *); static void g_buffer_view_reset_required_widths(GBufferView *); /* Calcule les largeurs requises par une visualisation. */ -static void g_buffer_view_compute_required_widths(GBufferView *, bool, bool); +static void g_buffer_view_compute_required_widths(GBufferView *, bool, bool, bool); @@ -466,7 +466,7 @@ static size_t g_code_buffer_get_index_from_address(GCodeBuffer *buffer, vmpa_t a /****************************************************************************** * * * Paramètres : buffer = composant GTK à mettre à jour. * -* addr = adresse où va se situer la ligne. * +* addr = emplacement où va se situer la ligne. * * * * Description : Ajoute une nouvelle ligne à un tampon pour code désassemblé. * * * @@ -476,7 +476,7 @@ static size_t g_code_buffer_get_index_from_address(GCodeBuffer *buffer, vmpa_t a * * ******************************************************************************/ -GBufferLine *g_code_buffer_append_new_line(GCodeBuffer *buffer, vmpa_t addr) +GBufferLine *g_code_buffer_append_new_line(GCodeBuffer *buffer, const vmpa2t *addr) { GBufferLine *result; /* Instance à retourner */ size_t i; /* Boucle de parcours */ @@ -886,7 +886,8 @@ static void g_buffer_view_compute_required_height(GBufferView *view) /****************************************************************************** * * * Paramètres : view = visualisation à mettre à jour. * -* addr = indique si les positions doivent être affichées. * +* phys = indique si les positions doivent être affichées. * +* virt = indique si les adresses doivent être affichées. * * code = indique si le code binaire doit être affiché. * * * * Description : Calcule les largeurs requises par une visualisation. * @@ -897,7 +898,7 @@ static void g_buffer_view_compute_required_height(GBufferView *view) * * ******************************************************************************/ -static void g_buffer_view_compute_required_widths(GBufferView *view, bool addr, bool code) +static void g_buffer_view_compute_required_widths(GBufferView *view, bool phys, bool virt, bool code) { GBufferLine **lines; /* Liste des lignes à traiter */ size_t first; /* Première ligne intégrée */ @@ -930,7 +931,7 @@ static void g_buffer_view_compute_required_widths(GBufferView *view, bool addr, view->max_widths[j] = MAX(view->max_widths[j], width); } - width = g_buffer_line_get_merge_width(lines[i], &merge, addr, code); + width = g_buffer_line_get_merge_width(lines[i], &merge, phys, virt, code); view->last_width = MAX(view->last_width, width); if (merge != BLC_COUNT) { @@ -973,7 +974,8 @@ gint g_buffer_view_get_line_height(GBufferView *view) /****************************************************************************** * * * Paramètres : view = visualisation à consulter. * -* addr = indique si les positions doivent être affichées. * +* phys = indique si les positions doivent être affichées. * +* virt = indique si les adresses doivent être affichées. * * code = indique si le code binaire doit être affiché. * * * * Description : Fournit la largeur requise par une visualisation. * @@ -984,7 +986,7 @@ gint g_buffer_view_get_line_height(GBufferView *view) * * ******************************************************************************/ -gint g_buffer_view_get_width(GBufferView *view, bool addr, bool code) +gint g_buffer_view_get_width(GBufferView *view, bool phys, bool virt, bool code) { gint result; /* Taille à retourner */ gint col_width; /* Calcul selon les colonnes */ @@ -992,7 +994,7 @@ gint g_buffer_view_get_width(GBufferView *view, bool addr, bool code) BufferLineColumn i; /* Boucle de parcours */ if (!WIDTHS_CACHED(view)) - g_buffer_view_compute_required_widths(view, addr, code); + g_buffer_view_compute_required_widths(view, phys, virt, code); result = view->left_text; @@ -1003,7 +1005,8 @@ gint g_buffer_view_get_width(GBufferView *view, bool addr, bool code) for (i = 0; i < BLC_COUNT; i++) { - if (i == BLC_ADDRESS && !addr) continue; + if (i == BLC_PHYSICAL && !phys) continue; + if (i == BLC_VIRTUAL && !virt) continue; if (i == BLC_BINARY && !code) continue; col_width += view->max_widths[i]; @@ -1017,7 +1020,8 @@ gint g_buffer_view_get_width(GBufferView *view, bool addr, bool code) for (i = 0; i < view->last_merge; i++) { - if (i == BLC_ADDRESS && !addr) continue; + if (i == BLC_PHYSICAL && !phys) continue; + if (i == BLC_VIRTUAL && !virt) continue; if (i == BLC_BINARY && !code) continue; full_width += view->max_widths[i]; @@ -1118,7 +1122,8 @@ vmpa_t g_buffer_view_compute_caret(GBufferView *view, GBufferLine *line, size_t * caret = position du curseur à faire évoluer. * * ctrl = indique la demande d'un parcours rapide. * * dir = direction du parcours. * -* addr = indique si les positions doivent être affichées. * +* phys = indique si les positions doivent être affichées. * +* virt = indique si les adresses doivent être affichées. * * code = indique si le code binaire doit être affiché. * * * * Description : Déplace le curseur au sein d'une vue de tampon. * @@ -1129,7 +1134,7 @@ vmpa_t g_buffer_view_compute_caret(GBufferView *view, GBufferLine *line, size_t * * ******************************************************************************/ -vmpa_t g_buffer_view_move_caret(GBufferView *view, GdkRectangle *caret, bool ctrl, GdkScrollDirection dir, bool addr, bool code) +vmpa_t g_buffer_view_move_caret(GBufferView *view, GdkRectangle *caret, bool ctrl, GdkScrollDirection dir, bool phys, bool virt, bool code) { bool result; /* Actualisation à renvoyer */ bool computed; /* Récursivité pris en compte */ @@ -1153,7 +1158,8 @@ vmpa_t g_buffer_view_move_caret(GBufferView *view, GdkRectangle *caret, bool ctr case GDK_SCROLL_LEFT: case GDK_SCROLL_RIGHT: left_pos = view->left_text; - if (addr) left_pos += view->max_widths[BLC_ADDRESS] + COL_MARGIN; + if (phys) left_pos += view->max_widths[BLC_PHYSICAL] + COL_MARGIN; + if (virt) left_pos += view->max_widths[BLC_VIRTUAL] + COL_MARGIN; if (code) left_pos += view->max_widths[BLC_BINARY] + COL_MARGIN; right_pos = left_pos; for (i = BLC_ASSEMBLY_HEAD; i < BLC_COUNT; i++) @@ -1184,13 +1190,13 @@ vmpa_t g_buffer_view_move_caret(GBufferView *view, GdkRectangle *caret, bool ctr line = g_buffer_view_find_line_at(view, caret->y, NULL); if (line == NULL) break; - result = g_buffer_line_move_caret(line, caret, ctrl, GDK_SCROLL_LEFT, addr, code); + result = g_buffer_line_move_caret(line, caret, ctrl, GDK_SCROLL_LEFT, phys, virt, code); if (caret->x < left_pos) { caret->x = right_pos; - result = g_buffer_view_move_caret(view, caret, ctrl, GDK_SCROLL_UP, addr, code); + result = g_buffer_view_move_caret(view, caret, ctrl, GDK_SCROLL_UP, phys, virt, code); if (result == VMPA_INVALID) caret->x = left_pos; @@ -1205,13 +1211,13 @@ vmpa_t g_buffer_view_move_caret(GBufferView *view, GdkRectangle *caret, bool ctr line = g_buffer_view_find_line_at(view, caret->y, NULL); if (line == NULL) break; - result = g_buffer_line_move_caret(line, caret, ctrl, GDK_SCROLL_RIGHT, addr, code); + result = g_buffer_line_move_caret(line, caret, ctrl, GDK_SCROLL_RIGHT, phys, virt, code); if (!result) { caret->x = left_pos; - result = g_buffer_view_move_caret(view, caret, ctrl, GDK_SCROLL_DOWN, addr, code); + result = g_buffer_view_move_caret(view, caret, ctrl, GDK_SCROLL_DOWN, phys, virt, code); if (result == VMPA_INVALID) caret->x = right_pos; @@ -1347,7 +1353,8 @@ void g_buffer_view_highlight_segments(GBufferView *view, gint x, gint y) * fake_x = abscisse réelle du point 0 à l'écran. * * fake_y = ordonnée réelle du point 0 à l'écran. * * area = position et surface à traiter. * -* addr = indique si les positions doivent être affichées. * +* phys = indique si les positions doivent être affichées. * +* virt = indique si les adresses doivent être affichées. * * code = indique si le code binaire doit être affiché. * * * * Description : Imprime la visualisation du tampon de code désassemblé. * @@ -1358,7 +1365,7 @@ void g_buffer_view_highlight_segments(GBufferView *view, gint x, gint y) * * ******************************************************************************/ -void g_buffer_view_draw(const GBufferView *view, cairo_t *cr, gint fake_x, gint fake_y, const cairo_rectangle_int_t *area, bool addr, bool code) +void g_buffer_view_draw(const GBufferView *view, cairo_t *cr, gint fake_x, gint fake_y, const cairo_rectangle_int_t *area, bool phys, bool virt, bool code) { gint real_x; /* Abscisse réelle pour tampon */ gint real_y; /* Ordonnée réelle pour tampon */ @@ -1395,7 +1402,7 @@ void g_buffer_view_draw(const GBufferView *view, cairo_t *cr, gint fake_x, gint */ g_buffer_line_draw(lines[i], cr, - view->max_widths, real_x, y, addr, code); + view->max_widths, real_x, y, phys, virt, code); y += view->line_height; diff --git a/src/glibext/gcodebuffer.h b/src/glibext/gcodebuffer.h index 18d13f0..3167d41 100644 --- a/src/glibext/gcodebuffer.h +++ b/src/glibext/gcodebuffer.h @@ -60,7 +60,7 @@ GCodeBuffer *g_code_buffer_new(BufferLineColumn); #define g_code_buffer_append_new_line_fixme(b) g_code_buffer_append_new_line(b, 0ull) /* Ajoute une nouvelle ligne à un tampon pour code désassemblé. */ -GBufferLine *g_code_buffer_append_new_line(GCodeBuffer *, vmpa_t); +GBufferLine *g_code_buffer_append_new_line(GCodeBuffer *, const vmpa2t *); /* Ajoute une nouvelle ligne à un tampon pour code désassemblé. */ GBufferLine *g_code_buffer_insert_at(GCodeBuffer *, vmpa_t, bool); @@ -122,7 +122,7 @@ GCodeBuffer *g_buffer_view_get_buffer(const GBufferView *); gint g_buffer_view_get_line_height(GBufferView *); /* Fournit la largeur requise par une visualisation. */ -gint g_buffer_view_get_width(GBufferView *, bool, bool); +gint g_buffer_view_get_width(GBufferView *, bool, bool, bool); /* Fournit la hauteur requise par une visualisation. */ gint g_buffer_view_get_height(const GBufferView *); @@ -131,7 +131,7 @@ gint g_buffer_view_get_height(const GBufferView *); vmpa_t g_buffer_view_compute_caret(GBufferView *, GBufferLine *, size_t, gint, GdkRectangle *); /* Déplace le curseur au sein d'une vue de tampon. */ -vmpa_t g_buffer_view_move_caret(GBufferView *, GdkRectangle *, bool, GdkScrollDirection, bool, bool); +vmpa_t g_buffer_view_move_caret(GBufferView *, GdkRectangle *, bool, GdkScrollDirection, bool, bool, bool); /* Supprime toute mise en évidence de segments. */ bool g_buffer_view_unhighlight_segments(GBufferView *); @@ -140,7 +140,7 @@ bool g_buffer_view_unhighlight_segments(GBufferView *); void g_buffer_view_highlight_segments(GBufferView *, gint, gint); /* Imprime la visualisation du tampon de code désassemblé. */ -void g_buffer_view_draw(const GBufferView *, cairo_t *, gint, gint, const cairo_rectangle_int_t *, bool, bool); +void g_buffer_view_draw(const GBufferView *, cairo_t *, gint, gint, const cairo_rectangle_int_t *, bool, bool, bool); /* Fournit la ligne présente à une ordonnée donnée. */ GBufferLine *g_buffer_view_find_line_at(GBufferView *, gint, size_t *); diff --git a/src/glibext/signal.h b/src/glibext/signal.h index 8d139a7..c2a442d 100644 --- a/src/glibext/signal.h +++ b/src/glibext/signal.h @@ -26,6 +26,7 @@ #include <glib-object.h> +#include <gobject/gclosure.h> diff --git a/src/gtkext/gtkbufferview.c b/src/gtkext/gtkbufferview.c index 26f67c1..e58ae5c 100644 --- a/src/gtkext/gtkbufferview.c +++ b/src/gtkext/gtkbufferview.c @@ -372,6 +372,7 @@ static void gtk_buffer_view_get_preferred_width(GtkWidget *widget, gint *minimal if (view->buffer_view != NULL) *minimal = g_buffer_view_get_width(view->buffer_view, + *GTK_VIEW_PANEL(view)->display_phys, *GTK_VIEW_PANEL(view)->display_addr, *GTK_VIEW_PANEL(view)->display_code); else @@ -420,7 +421,7 @@ static void gtk_buffer_view_size_allocate(GtkWidget *widget, GtkAllocation *allo view = GTK_BUFFER_VIEW(widget); - width = g_buffer_view_get_width(view->buffer_view, *panel->display_addr, *panel->display_code); + width = g_buffer_view_get_width(view->buffer_view, *panel->display_phys, *panel->display_addr, *panel->display_code); height = g_buffer_view_get_height(view->buffer_view); gtk_view_panel_compute_allocation(panel, &valloc); @@ -516,7 +517,7 @@ static gboolean gtk_buffer_view_draw(GtkWidget *widget, cairo_t *cr) if (view->buffer_view != NULL) g_buffer_view_draw(view->buffer_view, cr, fake_x, fake_y, &area, - *pview->display_addr, *pview->display_code); + *pview->display_phys, *pview->display_addr, *pview->display_code); return TRUE; @@ -623,7 +624,8 @@ static void gtk_buffer_view_cache_glance(GtkBufferView *view, cairo_t *cairo, co * * * Paramètres : view = composant GTK à mettre à jour. * * buffer = tampon de lignes à encadrer. * -* addr = indique si les positions doivent être affichées. * +* phys = indique si les positions doivent être affichées. * +* virt = indique si les adresses doivent être affichées. * * code = indique si le code binaire doit être affiché. * * * * Description : Prend acte de l'association d'un tampon de lignes. * @@ -634,7 +636,7 @@ static void gtk_buffer_view_cache_glance(GtkBufferView *view, cairo_t *cairo, co * * ******************************************************************************/ -void gtk_buffer_view_attach_buffer(GtkBufferView *view, GBufferView *buffer, bool *addr, bool *code) +void gtk_buffer_view_attach_buffer(GtkBufferView *view, GBufferView *buffer, /*bool *phys, */bool *addr, bool *code) { gint width; /* Largeur de l'objet actuelle */ gint height; /* Hauteur de l'objet actuelle */ @@ -658,7 +660,7 @@ void gtk_buffer_view_attach_buffer(GtkBufferView *view, GBufferView *buffer, boo /* Validation finale */ - width = g_buffer_view_get_width(view->buffer_view, *addr, *code); + width = g_buffer_view_get_width(view->buffer_view, true/* FIXME : *phys*/, *addr, *code); height = g_buffer_view_get_height(view->buffer_view); width += -view->left_text + 1; diff --git a/src/gtkext/gtkviewpanel-int.h b/src/gtkext/gtkviewpanel-int.h index 63a6a5b..b3a6cf6 100644 --- a/src/gtkext/gtkviewpanel-int.h +++ b/src/gtkext/gtkviewpanel-int.h @@ -68,6 +68,7 @@ struct _GtkViewPanel get_addr_coordinates_fc get_coordinates;/* Conversion adresse <-> pos. */ cache_glance_fc cache_glance; /* Cache de la mignature */ + bool *display_phys; /* Affichage des adresses ? */ bool *display_addr; /* Affichage des adresses ? */ bool *display_code; /* Affichage du code binaire ? */ diff --git a/src/gtkext/gtkviewpanel.c b/src/gtkext/gtkviewpanel.c index 2b1aa97..739fde7 100644 --- a/src/gtkext/gtkviewpanel.c +++ b/src/gtkext/gtkviewpanel.c @@ -303,6 +303,7 @@ void gtk_view_panel_attach_binary(GtkViewPanel *panel, GLoadedBinary *binary, bo g_object_ref(G_OBJECT(binary)); panel->binary = binary; + panel->display_phys = addr; panel->display_addr = addr; panel->display_code = code; |