diff options
| author | Cyrille Bagard <nocbos@gmail.com> | 2016-09-26 18:24:23 (GMT) | 
|---|---|---|
| committer | Cyrille Bagard <nocbos@gmail.com> | 2016-09-26 18:24:23 (GMT) | 
| commit | 7972f2da7d0e363fe918992cb5661b17ee3577d7 (patch) | |
| tree | 6bf42830f32315d01f90c551778b47cc62bba639 /src/analysis | |
| parent | 79f384b20e00977f8450920a8a8983b818d302f8 (diff) | |
Defined a proper cache for routine names with their packages.
Diffstat (limited to 'src/analysis')
| -rw-r--r-- | src/analysis/routine.c | 179 | ||||
| -rw-r--r-- | src/analysis/routine.h | 10 | ||||
| -rw-r--r-- | src/analysis/type.c | 16 | 
3 files changed, 151 insertions, 54 deletions
| diff --git a/src/analysis/routine.c b/src/analysis/routine.c index 559b9bf..7483bf0 100644 --- a/src/analysis/routine.c +++ b/src/analysis/routine.c @@ -45,13 +45,16 @@ struct _GBinRoutine      GDataType *ret_type;                    /* Type retourné               */      GDataType *namespace;                   /* Espace de noms / classe     */ +    const char *ns_sep;                     /* Séparateur d'éléments       */      char *name;                             /* Désignation humaine         */      GDataType *full_name;                   /* Désignation très complète   */ -    char *long_name;                        /* Désignation très complète ??*/      GBinVariable **args;                    /* Arguments de la routines    */      size_t args_count;                      /* Nombre d'arguments          */ +    char *cached_decl;                      /* Cache pour désignation #1   */ +    char *cached_full_decl;                 /* Cache pour désignation #2   */ +      GBinVariable **locals;                  /* Variables locales du code   */      size_t locals_count;                    /* Nombre de variables locales */ @@ -76,6 +79,9 @@ static void g_bin_routine_class_init(GBinRoutineClass *);  /* Initialise une instance représentation de routine. */  static void g_bin_routine_init(GBinRoutine *); +/* Vide le cache des descriptions humaines. */ +static void g_binary_routine_reset_declarator(GBinRoutine *, bool); +  /* Indique le type définit pour une représentation de routine. */ @@ -102,7 +108,7 @@ static void g_bin_routine_class_init(GBinRoutineClass *klass)  /******************************************************************************  *                                                                             * -*  Paramètres  : line = instance à initialiser.                               * +*  Paramètres  : routine = instance à initialiser.                            *  *                                                                             *  *  Description : Initialise une instance représentation de routine.           *  *                                                                             * @@ -112,7 +118,7 @@ static void g_bin_routine_class_init(GBinRoutineClass *klass)  *                                                                             *  ******************************************************************************/ -static void g_bin_routine_init(GBinRoutine *line) +static void g_bin_routine_init(GBinRoutine *routine)  {  } @@ -301,6 +307,7 @@ void g_binary_routine_set_type(GBinRoutine *routine, RoutineType type)  *                                                                             *  *  Paramètres  : routine   = routine à mettre à jour.                         *  *                namespace = instance d'appartenance.                         * +*                sep       = séparateur à utiliser entre les éléments.        *  *                                                                             *  *  Description : Définit le groupe d'appartenance d'une routine donnée.       *  *                                                                             * @@ -310,9 +317,12 @@ void g_binary_routine_set_type(GBinRoutine *routine, RoutineType type)  *                                                                             *  ******************************************************************************/ -void g_binary_routine_set_namespace(GBinRoutine *routine, GDataType *namespace) +void g_binary_routine_set_namespace(GBinRoutine *routine, GDataType *namespace, const char *sep)  {      routine->namespace = namespace; +    routine->ns_sep = sep; + +    g_binary_routine_reset_declarator(routine, false);  } @@ -356,6 +366,8 @@ void g_binary_routine_set_name(GBinRoutine *routine, char *name)      routine->name = name; +    g_binary_routine_reset_declarator(routine, true); +  } @@ -371,11 +383,8 @@ void g_binary_routine_set_name(GBinRoutine *routine, char *name)  *                                                                             *  ******************************************************************************/ -const char *g_binary_routine_get_name(GBinRoutine *routine) +const char *g_binary_routine_get_name(const GBinRoutine *routine)  { -    if (routine->name == NULL && routine->full_name != NULL) -        g_binary_routine_set_name(routine, g_data_type_to_string(routine->full_name)); -      return routine->name;  } @@ -384,40 +393,6 @@ const char *g_binary_routine_get_name(GBinRoutine *routine)  /******************************************************************************  *                                                                             *  *  Paramètres  : routine = routine à mettre à jour.                           * -*                                                                             * -*  Description : Fournit le nom long et humain d'une routine.                 * -*                                                                             * -*  Retour      : Désignation humainement lisible ou NULL si non définie.      * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -const char *g_binary_routine_get_long_name(GBinRoutine *routine) -{ -    if (routine->long_name == NULL) -    { -        if (routine->namespace != NULL) -        { -            routine->long_name = strdup(""); -            routine->long_name = g_data_type_to_string(routine->namespace); -            routine->long_name = stradd(routine->long_name, "." /* FIXME */); -        } -        else -            routine->long_name = strdup(""); - -        routine->long_name = stradd(routine->long_name, g_binary_routine_get_name(routine)); - -    } - -    return routine->long_name; - -} - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : routine = routine à mettre à jour.                           *  *                type    = désignation complète du nom de la routine.         *  *                                                                             *  *  Description : Définit de façon indirecte le nom humain d'une routine.      * @@ -435,6 +410,8 @@ void g_binary_routine_set_name_from_type(GBinRoutine *routine, GDataType *type)      routine->full_name = type; +    g_binary_routine_reset_declarator(routine, true); +  } @@ -599,6 +576,124 @@ void g_binary_routine_remove_arg(GBinRoutine *routine, size_t index)  /******************************************************************************  *                                                                             *  *  Paramètres  : routine = routine à mettre à jour.                           * +*                full    = indique la portée de la réinitialisation.          * +*                                                                             * +*  Description : Vide le cache des descriptions humaines.                     * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_binary_routine_reset_declarator(GBinRoutine *routine, bool full) +{ +    if (full && routine->cached_decl != NULL) +    { +        free(routine->cached_decl); +        routine->cached_decl = NULL; +    } + +    if (routine->cached_full_decl != NULL) +    { +        free(routine->cached_full_decl); +        routine->cached_full_decl = NULL; +    } + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : routine = routine à mettre à jour.                           * +*                full    = indique si la liste des arguments est à ajouter.   * +*                                                                             * +*  Description : Fournit le nom humain d'une routine.                         * +*                                                                             * +*  Retour      : Désignation humainement lisible ou NULL si non définie.      * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +const char *g_binary_routine_get_declarator(GBinRoutine *routine, bool full) +{ +    char *new;                              /* Nouvelle description        */ +    char *namespace;                        /* Groupe d'appartenance       */ +    size_t i;                               /* Boucle de parcours          */ +    char *typestr;                          /* Stockage de nom temporaire  */ + +    if (routine->cached_decl == NULL) +    { +        if (routine->full_name != NULL) +            new = _g_data_type_to_string(routine->full_name, false); +        else +            new = routine->name; + +        if (routine->namespace != NULL) +        { +            namespace = _g_data_type_to_string(routine->namespace, false); + +            new = strprep(new, routine->ns_sep); +            new = strprep(new, namespace); + +            free(namespace); + +        } + +        /* Mémorisation finale */ + +        routine->cached_decl = new; + +    } + +    if (full && routine->cached_full_decl == NULL) +    { +        /* Type de retour */ + +        if (routine->ret_type == NULL) +            new = strdup("??? "); +        else +        { +            new = _g_data_type_to_string(routine->ret_type, true); +            if (!g_data_type_is_pointer(routine->ret_type, true)) +                new = stradd(new, " "); +        } + +        /* Nom de la routine */ + +        new = stradd(new, routine->cached_decl); + +        /* Liste des arguments */ + +        new = stradd(new, "("); + +        for (i = 0; i < routine->args_count; i++) +        { +            if (i > 0) new = stradd(new, ", "); + +            typestr = g_binary_variable_to_string(routine->args[i], true); +            new = stradd(new, typestr); +            free(typestr); + +        } + +        new = stradd(new, ")"); + +        /* Mémorisation finale */ + +        routine->cached_full_decl = new; + +    } + +    return (full ? routine->cached_full_decl : routine->cached_decl); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : routine = routine à mettre à jour.                           *  *                offset  = position abstraite à retrouver.                    *  *                local   = indique le type de variable à manipuler.           *  *                                                                             * diff --git a/src/analysis/routine.h b/src/analysis/routine.h index 9ee2c2f..38e7b32 100644 --- a/src/analysis/routine.h +++ b/src/analysis/routine.h @@ -113,7 +113,7 @@ void g_binary_routine_set_size(GBinRoutine *, off_t);  void g_binary_routine_set_type(GBinRoutine *, RoutineType);  /* Définit le groupe d'appartenance d'une routine donnée. */ -void g_binary_routine_set_namespace(GBinRoutine *, GDataType *); +void g_binary_routine_set_namespace(GBinRoutine *, GDataType *, const char *);  /* Fournit le groupe d'appartenance d'une routine donnée. */  GDataType *g_binary_routine_get_namespace(const GBinRoutine *); @@ -122,10 +122,7 @@ GDataType *g_binary_routine_get_namespace(const GBinRoutine *);  void g_binary_routine_set_name(GBinRoutine *, char *);  /* Désignation humainement lisible ou NULL si non définie. */ -const char *g_binary_routine_get_name(GBinRoutine *); - -/* Fournit le nom long et humain d'une routine. */ -const char *g_binary_routine_get_long_name(GBinRoutine *); +const char *g_binary_routine_get_name(const GBinRoutine *);  /* Définit de façon indirecte le nom humain d'une routine. */  void g_binary_routine_set_name_from_type(GBinRoutine *, GDataType *); @@ -151,6 +148,9 @@ GBinVariable *g_binary_routine_get_arg(GBinRoutine *, size_t);  /* Retire un argument d'une routine. */  void g_binary_routine_remove_arg(GBinRoutine *, size_t); +/* Fournit le nom humain d'une routine. */ +const char *g_binary_routine_get_declarator(GBinRoutine *, bool); +  /* S'assure qu'une variable est bien associée à une routine. */  void g_binary_routine_register_if_needed(GBinRoutine *, size_t, bool); diff --git a/src/analysis/type.c b/src/analysis/type.c index 37ad5a1..23ecc2a 100644 --- a/src/analysis/type.c +++ b/src/analysis/type.c @@ -174,20 +174,22 @@ void g_data_type_set_namespace(GDataType *type, GDataType *namespace)  char *_g_data_type_to_string(const GDataType *type, bool simple)  {      char *result;                           /* Chaîne à retourner          */ +    const GDataType *parent;                /* Espace supérieur            */      char *namespace;                        /* Groupe d'appartenance       */      result = type->to_string(type); -    if (!simple && type->namespace != NULL) -    { -        namespace = g_data_type_to_string(type->namespace); +    if (!simple) +        for (parent = type->namespace; parent != NULL; parent = parent->namespace) +        { +            namespace = g_data_type_to_string(parent); -        result = strprep(result, "." /* FIXME */); -        result = strprep(result, namespace); +            result = strprep(result, "." /* FIXME */); +            result = strprep(result, namespace); -        free(namespace); +            free(namespace); -    } +        }      if (type->qualifiers & TQF_RESTRICT)          result = strprep(result, "restrict "); | 
