diff options
Diffstat (limited to 'src/arch')
| -rw-r--r-- | src/arch/arm/v7/fetch.c | 15 | ||||
| -rw-r--r-- | src/arch/arm/v7/post.c | 13 | ||||
| -rw-r--r-- | src/arch/dalvik/link.c | 8 | ||||
| -rw-r--r-- | src/arch/instruction-int.h | 1 | ||||
| -rw-r--r-- | src/arch/instruction.c | 147 | ||||
| -rw-r--r-- | src/arch/instruction.h | 58 | ||||
| -rw-r--r-- | src/arch/link.c | 24 | ||||
| -rw-r--r-- | src/arch/post.c | 8 | ||||
| -rw-r--r-- | src/arch/raw.c | 8 | 
9 files changed, 214 insertions, 68 deletions
diff --git a/src/arch/arm/v7/fetch.c b/src/arch/arm/v7/fetch.c index 15707e3..6675706 100644 --- a/src/arch/arm/v7/fetch.c +++ b/src/arch/arm/v7/fetch.c @@ -388,13 +388,16 @@ void help_fetching_with_instruction_ldr_literal_with_orig(GArchInstruction *inst              break;      } -    op = g_arch_instruction_get_operand(instr, 1); +    g_arch_instruction_lock_operands(instr); + +    op = _g_arch_instruction_get_operand(instr, 1);      assert(G_IS_IMM_OPERAND(op));      ret = g_imm_operand_get_value(G_IMM_OPERAND(op), MDS_32_BITS_UNSIGNED, &offset);      if (!ret)      {          assert(0); +        g_arch_instruction_unlock_operands(instr);          return;      } @@ -405,6 +408,7 @@ void help_fetching_with_instruction_ldr_literal_with_orig(GArchInstruction *inst      if (!g_exe_format_translate_offset_into_vmpa(format, val_offset, &sym_addr))      {          assert(0); +        g_arch_instruction_unlock_operands(instr);          return;      } @@ -427,7 +431,11 @@ void help_fetching_with_instruction_ldr_literal_with_orig(GArchInstruction *inst      ret = g_binary_content_read_u32(content, &pos, SRE_LITTLE /* FIXME */, &target);      g_object_unref(G_OBJECT(content)); -    if (!ret) return; +    if (!ret) +    { +        g_arch_instruction_unlock_operands(instr); +        return; +    }      /* Réalise l'intégration du symbole associé */ @@ -480,8 +488,9 @@ void help_fetching_with_instruction_ldr_literal_with_orig(GArchInstruction *inst      new = g_imm_operand_new_from_value(MDS_32_BITS_UNSIGNED, target); -    g_arch_instruction_replace_operand(instr, new, op); +    _g_arch_instruction_replace_operand(instr, new, op); +    g_arch_instruction_unlock_operands(instr); diff --git a/src/arch/arm/v7/post.c b/src/arch/arm/v7/post.c index 5ac3c62..6c63832 100644 --- a/src/arch/arm/v7/post.c +++ b/src/arch/arm/v7/post.c @@ -56,11 +56,12 @@ void post_process_ldr_instructions(GArchInstruction *instr, GArchProcessor *proc      GBinRoutine *routine;                   /* Nouvelle routine trouvée    */      GBinSymbol *symbol;                     /* Nouveau symbole construit   */ -    op = g_arch_instruction_get_operand(instr, 1); +    g_arch_instruction_lock_operands(instr); +    op = _g_arch_instruction_get_operand(instr, 1); -    if (!G_IS_IMM_OPERAND(op)) return; - +    if (!G_IS_IMM_OPERAND(op)) +        goto ppli_release;      if (g_imm_operand_get_value(G_IMM_OPERAND(op), MDS_32_BITS_UNSIGNED, &addr)          && g_exe_format_translate_address_into_vmpa(format, addr, &target)) @@ -92,8 +93,12 @@ void post_process_ldr_instructions(GArchInstruction *instr, GArchProcessor *proc          } -        g_arch_instruction_replace_operand(instr, new, op); +        _g_arch_instruction_replace_operand(instr, new, op);      } + ppli_release: + +    g_arch_instruction_unlock_operands(instr); +  } diff --git a/src/arch/dalvik/link.c b/src/arch/dalvik/link.c index f92541b..d1404d0 100644 --- a/src/arch/dalvik/link.c +++ b/src/arch/dalvik/link.c @@ -101,9 +101,13 @@ void handle_dalvik_packed_switch_links(GArchInstruction *instr, GArchProcessor *      char *int_val;                          /* Valeur en chaîne de carac.  */      GDbComment *item;                       /* Indication sur la condition */ -    assert(g_arch_instruction_count_operands(instr) == 2); +    g_arch_instruction_lock_operands(instr); -    op = g_arch_instruction_get_operand(instr, 1); +    assert(_g_arch_instruction_count_operands(instr) == 2); + +    op = _g_arch_instruction_get_operand(instr, 1); + +    g_arch_instruction_unlock_operands(instr);      defined = false; diff --git a/src/arch/instruction-int.h b/src/arch/instruction-int.h index 5f6758f..8dbdd18 100644 --- a/src/arch/instruction-int.h +++ b/src/arch/instruction-int.h @@ -56,6 +56,7 @@ struct _GArchInstruction      GArchOperand **operands;                /* Liste des opérandes         */      size_t operands_count;                  /* Nbre. d'opérandes utilisées */ +    gint operands_lock;                     /* Verrouillage des accès      */      /**       * Il existe le besoin indéniable d'un verrou pour les accès aux instructions diff --git a/src/arch/instruction.c b/src/arch/instruction.c index 7df72bf..339364f 100644 --- a/src/arch/instruction.c +++ b/src/arch/instruction.c @@ -145,6 +145,8 @@ static void g_arch_instruction_class_init(GArchInstructionClass *klass)  static void g_arch_instruction_init(GArchInstruction *instr)  { +    instr->operands_lock = 0; +      instr->from_count = 0;      instr->to_count = 0; @@ -409,6 +411,91 @@ void g_arch_instruction_get_location(const GArchInstruction *instr, off_t *offse  } + +/****************************************************************************** +*                                                                             * +*  Paramètres  : instr  = instruction à consulter.                            * +*                rregs  = liste des rgistres lus. [OUT]                       * +*                rcount = nombre de registres lus. [OUT]                      * +*                wregs  = liste des rgistres écrits. [OUT]                    * +*                wcount = nombre de registres écrits. [OUT]                   * +*                                                                             * +*  Description : Liste les registres lus et écrits par l'instruction.         * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : Les compteurs de références sont à décrémenter après usage ! * +*                                                                             * +******************************************************************************/ + +void g_arch_instruction_get_rw_registers(const GArchInstruction *instr, GArchRegister ***rregs, size_t *rcount, GArchRegister ***wregs, size_t *wcount) +{ +#if 0 + +    size_t i;                               /* Boucle de parcours          */ + +    *rregs = NULL; +    *rcount = 0; +    *wregs = NULL; +    *wcount = 0; + +    instr->get_rw_regs(instr, rregs, rcount, wregs, wcount); + +    for (i = 0; i < *rcount; i++) +        g_object_ref(G_OBJECT((*rregs)[i])); + +    for (i = 0; i < *wcount; i++) +        g_object_ref(G_OBJECT((*wregs)[i])); + +#endif + +} + + + +/* ---------------------------------------------------------------------------------- */ +/*                             MANIPULATION DES OPERANDES                             */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : instr = instruction à mettre à jour.                         * +*                                                                             * +*  Description : Verrouille les accès la liste des opérandes.                 * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void g_arch_instruction_lock_operands(GArchInstruction *instr) +{ +    g_bit_lock(&instr->operands_lock, 0); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : instr = instruction à mettre à jour.                         * +*                                                                             * +*  Description : Déverrouille les accès la liste des opérandes.               * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void g_arch_instruction_unlock_operands(GArchInstruction *instr) +{ +    g_bit_unlock(&instr->operands_lock, 0); + +} + +  /******************************************************************************  *                                                                             *  *  Paramètres  : instr     = instance à mettre à jour.                        * @@ -424,11 +511,15 @@ void g_arch_instruction_get_location(const GArchInstruction *instr, off_t *offse  void g_arch_instruction_attach_extra_operand(GArchInstruction *instr, GArchOperand *operand)  { +    g_arch_instruction_lock_operands(instr); +      instr->operands_count++;      instr->operands = (GArchOperand **)realloc(instr->operands, instr->operands_count * sizeof(GArchOperand *));      instr->operands[instr->operands_count - 1] = operand; +    g_arch_instruction_unlock_operands(instr); +  } @@ -444,8 +535,10 @@ void g_arch_instruction_attach_extra_operand(GArchInstruction *instr, GArchOpera  *                                                                             *  ******************************************************************************/ -size_t g_arch_instruction_count_operands(const GArchInstruction *instr) +size_t _g_arch_instruction_count_operands(const GArchInstruction *instr)  { +    assert(instr->operands_lock != 0); +      return instr->operands_count;  } @@ -464,10 +557,12 @@ size_t g_arch_instruction_count_operands(const GArchInstruction *instr)  *                                                                             *  ******************************************************************************/ -GArchOperand *g_arch_instruction_get_operand(const GArchInstruction *instr, size_t index) +GArchOperand *_g_arch_instruction_get_operand(const GArchInstruction *instr, size_t index)  {      GArchOperand *result;                   /* Opérande à retourner        */ +    assert(instr->operands_lock != 0); +      if (index >= instr->operands_count) result = NULL;      else result = instr->operands[index]; @@ -492,10 +587,12 @@ GArchOperand *g_arch_instruction_get_operand(const GArchInstruction *instr, size  *                                                                             *  ******************************************************************************/ -void g_arch_instruction_replace_operand(GArchInstruction *instr, GArchOperand *new, const GArchOperand *old) +void _g_arch_instruction_replace_operand(GArchInstruction *instr, GArchOperand *new, const GArchOperand *old)  {      size_t i;                               /* Boucle de parcours          */ +    assert(instr->operands_lock != 0); +      for (i = 0; i < instr->operands_count; i++)          if (instr->operands[i] == old)              break; @@ -522,10 +619,12 @@ void g_arch_instruction_replace_operand(GArchInstruction *instr, GArchOperand *n  *                                                                             *  ******************************************************************************/ -void g_arch_instruction_detach_operand(GArchInstruction *instr, GArchOperand *operand) +void _g_arch_instruction_detach_operand(GArchInstruction *instr, GArchOperand *operand)  {      size_t i;                               /* Boucle de parcours          */ +    assert(instr->operands_lock != 0); +      for (i = 0; i < instr->operands_count; i++)          if (instr->operands[i] == operand)              break; @@ -540,46 +639,6 @@ void g_arch_instruction_detach_operand(GArchInstruction *instr, GArchOperand *op  } -/****************************************************************************** -*                                                                             * -*  Paramètres  : instr  = instruction à consulter.                            * -*                rregs  = liste des rgistres lus. [OUT]                       * -*                rcount = nombre de registres lus. [OUT]                      * -*                wregs  = liste des rgistres écrits. [OUT]                    * -*                wcount = nombre de registres écrits. [OUT]                   * -*                                                                             * -*  Description : Liste les registres lus et écrits par l'instruction.         * -*                                                                             * -*  Retour      : -                                                            * -*                                                                             * -*  Remarques   : Les compteurs de références sont à décrémenter après usage ! * -*                                                                             * -******************************************************************************/ - -void g_arch_instruction_get_rw_registers(const GArchInstruction *instr, GArchRegister ***rregs, size_t *rcount, GArchRegister ***wregs, size_t *wcount) -{ -#if 0 - -    size_t i;                               /* Boucle de parcours          */ - -    *rregs = NULL; -    *rcount = 0; -    *wregs = NULL; -    *wcount = 0; - -    instr->get_rw_regs(instr, rregs, rcount, wregs, wcount); - -    for (i = 0; i < *rcount; i++) -        g_object_ref(G_OBJECT((*rregs)[i])); - -    for (i = 0; i < *wcount; i++) -        g_object_ref(G_OBJECT((*wregs)[i])); - -#endif - -} - -  /* ---------------------------------------------------------------------------------- */  /*                     DEFINITION DES LIAISONS ENTRE INSTRUCTIONS                     */ diff --git a/src/arch/instruction.h b/src/arch/instruction.h index 6388f94..fad6c72 100644 --- a/src/arch/instruction.h +++ b/src/arch/instruction.h @@ -123,23 +123,67 @@ void g_arch_instruction_get_location(const GArchInstruction *, off_t *, off_t *, +/* Liste les registres lus et écrits par l'instruction. */ +void g_arch_instruction_get_rw_registers(const GArchInstruction *, GArchRegister ***, size_t *, GArchRegister ***, size_t *) __attribute__ ((deprecated)); + + + +/* --------------------------- MANIPULATION DES OPERANDES --------------------------- */ + + +/* Verrouille les accès la liste des opérandes. */ +void g_arch_instruction_lock_operands(GArchInstruction *); + +/* Déverrouille les accès la liste des opérandes. */ +void g_arch_instruction_unlock_operands(GArchInstruction *); +  /* Attache un opérande supplémentaire à une instruction. */  void g_arch_instruction_attach_extra_operand(GArchInstruction *, GArchOperand *);  /* Indique la quantité d'opérandes présents dans l'instruction. */ -size_t g_arch_instruction_count_operands(const GArchInstruction *); +size_t _g_arch_instruction_count_operands(const GArchInstruction *);  /* Fournit un opérande donné d'une instruction. */ -GArchOperand *g_arch_instruction_get_operand(const GArchInstruction *, size_t); +GArchOperand *_g_arch_instruction_get_operand(const GArchInstruction *, size_t);  /* Remplace un opérande d'une instruction par un autre. */ -void g_arch_instruction_replace_operand(GArchInstruction *, GArchOperand *, const GArchOperand *); +void _g_arch_instruction_replace_operand(GArchInstruction *, GArchOperand *, const GArchOperand *);  /* Détache un opérande liée d'une instruction. */ -void g_arch_instruction_detach_operand(GArchInstruction *, GArchOperand *); - -/* Liste les registres lus et écrits par l'instruction. */ -void g_arch_instruction_get_rw_registers(const GArchInstruction *, GArchRegister ***, size_t *, GArchRegister ***, size_t *) __attribute__ ((deprecated)); +void _g_arch_instruction_detach_operand(GArchInstruction *, GArchOperand *); + + +#define g_arch_instruction_count_operands(ins)                  \ +    ({                                                          \ +        size_t __result;                                        \ +        g_arch_instruction_lock_operands(ins);                  \ +        __result = _g_arch_instruction_count_operands(ins);     \ +        g_arch_instruction_unlock_operands(ins);                \ +        __result;                                               \ +    }) + +#define g_arch_instruction_get_operand(ins, idx)                \ +    ({                                                          \ +        GArchOperand *__result;                                 \ +        g_arch_instruction_lock_operands(ins);                  \ +        __result = _g_arch_instruction_get_operand(ins, idx);   \ +        g_arch_instruction_unlock_operands(ins);                \ +        __result;                                               \ +    }) + +#define g_arch_instruction_replace_operand(ins, n, o)           \ +    ({                                                          \ +        g_arch_instruction_lock_operands(ins);                  \ +        _g_arch_instruction_replace_operand(ins, n, o);         \ +        g_arch_instruction_unlock_operands(ins);                \ +    }) + +#define g_arch_instruction_detach_operand(ins, o)               \ +    ({                                                          \ +        g_arch_instruction_lock_operands(ins);                  \ +        _g_arch_instruction_detach_operand(ins, o);             \ +        g_arch_instruction_unlock_operands(ins);                \ +    }) diff --git a/src/arch/link.c b/src/arch/link.c index dfc2bd5..fbcd391 100644 --- a/src/arch/link.c +++ b/src/arch/link.c @@ -53,9 +53,13 @@ void handle_jump_as_link(GArchInstruction *instr, GArchProcessor *proc, GProcCon      vmpa2t addr;                            /* Adresse de destination      */      GArchInstruction *target;               /* Ligne visée par la référence*/ -    assert(g_arch_instruction_count_operands(instr) > 0); +    g_arch_instruction_lock_operands(instr); -    op = g_arch_instruction_get_operand(instr, 0); +    assert(_g_arch_instruction_count_operands(instr) > 0); + +    op = _g_arch_instruction_get_operand(instr, 0); + +    g_arch_instruction_unlock_operands(instr);      if (!G_IS_IMM_OPERAND(op)) return; @@ -102,9 +106,13 @@ void handle_branch_as_link(GArchInstruction *instr, GArchProcessor *proc, GProcC      const mrange_t *range;                  /* Emplacement d'instruction   */      vmpa2t next;                            /* Position suivante           */ -    assert(g_arch_instruction_count_operands(instr) > index); +    g_arch_instruction_lock_operands(instr); + +    assert(_g_arch_instruction_count_operands(instr) > index); -    op = g_arch_instruction_get_operand(instr, index); +    op = _g_arch_instruction_get_operand(instr, index); + +    g_arch_instruction_unlock_operands(instr);      defined = false; @@ -175,9 +183,13 @@ void handle_call_as_link(GArchInstruction *instr, GArchProcessor *proc, GProcCon      vmpa2t addr;                            /* Adresse de destination      */      GArchInstruction *target;               /* Ligne visée par la référence*/ -    assert(g_arch_instruction_count_operands(instr) > 0); +    g_arch_instruction_lock_operands(instr); + +    assert(_g_arch_instruction_count_operands(instr) > 0); + +    op = _g_arch_instruction_get_operand(instr, 0); -    op = g_arch_instruction_get_operand(instr, 0); +    g_arch_instruction_unlock_operands(instr);      if (!G_IS_IMM_OPERAND(op)) return; diff --git a/src/arch/post.c b/src/arch/post.c index 59ed40e..babe6a9 100644 --- a/src/arch/post.c +++ b/src/arch/post.c @@ -63,7 +63,9 @@ void post_process_target_resolution(GArchInstruction *instr, GArchProcessor *pro      GBinRoutine *routine;                   /* Nouvelle routine trouvée    */      GBinSymbol *symbol;                     /* Nouveau symbole construit   */ -    op = g_arch_instruction_get_operand(instr, index); +    g_arch_instruction_lock_operands(instr); + +    op = _g_arch_instruction_get_operand(instr, index);      assert(G_IS_IMM_OPERAND(op));      if (g_imm_operand_to_virt_t(G_IMM_OPERAND(op), &addr) @@ -109,8 +111,10 @@ void post_process_target_resolution(GArchInstruction *instr, GArchProcessor *pro          } -        g_arch_instruction_replace_operand(instr, new, op); +        _g_arch_instruction_replace_operand(instr, new, op);      } +    g_arch_instruction_unlock_operands(instr); +  } diff --git a/src/arch/raw.c b/src/arch/raw.c index 63dadab..f22645f 100644 --- a/src/arch/raw.c +++ b/src/arch/raw.c @@ -512,6 +512,8 @@ static void g_raw_instruction_print(GRawInstruction *instr, GBufferLine *line, s          first = true; +        g_arch_instruction_lock_operands(base); +          for (i = 0; i < base->operands_count; i++)          {              status = g_imm_operand_get_value(G_IMM_OPERAND(base->operands[i]), MDS_8_BITS, &byte); @@ -558,6 +560,8 @@ static void g_raw_instruction_print(GRawInstruction *instr, GBufferLine *line, s          } +        g_arch_instruction_unlock_operands(base); +          /* Si une chaîne reste encore */          if (iter > 1)          { @@ -581,6 +585,8 @@ static void g_raw_instruction_print(GRawInstruction *instr, GBufferLine *line, s      else      { +        g_arch_instruction_lock_operands(base); +          if (base->operands_count > 0)          {              g_arch_operand_print(base->operands[0], line, 0/*syntax*/); @@ -596,6 +602,8 @@ static void g_raw_instruction_print(GRawInstruction *instr, GBufferLine *line, s          } +        g_arch_instruction_unlock_operands(base); +      }  }  | 
