diff options
| author | Cyrille Bagard <nocbos@gmail.com> | 2017-04-13 16:34:34 (GMT) | 
|---|---|---|
| committer | Cyrille Bagard <nocbos@gmail.com> | 2017-04-13 16:34:34 (GMT) | 
| commit | 6906aa19b7ac4c14615c30d15bfb26b0b86557d5 (patch) | |
| tree | f0fb0b6ea116e4ec87f33b3b4198f6dc4c88766c /src/analysis/disass | |
| parent | acc7b5f33e93bae3bf43e8f029976b7f74260b52 (diff) | |
Simplified the way links between instructions are handled.
Diffstat (limited to 'src/analysis/disass')
| -rw-r--r-- | src/analysis/disass/dragon.c | 64 | ||||
| -rw-r--r-- | src/analysis/disass/links.c | 47 | ||||
| -rw-r--r-- | src/analysis/disass/loop.c | 19 | ||||
| -rw-r--r-- | src/analysis/disass/rank.c | 28 | 
4 files changed, 101 insertions, 57 deletions
| diff --git a/src/analysis/disass/dragon.c b/src/analysis/disass/dragon.c index b4c85c0..75ccc40 100644 --- a/src/analysis/disass/dragon.c +++ b/src/analysis/disass/dragon.c @@ -101,13 +101,13 @@ static dragon_node *create_dragon_nodes(GArchProcessor *proc, const instr_covera      GArchInstruction *last;                 /* Mémorisation du passé       */      instr_iter_t *iter;                     /* Boucle de parcours          */      GArchInstruction *instr;                /* Instruction analysée        */ -    instr_link_t *sources;                  /* Liste des instructions liées*/      size_t scount;                          /* Nombre de liens de source   */      bool cut;                               /* Un découpage a été réalisé ?*/      size_t i;                               /* Boucle de parcours          */ +    instr_link_t *source;                   /* Instruction de source liée  */      dragon_node *new;                       /* Nouvel élément à créer      */ -    instr_link_t *dests;                    /* Liste des instructions liées*/      size_t dcount;                          /* Nombre de liens de dest.    */ +    instr_link_t *dest;                     /* Instruction de destination  */      result = NULL;      *count = 0; @@ -163,13 +163,16 @@ static dragon_node *create_dragon_nodes(GArchProcessor *proc, const instr_covera          {              /* Analyse des sources */ -            g_arch_instruction_rlock_src(instr); -            scount = g_arch_instruction_get_sources(instr, &sources); +            g_arch_instruction_lock_src(instr); +            scount = g_arch_instruction_count_sources(instr);              cut = false;              for (i = 0; i < scount && !cut; i++) -                switch (sources[i].type) +            { +                source = g_arch_instruction_get_source(instr, i); + +                switch (source->type)                  {                      case ILT_EXEC_FLOW:                      case ILT_JUMP: @@ -201,19 +204,24 @@ static dragon_node *create_dragon_nodes(GArchProcessor *proc, const instr_covera                  } -            g_arch_instruction_runlock_src(instr); +            } + +            g_arch_instruction_unlock_src(instr);          }          /* Analyse des destinations */ -        g_arch_instruction_rlock_dest(instr); -        dcount = g_arch_instruction_get_destinations(instr, &dests); +        g_arch_instruction_lock_dest(instr); +        dcount = g_arch_instruction_count_destinations(instr);          cut = false;          for (i = 0; i < dcount && !cut; i++) -            switch (dests[i].type) +        { +            dest = g_arch_instruction_get_destination(instr, i); + +            switch (dest->type)              {                  case ILT_JUMP: @@ -230,7 +238,9 @@ static dragon_node *create_dragon_nodes(GArchProcessor *proc, const instr_covera              } -        g_arch_instruction_runlock_dest(instr); +        } + +        g_arch_instruction_unlock_dest(instr);          if (!need_alloc && g_arch_instruction_get_flags(instr) & AIF_RETURN_POINT)          { @@ -436,17 +446,20 @@ void compute_all_paths(dragon_node *nodes, size_t count)  {      void follow_flow_in_nodes(dragon_node *node)      { -        instr_link_t *dests;                /* Liste des instructions liées*/          size_t dcount;                      /* Nombre de liens de dest.    */          size_t i;                           /* Boucle de parcours          */ +        instr_link_t *dest;                 /* Instructions de destination */          dragon_node *next;                  /* Noeud suivant dans le code  */          size_t id;                          /* Indice du bit associé       */ -        g_arch_instruction_rlock_dest(node->last); -        dcount = g_arch_instruction_get_destinations(node->last, &dests); +        g_arch_instruction_lock_dest(node->last); +        dcount = g_arch_instruction_count_destinations(node->last);          for (i = 0; i < dcount; i++) -            switch (dests[i].type) +        { +            dest = g_arch_instruction_get_destination(node->last, i); + +            switch (dest->type)              {                  case ILT_EXEC_FLOW:                  case ILT_JUMP: @@ -454,7 +467,7 @@ void compute_all_paths(dragon_node *nodes, size_t count)                  case ILT_JUMP_IF_TRUE:                  case ILT_JUMP_IF_FALSE: -                    next = find_node_for_instruction(nodes, count, false, dests[i].linked); +                    next = find_node_for_instruction(nodes, count, false, dest->linked);                      if (next == NULL) break;                      id = get_dragon_node_index(nodes, next); @@ -470,7 +483,9 @@ void compute_all_paths(dragon_node *nodes, size_t count)              } -        g_arch_instruction_runlock_dest(node->last); +        } + +        g_arch_instruction_unlock_dest(node->last);      } @@ -518,9 +533,9 @@ void compute_all_dominators(dragon_node *nodes, size_t count)      size_t k;                               /* Boucle de parcours #1       */      dragon_node *node;                      /* Noeud à traiter             */      dragon_node *predecessor;               /* Noeud prédécesseur direct   */ -    instr_link_t *sources;                  /* Instructions d'origine      */      size_t scount;                          /* Nombre de liens de source   */      size_t i;                               /* Boucle de parcours #2       */ +    instr_link_t *source;                   /* Instruction d'origine       */      inter = create_bit_field(count, false); @@ -534,12 +549,15 @@ void compute_all_dominators(dragon_node *nodes, size_t count)              set_all_in_bit_field(inter); -            g_arch_instruction_rlock_src(node->first); -            scount = g_arch_instruction_get_sources(node->first, &sources); +            g_arch_instruction_lock_src(node->first); +            scount = g_arch_instruction_count_sources(node->first);              //assert(scount > 0); // un 'ret' coupe, le suivant n'a pas de source              for (i = 0; i < scount; i++) -                switch (sources[i].type) +            { +                source = g_arch_instruction_get_source(node->first, i); + +                switch (source->type)                  {                      case ILT_EXEC_FLOW:                      case ILT_JUMP: @@ -547,7 +565,7 @@ void compute_all_dominators(dragon_node *nodes, size_t count)                      case ILT_JUMP_IF_TRUE:                      case ILT_JUMP_IF_FALSE: -                        predecessor = find_node_for_instruction(nodes, count, true, sources[i].linked); +                        predecessor = find_node_for_instruction(nodes, count, true, source->linked);                          /*                          printf("  -- finding pred @ 0x%08x -> 0x%08x :: %p\n", @@ -567,7 +585,9 @@ void compute_all_dominators(dragon_node *nodes, size_t count)                  } -            g_arch_instruction_runlock_src(node->first); +            } + +            g_arch_instruction_unlock_src(node->first);              set_in_bit_field(inter, k, 1); diff --git a/src/analysis/disass/links.c b/src/analysis/disass/links.c index d67040b..e1bc58c 100644 --- a/src/analysis/disass/links.c +++ b/src/analysis/disass/links.c @@ -53,9 +53,9 @@ static void convert_immediate_into_target(GArchInstruction *, size_t, GBinFormat  void establish_natural_link(GArchInstruction *instr, GArchInstruction *prev)  { -    bool has_src;                           /* Présence de sources ?       */ -    instr_link_t *others;                   /* Instructions diverses liées */      size_t count;                           /* Nbre de sources affichées   */ +    bool has_src;                           /* Présence de sources ?       */ +    instr_link_t *other;                    /* Instruction diverse liée    */      size_t i;                               /* Boucle de parcours          */      bool no_natural;                        /* Aucun lien naturel présent  */      bool no_need;                           /* Pas de besoin pour ce lien  */ @@ -65,17 +65,22 @@ void establish_natural_link(GArchInstruction *instr, GArchInstruction *prev)       * on ne peut pas créer de lien plus naturel que l'existant.       */ -    g_arch_instruction_rlock_src(instr); +    g_arch_instruction_lock_src(instr); -    count = g_arch_instruction_get_sources(instr, &others); +    count = g_arch_instruction_count_sources(instr);      has_src = false;      for (i = 0; i < count && !has_src; i++) -        if (others[i].type != ILT_REF) +    { +        other = g_arch_instruction_get_source(instr, i); + +        if (other->type != ILT_REF)              has_src = true; -    g_arch_instruction_runlock_src(instr); +    } + +    g_arch_instruction_unlock_src(instr);      if (!has_src)          return; @@ -96,15 +101,18 @@ void establish_natural_link(GArchInstruction *instr, GArchInstruction *prev)       * déjà en place.       */ -    g_arch_instruction_rlock_dest(prev); +    g_arch_instruction_lock_dest(prev); -    count = g_arch_instruction_get_destinations(prev, &others); +    count = g_arch_instruction_count_destinations(prev);      no_natural = true;      no_need = (count > 0);      for (i = 0; i < count && no_natural; i++) -        switch (others[i].type) +    { +        other = g_arch_instruction_get_destination(prev, i); + +        switch (other->type)          {              case ILT_EXEC_FLOW:                  no_natural = false; @@ -112,7 +120,7 @@ void establish_natural_link(GArchInstruction *instr, GArchInstruction *prev)              case ILT_JUMP_IF_TRUE:              case ILT_JUMP_IF_FALSE: -                if (others[i].linked != instr) +                if (other->linked != instr)                      no_need = false;                  else                  { @@ -126,20 +134,25 @@ void establish_natural_link(GArchInstruction *instr, GArchInstruction *prev)          } +    } +   check_done: -    g_arch_instruction_runlock_dest(prev); +    g_arch_instruction_unlock_dest(prev);      if (no_natural && !no_need)      {          /* Vérification de la cohérence de l'ensemble */  #ifndef NDEBUG -        g_arch_instruction_rlock_src(instr); -        count = g_arch_instruction_get_sources(instr, &others); +        g_arch_instruction_lock_src(instr); +        count = g_arch_instruction_count_sources(instr);          for (i = 0; i < count; i++) -            switch (others[i].type) +        { +            other = g_arch_instruction_get_source(instr, i); + +            switch (other->type)              {                  case ILT_EXEC_FLOW:                      assert(false); @@ -151,7 +164,7 @@ void establish_natural_link(GArchInstruction *instr, GArchInstruction *prev)                  case ILT_JUMP_IF_FALSE:                  case ILT_LOOP:                  case ILT_CATCH_EXCEPTION: -                    assert(others[i].linked != prev); +                    assert(other->linked != prev);                      break;                  default: @@ -159,7 +172,9 @@ void establish_natural_link(GArchInstruction *instr, GArchInstruction *prev)              } -        g_arch_instruction_runlock_src(instr); +        } + +        g_arch_instruction_unlock_src(instr);  #endif diff --git a/src/analysis/disass/loop.c b/src/analysis/disass/loop.c index d8ca355..b7e7ff9 100644 --- a/src/analysis/disass/loop.c +++ b/src/analysis/disass/loop.c @@ -49,9 +49,9 @@ static void detect_back_edges(dragon_node *nodes, size_t count)      dragon_node *node;                      /* Noeud à traiter             */      const bitfield_t *dominators;           /* Liste de dominateurs        */      GArchInstruction *last;                 /* Instruction finale de noeud */ -    instr_link_t *dests;                    /* Instr. visées par une autre */      size_t dcount;                          /* Nombre de liens de dest.    */      size_t i;                               /* Boucle de parcours #2       */ +    instr_link_t *dest;                     /* Instr. visée par une autre  */      dragon_node *target;                    /* Noeud référence à tester    */      size_t id;                              /* Indice du bit associé       */ @@ -63,11 +63,14 @@ static void detect_back_edges(dragon_node *nodes, size_t count)          get_dragon_node_bounding_instructions(node, NULL, &last); -        g_arch_instruction_wlock_dest(last); -        dcount = g_arch_instruction_get_destinations(last, &dests); +        g_arch_instruction_lock_dest(last); +        dcount = g_arch_instruction_count_destinations(last);          for (i = 0; i < dcount; i++) -            switch (dests[i].type) +        { +            dest = g_arch_instruction_get_destination(last, i); + +            switch (dest->type)              {                  case ILT_EXEC_FLOW:                  case ILT_JUMP: @@ -75,7 +78,7 @@ static void detect_back_edges(dragon_node *nodes, size_t count)                  case ILT_JUMP_IF_TRUE:                  case ILT_JUMP_IF_FALSE: -                    target = find_node_for_instruction(nodes, count, false, dests[i].linked); +                    target = find_node_for_instruction(nodes, count, false, dest->linked);                      if (target == NULL) break;                      id = get_dragon_node_index(nodes, target); @@ -89,7 +92,7 @@ static void detect_back_edges(dragon_node *nodes, size_t count)                                 (unsigned int)g_arch_instruction_get_range(dests[i])->addr.virtual);                          */ -                        /* status = */g_arch_instruction_change_link(last, dests[i].linked, dests[i].type, ILT_LOOP); +                        /* status = */g_arch_instruction_change_link(last, dest->linked, dest->type, ILT_LOOP);                      } @@ -101,7 +104,9 @@ static void detect_back_edges(dragon_node *nodes, size_t count)              } -        g_arch_instruction_wunlock_dest(last); +        } + +        g_arch_instruction_unlock_dest(last);      } diff --git a/src/analysis/disass/rank.c b/src/analysis/disass/rank.c index 3f4cd9f..6ff194b 100644 --- a/src/analysis/disass/rank.c +++ b/src/analysis/disass/rank.c @@ -61,9 +61,9 @@ static bool rank_flow_block(GFlowBlock *block, BlockVisitOrder order, const GIns      unsigned int next;                      /* Rang suivant obtenu         */      GInstrBlock *links;                     /* Blocs liés au bloc courant  */      GArchInstruction *last;                 /* Dernière instruction du bloc*/ -    instr_link_t *dests;                    /* Instr. visées par une autre */      size_t dcount;                          /* Nombre de liens de dest.    */      size_t i;                               /* Boucle de parcours          */ +    instr_link_t *dest;                     /* Instr. visée par une autre  */      const mrange_t *range;                  /* Emplacement d'une cible     */      GFlowBlock *target;                     /* Bloc ciblé par un lien      */      unsigned int rank;                      /* Rang à constituer           */ @@ -77,14 +77,16 @@ static bool rank_flow_block(GFlowBlock *block, BlockVisitOrder order, const GIns      g_flow_block_get_boundary(block, NULL, &last); -    g_arch_instruction_rlock_dest(last); -    dcount = g_arch_instruction_get_destinations(last, &dests); +    g_arch_instruction_lock_dest(last); +    dcount = g_arch_instruction_count_destinations(last);      for (i = 0; i < dcount; i++)      { -        range = g_arch_instruction_get_range(dests[i].linked); +        dest = g_arch_instruction_get_destination(last, i); -        switch (dests[i].type) +        range = g_arch_instruction_get_range(dest->linked); + +        switch (dest->type)          {              case ILT_EXEC_FLOW:              case ILT_CATCH_EXCEPTION: @@ -175,7 +177,7 @@ static bool rank_flow_block(GFlowBlock *block, BlockVisitOrder order, const GIns      } -    g_arch_instruction_runlock_dest(last); +    g_arch_instruction_unlock_dest(last);      return true; @@ -304,9 +306,9 @@ void rank_routine_block(const GBlockList *list, GBasicBlock *block)  {      unsigned int next;                      /* Rang suivant obtenu         */      GArchInstruction *last;                 /* Dernière instruction du bloc*/ -    instr_link_t *dests;                    /* Instr. visées par une autre */      size_t dcount;                          /* Nombre de liens de dest.    */      size_t i;                               /* Boucle de parcours          */ +    instr_link_t *dest;                     /* Instr. visée par une autre  */      InstructionLinkType type;               /* Raccourci pour confort      */      GBasicBlock *target;                    /* Bloc ciblé par un lien      */      unsigned int rank;                      /* Rang à constituer           */ @@ -315,12 +317,14 @@ void rank_routine_block(const GBlockList *list, GBasicBlock *block)      g_basic_block_get_boundary(block, NULL, &last); -    g_arch_instruction_rlock_dest(last); -    dcount = g_arch_instruction_get_destinations(last, &dests); +    g_arch_instruction_lock_dest(last); +    dcount = g_arch_instruction_count_destinations(last);      for (i = 0; i < dcount; i++)      { -        type = dests[i].type; +        dest = g_arch_instruction_get_destination(last, i); + +        type = dest->type;          /* La boucle de remontée n'abaisse pas les rangs */          if (type == ILT_LOOP) continue; @@ -337,7 +341,7 @@ void rank_routine_block(const GBlockList *list, GBasicBlock *block)              && type != ILT_JUMP_IF_FALSE)              continue; -        target = g_block_list_find_by_starting_instr(list, dests[i].linked); +        target = g_block_list_find_by_starting_instr(list, dest->linked);          /**           * Les sauts ne se font pas toujours à l'intérieur d'une même fonction. @@ -366,7 +370,7 @@ void rank_routine_block(const GBlockList *list, GBasicBlock *block)      } -    g_arch_instruction_runlock_dest(last); +    g_arch_instruction_unlock_dest(last);  } | 
