From ab1489b6a6ef1f09957f6f805f143fceb42f6a08 Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Thu, 11 Sep 2008 22:25:26 +0000 Subject: Provided capabilities to resolve symbols for given addresses. git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@29 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a --- ChangeLog | 22 ++++++++++++++++++++++ src/arch/processor-int.h | 3 ++- src/arch/processor.c | 5 +++-- src/arch/processor.h | 3 ++- src/arch/x86/processor.c | 34 ++++++++++++++++++++++++++------- src/binary.c | 1 + src/format/elf/e_elf.c | 46 +++++++++++++++++++++++++++++++++++++++++++++ src/format/elf/e_elf.h | 2 ++ src/format/exe_format-int.h | 3 +++ src/format/exe_format.c | 22 ++++++++++++++++++++++ src/format/exe_format.h | 2 ++ src/gtksnippet.c | 22 +++++++++++++++++++++- src/gtksnippet.h | 6 ++++-- 13 files changed, 157 insertions(+), 14 deletions(-) diff --git a/ChangeLog b/ChangeLog index af808be..4955b49 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,25 @@ +2008-09-12 Cyrille Bagard + + * src/arch/processor.c: + * src/arch/processor.h: + * src/arch/processor-int.h: + * src/arch/x86/processor.c: + Try to resolve symbols for some kind of addresses. + + * src/binary.c: + Store in the code snippet the used format. + + * src/format/elf/e_elf.c: + * src/format/elf/e_elf.h: + * src/format/exe_format.c: + * src/format/exe_format.h: + * src/format/exe_format-int.h: + Provide capabilities to resolve symbols for given addresses. + + * src/gtksnippet.c: + * src/gtksnippet.h: + Add a way to register the used format. + 2008-09-10 Cyrille Bagard * src/arch/operand-int.h: diff --git a/src/arch/processor-int.h b/src/arch/processor-int.h index 50837e1..5dc12ff 100644 --- a/src/arch/processor-int.h +++ b/src/arch/processor-int.h @@ -32,6 +32,7 @@ #include "operand.h" /* TODO: AsmSyntax ? */ #include "instruction.h" #include "processor.h" +#include "../format/exe_format.h" @@ -41,7 +42,7 @@ typedef asm_instr * (* fetch_instruction) (const asm_processor *, const uint8_t *, off_t *, off_t, uint64_t); /* Traduit une instruction en version humainement lisible. */ -typedef void (* print_instruction) (const asm_processor *, const asm_instr *, char *, size_t, AsmSyntax); +typedef void (* print_instruction) (const asm_processor *, const exe_format *, const asm_instr *, char *, size_t, AsmSyntax); diff --git a/src/arch/processor.c b/src/arch/processor.c index 31cfb3e..0afca2c 100644 --- a/src/arch/processor.c +++ b/src/arch/processor.c @@ -74,6 +74,7 @@ asm_instr *decode_instruction(const asm_processor *proc, const uint8_t *data, of /****************************************************************************** * * * Paramètres : proc = architecture visée par la procédure. * +* format = format du binaire manipulé. * * instr = instruction à traiter. * * buffer = tampon de sortie mis à disposition. [OUT] * * len = taille de ce tampon. * @@ -87,9 +88,9 @@ asm_instr *decode_instruction(const asm_processor *proc, const uint8_t *data, of * * ******************************************************************************/ -void print_hinstruction(const asm_processor *proc, const asm_instr *instr, char *buffer, size_t len, AsmSyntax syntax) +void print_hinstruction(const asm_processor *proc, const exe_format *format, const asm_instr *instr, char *buffer, size_t len, AsmSyntax syntax) { - proc->print_instr(proc, instr, buffer, len, syntax); + proc->print_instr(proc, format, instr, buffer, len, syntax); } diff --git a/src/arch/processor.h b/src/arch/processor.h index e147f38..287a761 100644 --- a/src/arch/processor.h +++ b/src/arch/processor.h @@ -30,6 +30,7 @@ #include "operand.h" /* AsmSyntax */ #include "instruction.h" +#include "../format/exe_format.h" @@ -42,7 +43,7 @@ typedef struct _asm_processor asm_processor; asm_instr *decode_instruction(const asm_processor *, const uint8_t *, off_t *, off_t, uint64_t); /* Traduit une instruction en version humainement lisible. */ -void print_hinstruction(const asm_processor *, const asm_instr *, char *, size_t, AsmSyntax); +void print_hinstruction(const asm_processor *, const exe_format *, const asm_instr *, char *, size_t, AsmSyntax); diff --git a/src/arch/x86/processor.c b/src/arch/x86/processor.c index 4326294..7243064 100644 --- a/src/arch/x86/processor.c +++ b/src/arch/x86/processor.c @@ -106,7 +106,7 @@ void x86_register_instructions(asm_x86_processor *); asm_instr *x86_fetch_instruction(const asm_x86_processor *, const uint8_t *, off_t *, off_t, uint64_t); /* Traduit une instruction en version humainement lisible. */ -void x86_print_instruction(const asm_x86_processor *, const asm_x86_instr *, char *, size_t, AsmSyntax); +void x86_print_instruction(const asm_x86_processor *, const exe_format *, const asm_x86_instr *, char *, size_t, AsmSyntax); @@ -356,6 +356,7 @@ asm_instr *x86_fetch_instruction(const asm_x86_processor *proc, const uint8_t *d /****************************************************************************** * * * Paramètres : proc = architecture visée par la procédure. * +* format = format du binaire manipulé. * * instr = instruction à traiter. * * buffer = tampon de sortie mis à disposition. [OUT] * * len = taille de ce tampon. * @@ -369,10 +370,14 @@ asm_instr *x86_fetch_instruction(const asm_x86_processor *proc, const uint8_t *d * * ******************************************************************************/ -void x86_print_instruction(const asm_x86_processor *proc, const asm_x86_instr *instr, char *buffer, size_t len, AsmSyntax syntax) +void x86_print_instruction(const asm_x86_processor *proc, const exe_format *format, const asm_x86_instr *instr, char *buffer, size_t len, AsmSyntax syntax) { size_t i; /* Boucle de parcours */ - char opbuffer[3][64]; /* Tampon pour les textes */ + char opbuffer[3][256]; /* Tampon pour les textes */ + char *label; /* Etiquette de symbole */ + SymbolType symtype; /* Type de symbole */ + uint64_t offset; /* Décallage final constaté */ + size_t oplen; /* Taille de description */ /* Impression des opérandes */ @@ -380,18 +385,33 @@ void x86_print_instruction(const asm_x86_processor *proc, const asm_x86_instr *i switch (ASM_OPERAND(ASM_INSTRUCTION(instr)->operands[i])->type) { case AOT_NONE: - print_db_operand(ASM_OPERAND(ASM_INSTRUCTION(instr)->operands[i]), opbuffer[i], 64, syntax); + print_db_operand(ASM_OPERAND(ASM_INSTRUCTION(instr)->operands[i]), opbuffer[i], 256, syntax); break; case AOT_IMM: - print_imm_operand(ASM_OPERAND(ASM_INSTRUCTION(instr)->operands[i]), opbuffer[i], 64, syntax); + print_imm_operand(ASM_OPERAND(ASM_INSTRUCTION(instr)->operands[i]), opbuffer[i], 256, syntax); + + offset = ASM_OPERAND(ASM_INSTRUCTION(instr)->operands[i])->value.val32; /* FIXME !!! */ + + if (ASM_OPERAND(ASM_INSTRUCTION(instr)->operands[i])->size == proc->operand_size + && resolve_exe_symbol(format, &label, &symtype, &offset)) + { + oplen = strlen(opbuffer[i]); + + if (offset == 0) snprintf(&opbuffer[i][oplen], 256 - oplen, " <%s>", label); + else snprintf(&opbuffer[i][oplen], 256 - oplen, " <%s+0x%llx>", label, offset); + + free(label); + + } + break; case AOT_REG: - x86_print_reg_operand(ASM_INSTRUCTION(instr)->operands[i], opbuffer[i], 64, syntax); + x86_print_reg_operand(ASM_INSTRUCTION(instr)->operands[i], opbuffer[i], 256, syntax); break; case AOT_MEM: break; case AOT_MOFFS: - x86_print_moffs_operand(ASM_INSTRUCTION(instr)->operands[i], opbuffer[i], 64, syntax); + x86_print_moffs_operand(ASM_INSTRUCTION(instr)->operands[i], opbuffer[i], 256, syntax); break; } diff --git a/src/binary.c b/src/binary.c index 0737d90..1bc87cb 100644 --- a/src/binary.c +++ b/src/binary.c @@ -201,6 +201,7 @@ void fill_snippet(GtkSnippet *snippet, GtkWidget *panel) if (comments_list[i]->offset >= base) break; + gtk_snippet_set_format(snippet, format); gtk_snippet_set_processor(snippet, proc); diff --git a/src/format/elf/e_elf.c b/src/format/elf/e_elf.c index 0493df8..f716846 100644 --- a/src/format/elf/e_elf.c +++ b/src/format/elf/e_elf.c @@ -60,6 +60,7 @@ elf_format *load_elf(const uint8_t *content, off_t length) EXE_FORMAT(result)->find_section = (find_section_fc)find_elf_section; EXE_FORMAT(result)->get_symbols = (get_symbols_fc)get_elf_symbols; + EXE_FORMAT(result)->resolve_symbol = (resolve_symbol_fc)resolve_elf_symbol; memcpy(&result->header, content, sizeof(Elf32_Ehdr)); @@ -114,3 +115,48 @@ size_t get_elf_symbols(const elf_format *format, char ***labels, SymbolType **ty return result; } + + +/****************************************************************************** +* * +* Paramètres : format = informations chargées à consulter. * +* label = étiquette du symbole si trouvé. [OUT] * +* type = type du symbole trouvé. [OUT] * +* offset = adresse à cibler, puis décallage final. [OUT] * +* * +* Description : Recherche le symbole correspondant à une adresse. * +* * +* Retour : true si l'opération a été un succès, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool resolve_elf_symbol(const elf_format *format, char **label, SymbolType *type, uint64_t *offset) +{ + bool result; /* Bilan à retourner */ + size_t best_index; /* Meilleur symbole trouvé */ + uint64_t best_addr; /* Meilleure adresse trouvée */ + size_t i; /* Boucle de parcours */ + + best_addr = UINT64_MAX; + + for (i = 0; i < format->sym_count; i++) + if (format->symbols[i].address <= *offset && (*offset - format->symbols[i].address) < best_addr) + { + best_index = i; + best_addr = *offset - format->symbols[i].address; + } + + result = (best_addr != UINT64_MAX); + + if (result) + { + *label = strdup(format->symbols[best_index].name); + *type = STP_SECTION; + *offset -= format->symbols[best_index].address; + } + + return result; + +} diff --git a/src/format/elf/e_elf.h b/src/format/elf/e_elf.h index d4bf39b..e101fc6 100644 --- a/src/format/elf/e_elf.h +++ b/src/format/elf/e_elf.h @@ -45,6 +45,8 @@ elf_format *load_elf(const uint8_t *, off_t); /* Récupère tous les symboles présents dans le contenu binaire. */ size_t get_elf_symbols(const elf_format *, char ***, SymbolType **, uint64_t **); +/* Recherche le symbole correspondant à une adresse. */ +bool resolve_elf_symbol(const elf_format *, char **, SymbolType *, uint64_t *); diff --git a/src/format/exe_format-int.h b/src/format/exe_format-int.h index b437087..d1f9381 100644 --- a/src/format/exe_format-int.h +++ b/src/format/exe_format-int.h @@ -35,6 +35,8 @@ typedef bool (* find_section_fc) (const exe_format *, const char *, off_t *, off /* Récupère tous les symboles présents dans le contenu binaire. */ typedef size_t (* get_symbols_fc) (const exe_format *, char ***, SymbolType **, uint64_t **); +/* Recherche le symbole correspondant à une adresse. */ +typedef bool (* resolve_symbol_fc) (const exe_format *, char **, SymbolType *, uint64_t *); @@ -46,6 +48,7 @@ struct _exe_format find_section_fc find_section; /* Recherche d'une section */ get_symbols_fc get_symbols; /* Liste des symboles présents */ + resolve_symbol_fc resolve_symbol; /* Recherche de symboles */ }; diff --git a/src/format/exe_format.c b/src/format/exe_format.c index 5cbaba5..1481d22 100644 --- a/src/format/exe_format.c +++ b/src/format/exe_format.c @@ -73,3 +73,25 @@ size_t get_exe_symbols(const exe_format *format, char ***labels, SymbolType **ty return format->get_symbols(format, labels, types, offsets); } + + +/****************************************************************************** +* * +* Paramètres : format = informations chargées à consulter. * +* label = étiquette du symbole si trouvé. [OUT] * +* type = type du symbole trouvé. [OUT] * +* offset = adresse à cibler, puis décallage final. [OUT] * +* * +* Description : Recherche le symbole correspondant à une adresse. * +* * +* Retour : true si l'opération a été un succès, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool resolve_exe_symbol(const exe_format *format, char **label, SymbolType *type, uint64_t *offset) +{ + return format->resolve_symbol(format, label, type, offset); + +} diff --git a/src/format/exe_format.h b/src/format/exe_format.h index 3dab5a7..f859e13 100644 --- a/src/format/exe_format.h +++ b/src/format/exe_format.h @@ -50,6 +50,8 @@ bool find_exe_section(const exe_format *, const char *, off_t *, off_t *, uint64 /* Récupère tous les symboles présents dans le contenu binaire. */ size_t get_exe_symbols(const exe_format *, char ***, SymbolType **, uint64_t **); +/* Recherche le symbole correspondant à une adresse. */ +bool resolve_exe_symbol(const exe_format *, char **, SymbolType *, uint64_t *); diff --git a/src/gtksnippet.c b/src/gtksnippet.c index 73339fd..3254d8e 100644 --- a/src/gtksnippet.c +++ b/src/gtksnippet.c @@ -454,6 +454,26 @@ void gtk_snippet_test(GtkSnippet *snippet) /****************************************************************************** * * * Paramètres : snippet = composant GTK à mettre à jour. * +* format = format du binaire affiché. * +* * +* Description : Définit le format auquel le contenu est lié. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void gtk_snippet_set_format(GtkSnippet *snippet, const exe_format *format) +{ + snippet->format = format; + +} + + +/****************************************************************************** +* * +* Paramètres : snippet = composant GTK à mettre à jour. * * proc = architecture à associer au contenu. * * * * Description : Définit l'architecture à laquelle le contenu est lié. * @@ -558,7 +578,7 @@ void gtk_snippet_build_content(GtkSnippet *snippet) if (snippet->info[i].instr != NULL) { - print_hinstruction(snippet->proc, snippet->info[i].instr, buffer, CONTENT_BUFFER_LEN, ASX_INTEL); + print_hinstruction(snippet->proc, snippet->format, snippet->info[i].instr, buffer, CONTENT_BUFFER_LEN, ASX_INTEL); content_len += strlen("\t") + strlen(buffer); diff --git a/src/gtksnippet.h b/src/gtksnippet.h index a90e89c..016787c 100644 --- a/src/gtksnippet.h +++ b/src/gtksnippet.h @@ -30,10 +30,9 @@ #include - - #include "arch/instruction.h" #include "arch/processor.h" +#include "format/exe_format.h" @@ -97,6 +96,7 @@ struct _GtkSnippet { GdkGC *gc; /* Contexte graphique du rendu */ int line_height; /* Hauteur maximale des lignes */ + const exe_format *format; /* Format du contenu bianire */ const asm_processor *proc; /* Architecture utilisée */ code_line_info *info; /* Contenu à représenter */ unsigned int info_count; /* Quantité d'informations */ @@ -121,6 +121,8 @@ GtkWidget * gtk_snippet_new(); void gtk_snippet_test(GtkSnippet *cpu); +/* Définit le format auquel le contenu est lié. */ +void gtk_snippet_set_format(GtkSnippet *, const exe_format *); /* Définit l'architecture à laquelle le contenu est lié. */ void gtk_snippet_set_processor(GtkSnippet *, const asm_processor *); -- cgit v0.11.2-87-g4458