diff options
Diffstat (limited to 'src/format')
| -rwxr-xr-x | src/format/dex/Makefile.am | 1 | ||||
| -rwxr-xr-x | src/format/dex/dex.c | 9 | ||||
| -rw-r--r-- | src/format/dex/loading.c | 240 | ||||
| -rw-r--r-- | src/format/dex/loading.h | 61 | ||||
| -rw-r--r-- | src/format/dex/pool.c | 120 | ||||
| -rw-r--r-- | src/format/dex/pool.h | 6 | ||||
| -rw-r--r-- | src/format/elf/symbols.c | 2 | ||||
| -rw-r--r-- | src/format/mangling/dex/type_gram.y | 32 | ||||
| -rw-r--r-- | src/format/mangling/dex/type_tok.l | 32 | 
9 files changed, 444 insertions, 59 deletions
| diff --git a/src/format/dex/Makefile.am b/src/format/dex/Makefile.am index 7a2416f..28f8e73 100755 --- a/src/format/dex/Makefile.am +++ b/src/format/dex/Makefile.am @@ -6,6 +6,7 @@ libformatdex_la_SOURCES =				\  	dex-int.h dex-int.c					\  	dex.h dex.c							\  	dex_def.h							\ +	loading.h loading.c					\  	method.h method.c					\  	pool.h pool.c diff --git a/src/format/dex/dex.c b/src/format/dex/dex.c index 582390a..d02111c 100755 --- a/src/format/dex/dex.c +++ b/src/format/dex/dex.c @@ -248,6 +248,7 @@ GBinFormat *g_dex_format_new(GBinContent *content, GExeFormat *parent, GtkStatus      GDexFormat *result;                     /* Structure à retourner       */      GBinFormat *base;                       /* Version basique du format   */      vmpa2t pos;                             /* Position de tête de lecture */ +    wgroup_id_t gid;                        /* Identifiant pour les tâches */      result = g_object_new(G_TYPE_DEX_FORMAT, NULL); @@ -265,13 +266,15 @@ GBinFormat *g_dex_format_new(GBinContent *content, GExeFormat *parent, GtkStatus      /* TODO : vérifier que les *_id ne se chevauchent pas */ -    if (!load_all_dex_types(result, status)) +    gid = g_work_queue_define_work_group(get_work_queue()); + +    if (!load_all_dex_types(result, gid, status))          goto gdfn_error; -    if (!load_all_dex_fields(result, status)) +    if (!load_all_dex_fields(result, gid, status))          goto gdfn_error; -    if (!load_all_dex_classes(result, status)) +    if (!load_all_dex_classes(result, gid, status))          goto gdfn_error;      if (!g_binary_format_complete_loading(base, status)) diff --git a/src/format/dex/loading.c b/src/format/dex/loading.c new file mode 100644 index 0000000..a5b675d --- /dev/null +++ b/src/format/dex/loading.c @@ -0,0 +1,240 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * loading.c - chargements parallèles des éléments de la table globale du format Dex + * + * Copyright (C) 2016 Cyrille Bagard + * + *  This file is part of Chrysalide. + * + *  OpenIDA is free software; you can redistribute it and/or modify + *  it under the terms of the GNU General Public License as published by + *  the Free Software Foundation; either version 3 of the License, or + *  (at your option) any later version. + * + *  OpenIDA is distributed in the hope that it will be useful, + *  but WITHOUT ANY WARRANTY; without even the implied warranty of + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + *  GNU General Public License for more details. + * + *  You should have received a copy of the GNU General Public License + *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>. + */ + + +#include "loading.h" + + +#include <i18n.h> + + +#include "pool.h" +#include "../../glibext/delayed-int.h" +#include "../../gui/panels/log.h" + + + +/* Fraction de routines à limiter (instance) */ +struct _GDexLoading +{ +    GDelayedWork parent;                    /* A laisser en premier        */ + +    GDexFormat *format;                     /* Format à faire évoluer      */ + +    dex_loading_cb callback;                /* Routine de traitement finale*/ +    uint32_t begin;                         /* Point de départ du parcours */ +    uint32_t end;                           /* Point d'arrivée exclu       */ + +    activity_id_t id;                       /* Identifiant pour messages   */ + +    bool *status;                           /* Bilan global constitué      */ + +}; + +/* Fraction de routines à limiter (classe) */ +struct _GDexLoadingClass +{ +    GDelayedWorkClass parent;               /* A laisser en premier        */ + +}; + + +/* Initialise la classe des tâches des chargements pour DEX. */ +static void g_dex_loading_class_init(GDexLoadingClass *); + +/* Initialise une tâche de chargements pour DEX. */ +static void g_dex_loading_init(GDexLoading *); + +/* Supprime toutes les références externes. */ +static void g_dex_loading_dispose(GDexLoading *); + +/* Procède à la libération totale de la mémoire. */ +static void g_dex_loading_finalize(GDexLoading *); + +/* Assure le chargement pour un format DEX en différé. */ +static void g_dex_loading_process(GDexLoading *, GtkStatusStack *); + + + +/* Indique le type défini pour les tâches de chargements pour format DEX. */ +G_DEFINE_TYPE(GDexLoading, g_dex_loading, G_TYPE_DELAYED_WORK); + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : klass = classe à initialiser.                                * +*                                                                             * +*  Description : Initialise la classe des tâches des chargements pour DEX.    * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_dex_loading_class_init(GDexLoadingClass *klass) +{ +    GObjectClass *object;                   /* Autre version de la classe  */ +    GDelayedWorkClass *work;                /* Version en classe parente   */ + +    object = G_OBJECT_CLASS(klass); + +    object->dispose = (GObjectFinalizeFunc/* ! */)g_dex_loading_dispose; +    object->finalize = (GObjectFinalizeFunc)g_dex_loading_finalize; + +    work = G_DELAYED_WORK_CLASS(klass); + +    work->run = (run_task_fc)g_dex_loading_process; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : loading = instance à initialiser.                            * +*                                                                             * +*  Description : Initialise une tâche de chargements pour DEX.                * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_dex_loading_init(GDexLoading *loading) +{ + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : loading = instance d'objet GLib à traiter.                   * +*                                                                             * +*  Description : Supprime toutes les références externes.                     * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_dex_loading_dispose(GDexLoading *loading) +{ +    G_OBJECT_CLASS(g_dex_loading_parent_class)->dispose(G_OBJECT(loading)); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : loading = instance d'objet GLib à traiter.                   * +*                                                                             * +*  Description : Procède à la libération totale de la mémoire.                * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_dex_loading_finalize(GDexLoading *loading) +{ +    G_OBJECT_CLASS(g_dex_loading_parent_class)->finalize(G_OBJECT(loading)); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : format = = ensemble d'instructions désassemblées.            * +*                begin    = point de départ du parcours de liste.             * +*                end      = point d'arrivée exclu du parcours.                * +*                id       = identifiant du message affiché à l'utilisateur.   * +*                callback = routine de traitements particuliers.              * +*                status   = bilan final à constituer. [OUT]                   * +*                                                                             * +*  Description : Crée une tâche de chargement pour DEX différée.              * +*                                                                             * +*  Retour      : Tâche créée.                                                 * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +GDexLoading *g_dex_loading_new(GDexFormat *format, uint32_t begin, uint32_t end, activity_id_t id, dex_loading_cb callback, bool *status) +{ +    GDexLoading *result;                    /* Tâche à retourner           */ + +    result = g_object_new(G_TYPE_DEX_LOADING, NULL); + +    result->format = format; + +    result->callback = callback; +    result->begin = begin; +    result->end = end; + +    result->id = id; + +    result->status = status; + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : study  = étude de routines à mener.                          * +*                status = barre de statut à tenir informée.                   * +*                                                                             * +*  Description : Assure le chargement pour un format DEX en différé.          * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_dex_loading_process(GDexLoading *loading, GtkStatusStack *status) +{ +    uint32_t i;                             /* Boucle de parcours          */ +    GObject *obj;                           /* Object chargé en mémoire    */ + +    for (i = loading->begin; i < loading->end && *(loading->status); i++) +    { +        obj = loading->callback(loading->format, i); + +        if (obj != NULL) +            g_object_unref(obj); + +        else +        { +            *(loading->status) = false; +            log_variadic_message(LMT_ERROR, _("Error while loading Dex pool item #%u!"), i); +        } + +        gtk_status_stack_update_activity_value(status, loading->id, 1); + +    } + +} diff --git a/src/format/dex/loading.h b/src/format/dex/loading.h new file mode 100644 index 0000000..4c055ce --- /dev/null +++ b/src/format/dex/loading.h @@ -0,0 +1,61 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * loading.h - prototypes pour les chargements parallèles des éléments de la table globale du format Dex + * + * Copyright (C) 2016 Cyrille Bagard + * + *  This file is part of Chrysalide. + * + *  OpenIDA is free software; you can redistribute it and/or modify + *  it under the terms of the GNU General Public License as published by + *  the Free Software Foundation; either version 3 of the License, or + *  (at your option) any later version. + * + *  OpenIDA is distributed in the hope that it will be useful, + *  but WITHOUT ANY WARRANTY; without even the implied warranty of + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + *  GNU General Public License for more details. + * + *  You should have received a copy of the GNU General Public License + *  along with Foobar.  If not, see <http://www.gnu.org/licenses/>. + */ + + +#ifndef _FORMAT_DEX_LOADING_H +#define _FORMAT_DEX_LOADING_H + + +#include "dex.h" +#include "../../gtkext/gtkstatusstack.h" + + + +#define G_TYPE_DEX_LOADING              g_dex_loading_get_type() +#define G_DEX_LOADING(obj)              (G_TYPE_CHECK_INSTANCE_CAST((obj), g_dex_loading_get_type(), GDexLoading)) +#define G_IS_DEX_LOADING(obj)           (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_dex_loading_get_type())) +#define G_DEX_LOADING_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_DEX_LOADING, GDexLoadingClass)) +#define G_IS_DEX_LOADING_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_DEX_LOADING)) +#define G_DEX_LOADING_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_DEX_LOADING, GDexLoadingClass)) + + +/* Fraction de loading à limiter (instance) */ +typedef struct _GDexLoading GDexLoading; + +/* Fraction de loading à limiter (classe) */ +typedef struct _GDexLoadingClass GDexLoadingClass; + + + +/* Extrait une représentation générique d'une table Dex. */ +typedef GObject * (* dex_loading_cb) (GDexFormat *, uint32_t); + + +/* Indique le type défini pour les tâches de chargements pour format DEX. */ +GType g_dex_loading_get_type(void); + +/* Crée une tâche de chargement pour DEX différée. */ +GDexLoading *g_dex_loading_new(GDexFormat *, uint32_t, uint32_t, activity_id_t, dex_loading_cb, bool *); + + + +#endif  /* _FORMAT_DEX_LOADING_H */ diff --git a/src/format/dex/pool.c b/src/format/dex/pool.c index 7574638..769a4f1 100644 --- a/src/format/dex/pool.c +++ b/src/format/dex/pool.c @@ -32,6 +32,7 @@  #include "dex-int.h" +#include "loading.h"  #include "../mangling/demangler.h"  #include "../mangling/dex/context.h" @@ -125,6 +126,7 @@ const char *get_string_from_dex_pool(const GDexFormat *format, uint32_t index)  /******************************************************************************  *                                                                             *  *  Paramètres  : format = description de l'exécutable à compléter.            * +*                gid    = groupe de travail impliqué.                         *                   status = barre de statut à tenir informée.                   *  *                                                                             *  *  Description : Charge en mémoire l'ensemble des types du format DEX.        * @@ -135,33 +137,53 @@ const char *get_string_from_dex_pool(const GDexFormat *format, uint32_t index)  *                                                                             *  ******************************************************************************/ -bool load_all_dex_types(GDexFormat *format, GtkStatusStack *status) +bool load_all_dex_types(GDexFormat *format, wgroup_id_t gid, GtkStatusStack *status)  {      bool result;                            /* Bilan à retourner           */ +    guint runs_count;                       /* Qté d'exécutions parallèles */ +    uint32_t run_size;                      /* Volume réparti par exécution*/ +    GWorkQueue *queue;                      /* Gestionnaire de différés    */      activity_id_t msg;                      /* Message de progression      */ -    uint32_t i;                             /* Boucle de parcours          */ -    GDataType *type;                        /* Type récupéré               */ +    guint i;                                /* Boucle de parcours          */ +    uint32_t begin;                         /* Début de bloc de traitement */ +    uint32_t end;                           /* Fin d'un bloc de traitement */ +    GDexLoading *loading;                   /* Tâche de chargement à lancer*/      result = true; +    /* Préparation du réceptacle */ +      format->types = (GDataType **)calloc(format->header.type_ids_size, sizeof(GDataType *)); +    /* Lancement des chargements */ + +    runs_count = g_get_num_processors(); + +    run_size = format->header.type_ids_size / runs_count; + +    queue = get_work_queue(); +      msg = gtk_status_stack_add_activity(status, _("Loading all types from the Dex pool..."),                                          format->header.type_ids_size); -    for (i = 0; i < format->header.type_ids_size && result; i++) +    for (i = 0; i < runs_count; i++)      { -        type = get_type_from_dex_pool(format, i); +        begin = i * run_size; -        if (type != NULL) -            g_object_unref(G_OBJECT(type)); +        if ((i + 1) == runs_count) +            end = format->header.type_ids_size;          else -            result = false; +            end = begin + run_size; + +        loading = g_dex_loading_new(format, begin, end, msg, +                                    (dex_loading_cb)get_type_from_dex_pool, &result); -        gtk_status_stack_update_activity_value(status, msg, 1); +        g_work_queue_schedule_work(queue, G_DELAYED_WORK(loading), gid);      } +    g_work_queue_wait_for_completion(queue, gid); +      gtk_status_stack_remove_activity(status, msg);      return result; @@ -235,6 +257,7 @@ GDataType *get_type_from_dex_pool(GDexFormat *format, uint32_t index)  /******************************************************************************  *                                                                             *  *  Paramètres  : format = description de l'exécutable à compléter.            * +*                gid    = groupe de travail impliqué.                         *  *                status = barre de statut à tenir informée.                   *  *                                                                             *  *  Description : Charge en mémoire l'ensemble des champs du format DEX.       * @@ -245,33 +268,53 @@ GDataType *get_type_from_dex_pool(GDexFormat *format, uint32_t index)  *                                                                             *  ******************************************************************************/ -bool load_all_dex_fields(GDexFormat *format, GtkStatusStack *status) +bool load_all_dex_fields(GDexFormat *format, wgroup_id_t gid, GtkStatusStack *status)  {      bool result;                            /* Bilan à retourner           */ +    guint runs_count;                       /* Qté d'exécutions parallèles */ +    uint32_t run_size;                      /* Volume réparti par exécution*/ +    GWorkQueue *queue;                      /* Gestionnaire de différés    */      activity_id_t msg;                      /* Message de progression      */ -    uint32_t i;                             /* Boucle de parcours          */ -    GBinVariable *field;                    /* Champ récupéré              */ +    guint i;                                /* Boucle de parcours          */ +    uint32_t begin;                         /* Début de bloc de traitement */ +    uint32_t end;                           /* Fin d'un bloc de traitement */ +    GDexLoading *loading;                   /* Tâche de chargement à lancer*/      result = true; +    /* Préparation du réceptacle */ +      format->fields = (GBinVariable **)calloc(format->header.field_ids_size, sizeof(GBinVariable *)); +    /* Lancement des chargements */ + +    runs_count = g_get_num_processors(); + +    run_size = format->header.field_ids_size / runs_count; + +    queue = get_work_queue(); +      msg = gtk_status_stack_add_activity(status, _("Loading all fields from the Dex pool..."),                                          format->header.field_ids_size); -    for (i = 0; i < format->header.field_ids_size && result; i++) +    for (i = 0; i < runs_count; i++)      { -        field = get_field_from_dex_pool(format, i); +        begin = i * run_size; -        if (field != NULL) -            g_object_unref(G_OBJECT(field)); +        if ((i + 1) == runs_count) +            end = format->header.field_ids_size;          else -            result = false; +            end = begin + run_size; + +        loading = g_dex_loading_new(format, begin, end, msg, +                                    (dex_loading_cb)get_field_from_dex_pool, &result); -        gtk_status_stack_update_activity_value(status, msg, 1); +        g_work_queue_schedule_work(queue, G_DELAYED_WORK(loading), gid);      } +    g_work_queue_wait_for_completion(queue, gid); +      gtk_status_stack_remove_activity(status, msg);      return result; @@ -506,7 +549,8 @@ GDexMethod *get_method_from_dex_pool(GDexFormat *format, uint32_t index)  /******************************************************************************  *                                                                             *  *  Paramètres  : format = représentation interne du format DEX à compléter.   * -*                status = barre de statut à tenir informée.                   * +*                gid    = groupe de travail impliqué.                         * +                 status = barre de statut à tenir informée.                   *  *                                                                             *  *  Description : Charge toutes les classes listées dans le contenu binaire.   *  *                                                                             * @@ -516,33 +560,53 @@ GDexMethod *get_method_from_dex_pool(GDexFormat *format, uint32_t index)  *                                                                             *  ******************************************************************************/ -bool load_all_dex_classes(GDexFormat *format, GtkStatusStack *status) +bool load_all_dex_classes(GDexFormat *format, wgroup_id_t gid, GtkStatusStack *status)  {      bool result;                            /* Bilan à retourner           */ +    guint runs_count;                       /* Qté d'exécutions parallèles */ +    uint32_t run_size;                      /* Volume réparti par exécution*/ +    GWorkQueue *queue;                      /* Gestionnaire de différés    */      activity_id_t msg;                      /* Message de progression      */ -    uint32_t i;                             /* Boucle de parcours          */ -    GDexClass *class;                       /* Classe récupérée            */ +    guint i;                                /* Boucle de parcours          */ +    uint32_t begin;                         /* Début de bloc de traitement */ +    uint32_t end;                           /* Fin d'un bloc de traitement */ +    GDexLoading *loading;                   /* Tâche de chargement à lancer*/      result = true; +    /* Préparation du réceptacle */ +      format->classes = (GDexClass **)calloc(format->header.class_defs_size, sizeof(GDexClass *)); +    /* Lancement des chargements */ + +    runs_count = g_get_num_processors(); + +    run_size = format->header.class_defs_size / runs_count; + +    queue = get_work_queue(); +      msg = gtk_status_stack_add_activity(status, _("Loading all classes from the Dex pool..."),                                          format->header.class_defs_size); -    for (i = 0; i < format->header.class_defs_size && result; i++) +    for (i = 0; i < runs_count; i++)      { -        class = get_class_from_dex_pool(format, i); +        begin = i * run_size; -        if (class != NULL) -            g_object_unref(G_OBJECT(class)); +        if ((i + 1) == runs_count) +            end = format->header.class_defs_size;          else -            result = false; +            end = begin + run_size; + +        loading = g_dex_loading_new(format, begin, end, msg, +                                    (dex_loading_cb)get_class_from_dex_pool, &result); -        gtk_status_stack_update_activity_value(status, msg, 1); +        g_work_queue_schedule_work(queue, G_DELAYED_WORK(loading), gid);      } +    g_work_queue_wait_for_completion(queue, gid); +      gtk_status_stack_remove_activity(status, msg);      return result; diff --git a/src/format/dex/pool.h b/src/format/dex/pool.h index 4b804cc..cd4c2de 100644 --- a/src/format/dex/pool.h +++ b/src/format/dex/pool.h @@ -43,13 +43,13 @@ const char *get_string_from_dex_pool(const GDexFormat *, uint32_t);  /* Charge en mémoire l'ensemble des types du format DEX. */ -bool load_all_dex_types(GDexFormat *, GtkStatusStack *); +bool load_all_dex_types(GDexFormat *, wgroup_id_t, GtkStatusStack *);  /* Extrait une représentation de type d'une table DEX. */  GDataType *get_type_from_dex_pool(GDexFormat *, uint32_t);  /* Charge en mémoire l'ensemble des champs du format DEX. */ -bool load_all_dex_fields(GDexFormat *, GtkStatusStack *); +bool load_all_dex_fields(GDexFormat *, wgroup_id_t, GtkStatusStack *);  /* Extrait une représentation de champ d'une table DEX. */  GBinVariable *get_field_from_dex_pool(GDexFormat *, uint32_t); @@ -61,7 +61,7 @@ GBinRoutine *get_prototype_from_dex_pool(GDexFormat *, uint32_t);  GDexMethod *get_method_from_dex_pool(GDexFormat *, uint32_t);  /* Charge toutes les classes listées dans le contenu binaire. */ -bool load_all_dex_classes(GDexFormat *, GtkStatusStack *); +bool load_all_dex_classes(GDexFormat *, wgroup_id_t, GtkStatusStack *);  /* Extrait une représentation de classe d'une table DEX. */  GDexClass *get_class_from_dex_pool(GDexFormat *, uint32_t); diff --git a/src/format/elf/symbols.c b/src/format/elf/symbols.c index cfd0a09..57fb3c1 100644 --- a/src/format/elf/symbols.c +++ b/src/format/elf/symbols.c @@ -763,7 +763,7 @@ static bool load_elf_internal_symbols(GElfFormat *format, wgroup_id_t gid, GtkSt          for (i = 0; i < count; i++)              add_all_symbols_from_section(&symtab_sections[i], no_name, queue, msg); -    g_work_queue_wait_for_completion(get_work_queue(), gid); +    g_work_queue_wait_for_completion(queue, gid);      gtk_status_stack_remove_activity(status, msg); diff --git a/src/format/mangling/dex/type_gram.y b/src/format/mangling/dex/type_gram.y index d5c3f26..506eb9b 100644 --- a/src/format/mangling/dex/type_gram.y +++ b/src/format/mangling/dex/type_gram.y @@ -7,10 +7,10 @@  #include "context.h"  #include "../context-int.h" - +typedef void *yyscan_t;  /* Affiche un message d'erreur concernant l'analyse. */ -static int type_error(GDexDemangler *, char *); +static int type_error(GDexDemangler *, yyscan_t, char *);  /* Procède au décodage d'une chaîne de caractères. */  bool demangle_dex_type(GDexDemangler *, const char *); @@ -36,7 +36,11 @@ bool demangle_dex_type(GDexDemangler *, const char *);  } -%parse-param { GDexDemangler *demangler } + +%define api.pure full +%parse-param { GDexDemangler *demangler } { yyscan_t scanner } +%lex-param { yyscan_t scanner } +  %token V Z B S C I J F D  %token ARRAY @@ -55,9 +59,11 @@ bool demangle_dex_type(GDexDemangler *, const char *);  typedef struct yy_buffer_state *YY_BUFFER_STATE; -extern YY_BUFFER_STATE type__scan_string(const char *); -extern void type__delete_buffer(YY_BUFFER_STATE); -extern int type_lex(void); +extern int type_lex_init(yyscan_t *scanner); +extern YY_BUFFER_STATE type__scan_string(const char *, yyscan_t); +extern void type__delete_buffer(YY_BUFFER_STATE, yyscan_t); +extern int type_lex(YYSTYPE *, yyscan_t); +extern int type_lex_destroy(yyscan_t);  %} @@ -104,6 +110,7 @@ simple_name:  /******************************************************************************  *                                                                             *  *  Paramètres  : demangler = contexte associé à la procédure de décodage.     * +*                scanner   = données internes aux analyseurs.                 *  *                msg       = indications humaines sur l'événement.            *  *                                                                             *  *  Description : Affiche un message d'erreur concernant l'analyse.            * @@ -113,7 +120,7 @@ simple_name:  *  Remarques   : -                                                            *  *                                                                             *  ******************************************************************************/ -static int type_error(GDexDemangler *demangler, char *msg) +static int type_error(GDexDemangler *demangler, yyscan_t scanner, char *msg)  {  	return -1; @@ -135,12 +142,17 @@ static int type_error(GDexDemangler *demangler, char *msg)  bool demangle_dex_type(GDexDemangler *demangler, const char *desc)  { +    yyscan_t scanner;                       /* Données internes            */  	YY_BUFFER_STATE buffer;                 /* Tampon pour bison           */  	int ret;                                /* Bilan de l'appel            */ -	buffer = type__scan_string(desc); -	ret = yyparse(demangler); -	type__delete_buffer(buffer); +    type_lex_init(&scanner); + +    buffer = type__scan_string(desc, scanner); +	ret = yyparse(demangler, scanner); +	type__delete_buffer(buffer, scanner); + +    type_lex_destroy(scanner);      return (ret == 0); diff --git a/src/format/mangling/dex/type_tok.l b/src/format/mangling/dex/type_tok.l index 9c24085..918846a 100644 --- a/src/format/mangling/dex/type_tok.l +++ b/src/format/mangling/dex/type_tok.l @@ -4,13 +4,17 @@  #include "context.h"  #include "libformatmanglingdextype_la-type_gram.h" +/* See lemoda.net/c/reentrant-parser */ +  %}  %option noyywrap  %option yylineno  %option nounput - /*%option noinput*/ +/*%option noinput*/ +%option reentrant +%option bison-bridge  %x string @@ -29,11 +33,11 @@ SIMPLE      {ASCII}|"$"|"-"|"_"  "F"                     { return F; }  "D"                     { return D; }  "L"                     { BEGIN(string); return L; } -"["*                    { type_lval.adeep = strlen(yytext); return ARRAY; } +"["*                    { yylval->adeep = strlen(yytext); return ARRAY; }  <string>"/"             { return SLASH; }  <string>";"             { BEGIN(INITIAL); return SEMICOLON; } -<string>{SIMPLE}*       { type_lval.text = yytext; return TEXT; } +<string>{SIMPLE}*       { yylval->text = yytext; return TEXT; }  <string>.               {                              unsigned char next; @@ -44,7 +48,7 @@ SIMPLE      {ASCII}|"$"|"-"|"_"                                  /* U+00a1 ... U+1fff */                                  case 0x00 ... 0x1f: -                                    next = input(); +                                    next = input(yyscanner);                                      if (yytext[0] == 0x00 && next < 0xa1)                                      { @@ -57,7 +61,7 @@ SIMPLE      {ASCII}|"$"|"-"|"_"                                          mutf8[1] = next;                                          mutf8[2] = '\0'; -                                        strcpy(type_lval.text, mutf8); return TEXT; +                                        strcpy(yylval->text, mutf8); return TEXT;                                      } @@ -66,7 +70,7 @@ SIMPLE      {ASCII}|"$"|"-"|"_"                                  /* U+2010 ... U+2027 / U+2030 ... U+d7ff */                                  case 0x20: -                                    next = input(); +                                    next = input(yyscanner);                                      switch (next)                                      { @@ -77,7 +81,7 @@ SIMPLE      {ASCII}|"$"|"-"|"_"                                              mutf8[1] = next;                                              mutf8[2] = '\0'; -                                            strcpy(type_lval.text, mutf8); return TEXT; +                                            strcpy(yylval->text, mutf8); return TEXT;                                              break;                                          default: @@ -91,19 +95,19 @@ SIMPLE      {ASCII}|"$"|"-"|"_"                                  /* ~ U+2030 ... U+d7ff */                                  case 0x21 ... 0xd7: -                                    next = input(); +                                    next = input(yyscanner);                                      mutf8[0] = yytext[0];                                      mutf8[1] = next;                                      mutf8[2] = '\0'; -                                    strcpy(type_lval.text, mutf8); return TEXT; +                                    strcpy(yylval->text, mutf8); return TEXT;                                      break;                                  /* U+e000 ... U+ffef */                                  case 0xe0 ... 0xff: -                                    next = input(); +                                    next = input(yyscanner);                                      if (yytext[0] == 0xff && next > 0xef)                                      { @@ -116,7 +120,7 @@ SIMPLE      {ASCII}|"$"|"-"|"_"                                          mutf8[1] = next;                                          mutf8[2] = '\0'; -                                        strcpy(type_lval.text, mutf8); return TEXT; +                                        strcpy(yylval->text, mutf8); return TEXT;                                      } @@ -127,11 +131,11 @@ SIMPLE      {ASCII}|"$"|"-"|"_"                                  case 0x10:                                      mutf8[0] = yytext[0]; -                                    mutf8[1] = input(); -                                    mutf8[2] = input(); +                                    mutf8[1] = input(yyscanner); +                                    mutf8[2] = input(yyscanner);                                      mutf8[3] = '\0'; -                                    strcpy(type_lval.text, mutf8); return TEXT; +                                    strcpy(yylval->text, mutf8); return TEXT;                                      break;                                  */ | 
