diff options
Diffstat (limited to 'src/decomp')
| -rw-r--r-- | src/decomp/context.c | 55 | ||||
| -rw-r--r-- | src/decomp/context.h | 5 | ||||
| -rw-r--r-- | src/decomp/expr/pseudo.c | 30 | ||||
| -rw-r--r-- | src/decomp/expr/pseudo.h | 3 | 
4 files changed, 91 insertions, 2 deletions
| diff --git a/src/decomp/context.c b/src/decomp/context.c index 7fe6937..6440c56 100644 --- a/src/decomp/context.c +++ b/src/decomp/context.c @@ -24,6 +24,14 @@  #include "context.h" +#include <malloc.h> + + +#include "expr/pseudo.h" +#include "../arch/operand.h" +#include "../glibext/gnhash.h" + +  /* Définition d'une context décompilée (instance) */  struct _GDecContext @@ -32,6 +40,12 @@ struct _GDecContext      vmpa_t max;                             /* Première adresse à écarter  */ +    GHashTable *machine;                    /* Correspondance reg./pseudo  */ +    GHashTable *ssa;                        /* Remplacement des pseudos    */ + +    GDecInstruction **pseudos;              /* Liste des pseudos-registre  */ +    size_t count;                           /* Taille de cette liste       */ +  }; @@ -87,6 +101,8 @@ static void g_dec_context_class_init(GDecContextClass *klass)  static void g_dec_context_init(GDecContext *ctx)  { +    ctx->machine = g_hash_table_new(g_constant_hash, (GEqualFunc)g_arch_operand_compare); +    ctx->ssa = g_hash_table_new(NULL, NULL);  } @@ -151,3 +167,42 @@ void g_dec_context_set_max_address(GDecContext *ctx, vmpa_t max)      ctx->max = max;  } + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : ctx     = instance à consulter, voire mettre à jour.         * +*                operand = opérande représentant un registre quelconque.      * +*                                                                             * +*  Description : Convertit un registre machine en un pseudo-registre.         * +*                                                                             * +*  Retour      : Pseudo-registre, existant ou non, prêt à emploi.             * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +GDecInstruction *g_dec_context_convert_register(GDecContext *ctx, gpointer operand) +{ +    GDecInstruction *result;                /* Instance à retourner        */ +    gpointer *found;                        /* Pseudo-registre trouvé      */ + +    found = g_hash_table_lookup(ctx->machine, operand); + +    if (found != NULL) result = G_DEC_INSTRUCTION(found); +    else +    { +        result = g_pseudo_register_new(); +        g_pseudo_register_set_index(G_PSEUDO_REGISTER(result), ctx->count); + +        g_hash_table_insert(ctx->machine, operand, result); + +        ctx->pseudos = (GDecInstruction **)realloc(ctx->pseudos, +                                                   ++ctx->count * sizeof(GDecInstruction *)); +        ctx->pseudos[ctx->count - 1] = result; + +    } + +    return result; + +} diff --git a/src/decomp/context.h b/src/decomp/context.h index 76105e6..926a372 100644 --- a/src/decomp/context.h +++ b/src/decomp/context.h @@ -28,7 +28,7 @@  #include <glib-object.h> -#include "expr/pseudo.h" +#include "instruction.h"  #include "../arch/archbase.h" @@ -61,6 +61,9 @@ vmpa_t g_dec_context_get_max_address(const GDecContext *);  /* Définit l'adresse où la décompilation n'est plus souhaitée. */  void g_dec_context_set_max_address(GDecContext *, vmpa_t); +/* Convertit un registre machine en un pseudo-registre. */ +GDecInstruction *g_dec_context_convert_register(GDecContext *, gpointer); +  #endif  /* _DECOMP_CONTEXT_H */ diff --git a/src/decomp/expr/pseudo.c b/src/decomp/expr/pseudo.c index 393f32c..abfcd4d 100644 --- a/src/decomp/expr/pseudo.c +++ b/src/decomp/expr/pseudo.c @@ -24,6 +24,10 @@  #include "pseudo.h" +#include <stdio.h> +#include <string.h> + +  #include "../expression-int.h" @@ -33,6 +37,8 @@ struct _GPseudoRegister  {      GDecExpression parent;                  /* A laisser en premier        */ +    size_t index;                           /* Position dans l'ensemble    */ +  }; @@ -141,8 +147,30 @@ GDecInstruction *g_pseudo_register_new(void)  static void g_pseudo_register_print(const GPseudoRegister *reg, GCodeBuffer *buffer, GBufferLine *line, GLangOutput *output)  { +    char label[32]; + +    snprintf(label, 32, "var%d", reg->index); + +    g_buffer_line_insert_text(line, BLC_ASSEMBLY, label, strlen(label), RTT_RAW); -    g_buffer_line_insert_text(line, BLC_ASSEMBLY, "varX", 4, RTT_RAW); +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : reg   = expression représentant un pseudo-registre à traiter.* +*                index = indice à associer au pseudo-registre.                * +*                                                                             * +*  Description : Définit un indice unique pour un pseudo-registre donné.      * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ +void g_pseudo_register_set_index(GPseudoRegister *reg, size_t index) +{ +    reg->index = index;  } diff --git a/src/decomp/expr/pseudo.h b/src/decomp/expr/pseudo.h index 9734625..95612a9 100644 --- a/src/decomp/expr/pseudo.h +++ b/src/decomp/expr/pseudo.h @@ -54,6 +54,9 @@ GType g_pseudo_register_get_type(void);  /* Assigne le contenu d'une expression dans une autre. */  GDecInstruction *g_pseudo_register_new(void); +/* Définit un indice unique pour un pseudo-registre donné. */ +void g_pseudo_register_set_index(GPseudoRegister *, size_t); +  #endif  /* _DECOMP_EXPR_PSEUDO_H */ | 
