diff options
Diffstat (limited to 'src/arch')
| -rw-r--r-- | src/arch/arm/v7/post.c | 10 | ||||
| -rw-r--r-- | src/arch/immediate.c | 107 | ||||
| -rw-r--r-- | src/arch/instruction.c | 2 | ||||
| -rw-r--r-- | src/arch/post.c | 10 | ||||
| -rw-r--r-- | src/arch/sharing/instance.c | 10 | ||||
| -rw-r--r-- | src/arch/sharing/manager.c | 75 | ||||
| -rw-r--r-- | src/arch/sharing/manager.h | 6 | ||||
| -rw-r--r-- | src/arch/target.c | 269 | ||||
| -rw-r--r-- | src/arch/target.h | 22 | 
9 files changed, 317 insertions, 194 deletions
| diff --git a/src/arch/arm/v7/post.c b/src/arch/arm/v7/post.c index cfdc3be..4600700 100644 --- a/src/arch/arm/v7/post.c +++ b/src/arch/arm/v7/post.c @@ -48,7 +48,7 @@ void post_process_ldr_instructions(GArchInstruction *instr, GArchProcessor *proc      GArchOperand *op;                       /* Opérande numérique en place */      uint32_t addr;                          /* Adresse visée par le saut   */      GBinFormat *bfmt;                       /* Version basique du format   */ -    GArchOperand *new;                      /* Instruction de ciblage      */ +    GTargetOperand *new;                    /* Instruction de ciblage      */      vmpa2t target;                          /* Défination finale précise   */      mrange_t trange;                        /* Etendue du symbole à créer  */      VMPA_BUFFER(loc);                       /* Espace pour une conversion  */ @@ -68,9 +68,9 @@ void post_process_ldr_instructions(GArchInstruction *instr, GArchProcessor *proc      {          bfmt = G_BIN_FORMAT(format); -        new = g_target_operand_new(MDS_32_BITS_UNSIGNED, &target); +        new = G_TARGET_OPERAND(g_target_operand_new(MDS_32_BITS_UNSIGNED, &target)); -        if (!g_target_operand_resolve(G_TARGET_OPERAND(new), bfmt, true)) +        if (!g_target_operand_resolve(&new, bfmt, true, NULL))          {              addr &= ~0x1; @@ -89,11 +89,11 @@ void post_process_ldr_instructions(GArchInstruction *instr, GArchProcessor *proc              g_binary_symbol_attach_routine(symbol, routine);              g_binary_format_add_symbol(bfmt, symbol); -            g_target_operand_resolve(G_TARGET_OPERAND(new), bfmt, true); +            g_target_operand_resolve(&new, bfmt, true, NULL);          } -        _g_arch_instruction_replace_operand(instr, op, new); +        _g_arch_instruction_replace_operand(instr, op, G_ARCH_OPERAND(new));      } diff --git a/src/arch/immediate.c b/src/arch/immediate.c index 6c52892..6ae7b66 100644 --- a/src/arch/immediate.c +++ b/src/arch/immediate.c @@ -44,6 +44,9 @@ +/* ------------------ MANIPULATION D'OPERANDES DE VALEUR IMMEDIATE ------------------ */ + +  /* Définition d'un opérande de valeur numérique (instance) */  struct _GImmOperand  { @@ -361,8 +364,8 @@ GArchOperand *g_imm_operand_new_from_value(MemoryDataSize size, uint64_t value)  /******************************************************************************  *                                                                             * -*  Paramètres  : operand = objet partagé à initialiser.                       * -*                fake    = coquille vide contenant les infos à enregistrer.   * +*  Paramètres  : operand  = objet partagé à initialiser.                      * +*                template = coquille vide contenant les infos à enregistrer.  *  *                                                                             *  *  Description : Initialise un nouvel objet partagé avec des informations.    *  *                                                                             * @@ -372,14 +375,9 @@ GArchOperand *g_imm_operand_new_from_value(MemoryDataSize size, uint64_t value)  *                                                                             *  ******************************************************************************/ -static bool g_imm_operand_do_init(GImmOperand *operand, const GImmOperand *fake) +static bool g_imm_operand_do_init(GImmOperand *operand, const GImmOperand *template)  { -    operand->raw = fake->raw; -    operand->size = fake->size; - -    operand->zpad = fake->zpad; -    operand->def_display = fake->def_display; -    operand->display = fake->display; +    g_imm_operand_quickly_copy(template, operand);      return true; @@ -629,35 +627,18 @@ uint64_t g_imm_operand_get_raw_value(const GImmOperand *operand)  void g_imm_operand_set_value(GImmOperand **operand, MemoryDataSize size, uint64_t value, GShareContainer *container)  {      GSharedInstance *shared;                /* Instace de travail partagée */ -    size_t index;                           /* Indice du déménagement      */      GImmOperand fake;                       /* Transport d'informations    */      assert(size != MDS_UNDEFINED);      shared = G_SHARED_INSTANCE(*operand); -    if (container == NULL) -    { -        index = g_share_manager_prepare_light_update(_imm_operand_manager, shared); - -        (*operand)->size = size; -        (*operand)->raw = value; - -        shared = g_share_manager_complete_light_update(_imm_operand_manager, shared, index); +    g_shared_instance_quickly_copy(shared, (GSharedInstance *)&fake); -    } - -    else -    { -        g_shared_instance_quickly_copy(shared, (GSharedInstance *)&fake); - -        fake.size = size; -        fake.raw = value; - -        shared = g_share_manager_update(_imm_operand_manager, shared, -                                        (GSharedInstance *)&fake, container); +    fake.size = size; +    fake.raw = value; -    } +    shared = g_share_manager_update(_imm_operand_manager, shared, (GSharedInstance *)&fake, container);      *operand = G_IMM_OPERAND(shared); @@ -681,31 +662,15 @@ void g_imm_operand_set_value(GImmOperand **operand, MemoryDataSize size, uint64_  void g_imm_operand_pad(GImmOperand **operand, bool state, GShareContainer *container)  {      GSharedInstance *shared;                /* Instace de travail partagée */ -    size_t index;                           /* Indice du déménagement      */      GImmOperand fake;                       /* Transport d'informations    */      shared = G_SHARED_INSTANCE(*operand); -    if (container == NULL) -    { -        index = g_share_manager_prepare_light_update(_imm_operand_manager, shared); - -        (*operand)->zpad = state; - -        shared = g_share_manager_complete_light_update(_imm_operand_manager, shared, index); - -    } - -    else -    { -        g_shared_instance_quickly_copy(shared, (GSharedInstance *)&fake); - -        fake.zpad = state; +    g_shared_instance_quickly_copy(shared, (GSharedInstance *)&fake); -        shared = g_share_manager_update(_imm_operand_manager, shared, -                                        (GSharedInstance *)&fake, container); +    fake.zpad = state; -    } +    shared = g_share_manager_update(_imm_operand_manager, shared, (GSharedInstance *)&fake, container);      *operand = G_IMM_OPERAND(shared); @@ -748,31 +713,15 @@ bool g_imm_operand_does_padding(const GImmOperand *operand)  void g_imm_operand_set_default_display(GImmOperand **operand, ImmOperandDisplay display, GShareContainer *container)  {      GSharedInstance *shared;                /* Instace de travail partagée */ -    size_t index;                           /* Indice du déménagement      */      GImmOperand fake;                       /* Transport d'informations    */      shared = G_SHARED_INSTANCE(*operand); -    if (container == NULL) -    { -        index = g_share_manager_prepare_light_update(_imm_operand_manager, shared); - -        (*operand)->def_display = display; - -        shared = g_share_manager_complete_light_update(_imm_operand_manager, shared, index); +    g_shared_instance_quickly_copy(shared, (GSharedInstance *)&fake); -    } - -    else -    { -        g_shared_instance_quickly_copy(shared, (GSharedInstance *)&fake); - -        fake.def_display = display; +    fake.def_display = display; -        shared = g_share_manager_update(_imm_operand_manager, shared, -                                        (GSharedInstance *)&fake, container); - -    } +    shared = g_share_manager_update(_imm_operand_manager, shared, (GSharedInstance *)&fake, container);      *operand = G_IMM_OPERAND(shared); @@ -815,31 +764,15 @@ ImmOperandDisplay g_imm_operand_get_default_display(const GImmOperand *operand)  void g_imm_operand_set_display(GImmOperand **operand, ImmOperandDisplay display, GShareContainer *container)  {      GSharedInstance *shared;                /* Instace de travail partagée */ -    size_t index;                           /* Indice du déménagement      */      GImmOperand fake;                       /* Transport d'informations    */      shared = G_SHARED_INSTANCE(*operand); -    if (container == NULL) -    { -        index = g_share_manager_prepare_light_update(_imm_operand_manager, shared); - -        (*operand)->display = display; +    g_shared_instance_quickly_copy(shared, (GSharedInstance *)&fake); -        shared = g_share_manager_complete_light_update(_imm_operand_manager, shared, index); +    fake.display = display; -    } - -    else -    { -        g_shared_instance_quickly_copy(shared, (GSharedInstance *)&fake); - -        fake.display = display; - -        shared = g_share_manager_update(_imm_operand_manager, shared, -                                        (GSharedInstance *)&fake, container); - -    } +    shared = g_share_manager_update(_imm_operand_manager, shared, (GSharedInstance *)&fake, container);      *operand = G_IMM_OPERAND(shared); diff --git a/src/arch/instruction.c b/src/arch/instruction.c index a2ba138..a9bc4f2 100644 --- a/src/arch/instruction.c +++ b/src/arch/instruction.c @@ -643,7 +643,7 @@ bool _g_arch_instruction_replace_operand(GArchInstruction *instr, GArchOperand *      {          rpl_item_in_flat_array(instr->operands, i, &new, sizeof(GArchOperand *)); -        g_object_unref(G_OBJECT(old)); +        //g_object_unref(G_OBJECT(old));      } diff --git a/src/arch/post.c b/src/arch/post.c index 184430d..1463709 100644 --- a/src/arch/post.c +++ b/src/arch/post.c @@ -55,7 +55,7 @@ void post_process_target_resolution(GArchInstruction *instr, GArchProcessor *pro      virt_t addr;                            /* Adresse visée par le saut   */      GBinFormat *bfmt;                       /* Version basique du format   */      MemoryDataSize ptr_size;                /* Taille de l'espace mémoire  */ -    GArchOperand *new;                      /* Instruction de ciblage      */ +    GTargetOperand *new;                    /* Instruction de ciblage      */      vmpa2t target;                          /* Emplacement de la cible     */      mrange_t trange;                        /* Etendue du symbole à créer  */      VMPA_BUFFER(loc);                       /* Conversion en chaîne        */ @@ -75,9 +75,9 @@ void post_process_target_resolution(GArchInstruction *instr, GArchProcessor *pro          ptr_size = g_arch_processor_get_memory_size(proc); -        new = g_target_operand_new(ptr_size, &target); +        new = G_TARGET_OPERAND(g_target_operand_new(ptr_size, &target)); -        if (!g_target_operand_resolve(G_TARGET_OPERAND(new), bfmt, true)) +        if (!g_target_operand_resolve(&new, bfmt, true, NULL))          {              vmpa2_to_string(&target, MDS_UNDEFINED, loc, NULL); @@ -107,11 +107,11 @@ void post_process_target_resolution(GArchInstruction *instr, GArchProcessor *pro              g_binary_symbol_attach_routine(symbol, routine);              g_binary_format_add_symbol(bfmt, symbol); -            g_target_operand_resolve(G_TARGET_OPERAND(new), bfmt, true); +            g_target_operand_resolve(&new, bfmt, true, NULL);          } -        _g_arch_instruction_replace_operand(instr, op, new); +        _g_arch_instruction_replace_operand(instr, op, G_ARCH_OPERAND(new));      } diff --git a/src/arch/sharing/instance.c b/src/arch/sharing/instance.c index c0038aa..39dacec 100644 --- a/src/arch/sharing/instance.c +++ b/src/arch/sharing/instance.c @@ -78,6 +78,11 @@ bool g_shared_instance_init(GSharedInstance *instance, const GSharedInstance *te      iface = G_SHARED_INSTANCE_GET_IFACE(instance); +    /** +     * Le compteur de références des objets GLib doit être incrémenté ici, +     * à la différence d'une opération de copie minimaliste. +     */ +      result = iface->init(instance, template);      return result; @@ -104,6 +109,11 @@ void g_shared_instance_quickly_copy(const GSharedInstance *instance, GSharedInst      iface = G_SHARED_INSTANCE_GET_IFACE(instance); +    /** +     * Le compteur de références des objets GLib ne doit pas être incrémenté ici. +     * Ce genre de traitement est réservé à la phase d'initialisation. +     */ +      iface->qck_copy(instance, template);  } diff --git a/src/arch/sharing/manager.c b/src/arch/sharing/manager.c index 952fc33..3b7cd01 100644 --- a/src/arch/sharing/manager.c +++ b/src/arch/sharing/manager.c @@ -283,7 +283,7 @@ GSharedInstance *g_share_manager_update(GShareManager *manager, GSharedInstance      if (container != NULL)          replaced = g_share_container_replace(container, old, result);      else -        replaced = false; +        replaced = true;      if (replaced)          g_share_manager_put(manager, old); @@ -301,79 +301,6 @@ GSharedInstance *g_share_manager_update(GShareManager *manager, GSharedInstance  /******************************************************************************  *                                                                             * -*  Paramètres  : manager  = gestionnaire d'instance à consulter.              * -*                instance = instance partagée vouée à évoluer.                * -*                                                                             * -*  Description : Prépare une modification légère et locale d'un élément.      * -*                                                                             * -*  Retour      : Indice de l'élément prêt à être modifié.                     * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -size_t g_share_manager_prepare_light_update(GShareManager *manager, GSharedInstance *instance) -{ -    size_t result;                          /* Indice courant à retourner  */ -#ifndef NDEBUG -    bool found;                             /* Validation de présence      */ -#endif - -    g_mutex_lock(&manager->access); - -#ifndef NDEBUG - -    found = bsearch_index(&instance, manager->instances, manager->count,sizeof(GSharedInstance *), -                          (__compar_fn_t)g_shared_instance_quickly_compare, &result); - -    assert(found); - -#else - -    bsearch_index(&instance, manager->instances, manager->count,sizeof(GSharedInstance *), -                  (__compar_fn_t)g_shared_instance_quickly_compare, &result); - -#endif - -    return result; - -} - - -/****************************************************************************** -*                                                                             * -*  Paramètres  : manager  = gestionnaire d'instance à consulter.              * -*                instance = instance partagée vouée à évoluer.                * -*                index    = indice de la place de l'élément avant modifcation.* -*                                                                             * -*  Description : Conclut une modification légère et locale d'un élément.      * -*                                                                             * -*  Retour      : Indice de l'élément prêt à être modifié.                     * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -GSharedInstance *g_share_manager_complete_light_update(GShareManager *manager, GSharedInstance *instance, size_t index) -{ -    GSharedInstance *result;                /* Nouvelle instance à renvoyer*/ - -    manager->instances = _qdelete(manager->instances, &manager->count, -                                  sizeof(GSharedInstance *), index); - -    g_mutex_unlock(&manager->access); - -    result = g_share_manager_get(manager, instance); - -    g_object_unref(G_OBJECT(instance)); - -    return result; - -} - - -/****************************************************************************** -*                                                                             *  *  Paramètres  : manager = gestionnaire d'instance à consulter.               *  *                shared  = instance partagée à libérer.                       *  *                                                                             * diff --git a/src/arch/sharing/manager.h b/src/arch/sharing/manager.h index f2fcea6..959087d 100644 --- a/src/arch/sharing/manager.h +++ b/src/arch/sharing/manager.h @@ -65,12 +65,6 @@ GSharedInstance *g_share_manager_get(GShareManager *, GSharedInstance *);  /* Met à jour une instance partagée. */  GSharedInstance *g_share_manager_update(GShareManager *, GSharedInstance *, GSharedInstance *, GShareContainer *); -/* Prépare une modification légère et locale d'un élément. */ -size_t g_share_manager_prepare_light_update(GShareManager *, GSharedInstance *); - -/* Conclut une modification légère et locale d'un élément. */ -GSharedInstance *g_share_manager_complete_light_update(GShareManager *, GSharedInstance *, size_t); -  /* Abandonne un usage d'une instance partagée. */  void g_share_manager_put(GShareManager *, GSharedInstance *); diff --git a/src/arch/target.c b/src/arch/target.c index 896b9f7..a863d69 100644 --- a/src/arch/target.c +++ b/src/arch/target.c @@ -33,11 +33,15 @@  #include "operand-int.h" +#include "sharing/manager.h"  #include "../common/extstr.h"  #include "../format/format.h" +/* ------------------------ GESTION DES OPERANDES DE CIBLAGE ------------------------ */ + +  /* Définition d'un opérande ciblant idéalement un symbole connu (instance) */  struct _GTargetOperand  { @@ -72,6 +76,15 @@ static void g_target_operand_dispose(GTargetOperand *);  /* Procède à la libération totale de la mémoire. */  static void g_target_operand_finalize(GTargetOperand *); +/* Initialise un nouvel objet partagé avec des informations. */ +static bool g_target_operand_do_init(GTargetOperand *, const GTargetOperand *); + +/* Réalise une copie minimale d'un contenu partagé. */ +static void g_target_operand_quickly_copy(const GTargetOperand *, GTargetOperand *); + +/* Compare un opérande avec un autre. */ +static int g_target_operand_compare(const GTargetOperand * const *, const GTargetOperand * const *); +  /* Traduit un opérande en version humainement lisible. */  static void g_target_operand_print(const GTargetOperand *, GBufferLine *, AsmSyntax); @@ -80,6 +93,19 @@ static char *g_target_operand_build_tooltip(const GTargetOperand *, const GLoade +/* -------------------------- PARTAGES DE CONTENUS UNIQUES -------------------------- */ + + +/* Gestionnaire des partages d'instances */ +static GShareManager *_target_operand_manager = NULL; + + + +/* ---------------------------------------------------------------------------------- */ +/*                          GESTION DES OPERANDES DE CIBLAGE                          */ +/* ---------------------------------------------------------------------------------- */ + +  /* Indique le type défini pour un opérande de valeur numérique. */  G_DEFINE_TYPE(GTargetOperand, g_target_operand, G_TYPE_ARCH_OPERAND); @@ -108,6 +134,10 @@ static void g_target_operand_class_init(GTargetOperandClass *klass)      object->dispose = (GObjectFinalizeFunc/* ! */)g_target_operand_dispose;      object->finalize = (GObjectFinalizeFunc)g_target_operand_finalize; +    operand->init = (operand_do_init_fc)g_target_operand_do_init; +    operand->qck_copy = (operand_qck_copy_fc)g_target_operand_quickly_copy; + +    operand->compare = (operand_compare_fc)g_target_operand_compare;      operand->print = (operand_print_fc)g_target_operand_print;      operand->build_tooltip = (operand_build_tooltip_fc)g_target_operand_build_tooltip; @@ -128,6 +158,11 @@ static void g_target_operand_class_init(GTargetOperandClass *klass)  static void g_target_operand_init(GTargetOperand *operand)  { +    operand->size = MDS_UNDEFINED; +    init_vmpa(&operand->addr, VMPA_NO_PHYSICAL, VMPA_NO_VIRTUAL); + +    operand->symbol = NULL; +    operand->diff = 0;  } @@ -146,6 +181,8 @@ static void g_target_operand_init(GTargetOperand *operand)  static void g_target_operand_dispose(GTargetOperand *operand)  { +    printf(" !! dispose %p\n", operand); +      if (operand->symbol != NULL)          g_object_unref(G_OBJECT(operand->symbol)); @@ -188,14 +225,139 @@ static void g_target_operand_finalize(GTargetOperand *operand)  GArchOperand *g_target_operand_new(MemoryDataSize size, const vmpa2t *addr)  { -    GTargetOperand *result;                 /* Opérande à retourner        */ +    GArchOperand *result;                   /* Opérande à retourner        */ +    GTargetOperand fake;                    /* Transport d'informations    */ + +    g_target_operand_init(&fake); + +    fake.size = size; +    copy_vmpa(&fake.addr, addr); + +    result = G_ARCH_OPERAND(g_share_manager_get(_target_operand_manager, (GSharedInstance *)&fake)); + +    return result; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : operand  = objet partagé à initialiser.                      * +*                template = coquille vide contenant les infos à enregistrer.  * +*                                                                             * +*  Description : Initialise un nouvel objet partagé avec des informations.    * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static bool g_target_operand_do_init(GTargetOperand *operand, const GTargetOperand *template) +{ +    g_target_operand_quickly_copy(template, operand); + +    if (operand->symbol != NULL) +        g_object_ref(G_OBJECT(operand->symbol)); + +    return true; + +} + -    result = g_object_new(G_TYPE_TARGET_OPERAND, NULL); +/****************************************************************************** +*                                                                             * +*  Paramètres  : operand  = objet partagé à consulter.                        * +*                template = informations à retrouver intégralement.           * +*                                                                             * +*  Description : Réalise une copie minimale d'un contenu partagé.             * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ -    result->size = size; -    copy_vmpa(&result->addr, addr); +static void g_target_operand_quickly_copy(const GTargetOperand *operand, GTargetOperand *template) +{ +    template->size = operand->size; +    copy_vmpa(&template->addr, &operand->addr); -    return G_ARCH_OPERAND(result); +    template->symbol = operand->symbol; +    template->diff = operand->diff; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : a = premier opérande à consulter.                            * +*                b = second opérande à consulter.                             * +*                                                                             * +*  Description : Compare un opérande avec un autre.                           * +*                                                                             * +*  Retour      : Bilan de la comparaison.                                     * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static int g_target_operand_compare(const GTargetOperand * const *a, const GTargetOperand * const *b) +{ +    int result;                             /* Bilan à retourner           */ +    const GTargetOperand *target_a;         /* Accès simplifié à A         */ +    const GTargetOperand *target_b;         /* Accès simplifié à B         */ + +    target_a = *a; +    target_b = *b; + +    result = cmp_vmpa(&target_a->addr, &target_b->addr); +    if (result != 0) goto gtoc_done; + +    if (target_a->size < target_b->size) +    { +        result = -1; +        goto gtoc_done; +    } +    else if (target_a->size > target_b->size) +    { +        result = 1; +        goto gtoc_done; +    } + +    if (target_a->symbol == NULL && target_b->symbol != NULL) +    { +        result = -1; +        goto gtoc_done; +    } +    else if (target_a->symbol != NULL && target_b->symbol == NULL) +    { +        result = 1; +        goto gtoc_done; +    } +    else if (target_a->symbol != NULL && target_b->symbol != NULL) +    { +        result = g_binary_symbol_cmp((const GBinSymbol * []) { target_a->symbol }, +                                     (const GBinSymbol * []) { target_b->symbol }); +        if (result != 0) goto gtoc_done; +    } + +    if (target_a->diff < target_b->diff) +    { +        result = -1; +        goto gtoc_done; +    } +    else if (target_a->diff > target_b->diff) +    { +        result = 1; +        goto gtoc_done; +    } + +    result = 0; + + gtoc_done: + +    return result;  } @@ -372,9 +534,10 @@ void g_target_operand_get_addr(const GTargetOperand *operand, vmpa2t *addr)  /******************************************************************************  *                                                                             * -*  Paramètres  : operand = opérande dont le contenu est à raffiner.           * -*                format  = format du binaire d'origine à consulter.           * -*                strict  = indique si la résolution doit être parfaite ou non.* +*  Paramètres  : operand   = opérande dont le contenu est à raffiner. [OUT]   * +*                format    = format du binaire d'origine à consulter.         * +*                strict    = indique la perfection attendue de la résolution. * +*                container = propriétaire d'origine à tenir au courant.       *  *                                                                             *  *  Description : Tente une résolution de symbole.                             *  *                                                                             * @@ -384,18 +547,28 @@ void g_target_operand_get_addr(const GTargetOperand *operand, vmpa2t *addr)  *                                                                             *  ******************************************************************************/ -bool g_target_operand_resolve(GTargetOperand *operand, GBinFormat *format, bool strict) +bool g_target_operand_resolve(GTargetOperand **operand, GBinFormat *format, bool strict, GShareContainer *container)  {      bool result;                            /* Bilan à retourner           */ +    GSharedInstance *shared;                /* Instace de travail partagée */ +    GTargetOperand fake;                    /* Transport d'informations    */      GBinSymbol *symbol;                     /* Facilités d'accès au symbole*/      SymbolType stype;                       /* Type de symbole trouvé      */      const mrange_t *range;                  /* Couverture du symbole       */      char *label;                            /* Désignation de la chaîne    */ -    if (operand->symbol != NULL) -        g_object_unref(G_OBJECT(operand->symbol)); +    shared = G_SHARED_INSTANCE(*operand); + +    g_shared_instance_quickly_copy(shared, (GSharedInstance *)&fake); + +    result = g_binary_format_resolve_symbol(format, &fake.addr, strict, &fake.symbol, &fake.diff); + +    shared = g_share_manager_update(_target_operand_manager, shared, (GSharedInstance *)&fake, container); + +    if (fake.symbol != NULL) +        g_object_unref(G_OBJECT(fake.symbol)); -    result = g_binary_format_resolve_symbol(format, &operand->addr, strict, &operand->symbol, &operand->diff); +    *operand = G_TARGET_OPERAND(shared);      /**       * Si plusieurs chaînes se suivent, la seconde et les suivantes bénéficient @@ -409,9 +582,9 @@ bool g_target_operand_resolve(GTargetOperand *operand, GBinFormat *format, bool       * attribue à cette ligne une étiquette propre.       */ -    if (result && operand->diff == 0) +    if (result && (*operand)->diff == 0)      { -        symbol = operand->symbol; +        symbol = (*operand)->symbol;          stype = g_binary_symbol_get_target_type(symbol); @@ -421,7 +594,7 @@ bool g_target_operand_resolve(GTargetOperand *operand, GBinFormat *format, bool              {                  range = g_binary_symbol_get_range(symbol); -                assert(cmp_vmpa(&operand->addr, get_mrange_addr(range)) == 0); +                assert(cmp_vmpa(&(*operand)->addr, get_mrange_addr(range)) == 0);                  label = create_string_label(format, get_mrange_addr(range), get_mrange_length(range)); @@ -468,3 +641,69 @@ GBinSymbol *g_target_operand_get_symbol(const GTargetOperand *operand, phys_t *d      return result;  } + + + +/* ---------------------------------------------------------------------------------- */ +/*                            PARTAGES DE CONTENUS UNIQUES                            */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : -                                                            * +*                                                                             * +*  Description : Initialise les mécanismes de partage d'opérandes de ciblage. * +*                                                                             * +*  Retour      : Bilan de l'opération.                                        * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool init_target_operand_sharing(void) +{ +    _target_operand_manager = g_share_manager_new(G_TYPE_TARGET_OPERAND); + +    return true; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : -                                                            * +*                                                                             * +*  Description : Imprime des statistiques quant aux partages dans l'archi.    * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ +#ifdef DEBUG_DUMP_STATS +void dump_target_operand_share_stats(void) +{ +    g_share_manager_dump_stats(_target_operand_manager); + +} +#endif + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : -                                                            * +*                                                                             * +*  Description : Supprime les mécanismes de partage des opérandes de ciblage. * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void exit_target_operand_sharing(void) +{ +    g_object_unref(G_OBJECT(_target_operand_manager)); + +} diff --git a/src/arch/target.h b/src/arch/target.h index 529dba8..affe59e 100644 --- a/src/arch/target.h +++ b/src/arch/target.h @@ -32,10 +32,14 @@  #include "archbase.h"  #include "operand.h"  #include "vmpa.h" +#include "sharing/container.h"  #include "../format/format.h" +/* ------------------------ GESTION DES OPERANDES DE CIBLAGE ------------------------ */ + +  #define G_TYPE_TARGET_OPERAND               g_target_operand_get_type()  #define G_TARGET_OPERAND(obj)               (G_TYPE_CHECK_INSTANCE_CAST((obj), g_target_operand_get_type(), GTargetOperand))  #define G_IS_TARGET_OPERAND(obj)            (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_target_operand_get_type())) @@ -64,11 +68,27 @@ MemoryDataSize g_target_operand_get_size(const GTargetOperand *);  void g_target_operand_get_addr(const GTargetOperand *, vmpa2t *);  /* Tente une résolution de symbole. */ -bool g_target_operand_resolve(GTargetOperand *, GBinFormat *, bool); +bool g_target_operand_resolve(GTargetOperand **, GBinFormat *, bool, GShareContainer *);  /* Fournit les indications concernant le symbole associé. */  GBinSymbol *g_target_operand_get_symbol(const GTargetOperand *, phys_t *); +/* -------------------------- PARTAGES DE CONTENUS UNIQUES -------------------------- */ + + +/* Initialise les mécanismes de partage des opérandes de ciblage. */ +bool init_target_operand_sharing(void); + +/* Imprime des statistiques quant aux partages dans l'archi. */ +#ifdef DEBUG_DUMP_STATS +void dump_target_operand_share_stats(void); +#endif + +/* Supprime les mécanismes de partage des opérandes de ciblage. */ +void exit_target_operand_sharing(void); + + +  #endif  /* _ARCH_TARGET_H */ | 
