diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/analysis/disass/loop.c | 2 | ||||
| -rw-r--r-- | src/arch/instruction.c | 62 | ||||
| -rw-r--r-- | src/arch/instruction.h | 3 | ||||
| -rw-r--r-- | src/gtkext/graph/edge.c | 2 | ||||
| -rw-r--r-- | src/gtkext/graph/node.c | 9 | ||||
| -rw-r--r-- | src/gtkext/graph/nodes/flow.c | 46 | ||||
| -rw-r--r-- | src/gtkext/graph/nodes/virtual.c | 106 | 
7 files changed, 121 insertions, 109 deletions
diff --git a/src/analysis/disass/loop.c b/src/analysis/disass/loop.c index 0cb346b..44fa6d5 100644 --- a/src/analysis/disass/loop.c +++ b/src/analysis/disass/loop.c @@ -269,7 +269,7 @@ static void track_loops_in_code(const GArchProcessor *proc, const mrange_t *rang                      addr = get_mrange_addr(irange);                      if (!is_new_exec_flow(flow, addr)) -                        types[i] = ILT_LOOP; +                        /* status = */g_arch_instruction_change_link(iter, dests[i], types[i], ILT_LOOP);                      else                      { diff --git a/src/arch/instruction.c b/src/arch/instruction.c index 08256d1..475c038 100644 --- a/src/arch/instruction.c +++ b/src/arch/instruction.c @@ -624,6 +624,68 @@ void g_arch_instruction_link_with(GArchInstruction *instr, GArchInstruction *des  /******************************************************************************  *                                                                             *  *  Paramètres  : instr = instruction dont les informations sont à consulter.  * +*                dest  = ligne visée par la liaison (côté destination).       * +*                old   = ancien type de lien construit.                       * +*                new   = nouveau type de lien à construire.                   * +*                                                                             * +*  Description : Change la nature d'un lien entre deux instructions.          * +*                                                                             * +*  Retour      : true pour une mise à jour réussie, false sinon.              * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void g_arch_instruction_change_link(GArchInstruction *instr, GArchInstruction *dest, InstructionLinkType old, InstructionLinkType new) +{ +    size_t count;                           /* Raccourci pour la lecture   */ +    size_t i;                               /* Boucle de parcours          */ +    size_t from_idx;                        /* Indice côté destination     */ +    size_t to_idx;                          /* Indice côté source          */ + +    /* Côté destination */ + +    count = dest->from_count; + +    for (i = 0; i < count; i++) +        if (dest->from[i] == instr && dest->from_types[i] == old) +            break; + +    if (i == count) +        return false; +    else +        from_idx = i; + +    /* Côté point de départ */ + +    count = instr->to_count; + +    for (i = 0; i < count; i++) +        if (instr->to[i] == dest && instr->to_types[i] == old) +            break; + +    if (i == count) +        return false; +    else +        to_idx = i; + +    /* Si les deux extrémités sont raccord... */ + +    dest->from_types[from_idx] = new; + +    instr->to_types[to_idx] = new; + +    return true; + + +    /* TODO : si les informations complémentaires restent en place, compléter ! */ + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : instr = instruction dont les informations sont à consulter.  *  *                                                                             *  *  Description : Indique si l'instruction a une ou plusieurs origines.        *  *                                                                             * diff --git a/src/arch/instruction.h b/src/arch/instruction.h index 0198bb5..9123b6f 100644 --- a/src/arch/instruction.h +++ b/src/arch/instruction.h @@ -188,6 +188,9 @@ bool g_arch_instruction_is_return(const GArchInstruction *instr);  /* Etablit un lien entre deux instructions. */  void g_arch_instruction_link_with(GArchInstruction *, GArchInstruction *, InstructionLinkType, ...); +/* Change la nature d'un lien entre deux instructions. */ +void g_arch_instruction_change_link(GArchInstruction *, GArchInstruction *, InstructionLinkType, InstructionLinkType); +  /* Indique si l'instruction a une ou plusieurs origines. */  bool g_arch_instruction_has_sources(const GArchInstruction *); diff --git a/src/gtkext/graph/edge.c b/src/gtkext/graph/edge.c index cd312cb..acd164c 100644 --- a/src/gtkext/graph/edge.c +++ b/src/gtkext/graph/edge.c @@ -238,7 +238,7 @@ void g_graph_edge_reserve_vertical_space(GGraphEdge *edge, GGraphNode *nodes, GG              g_object_ref(G_OBJECT(container));              edge->container = G_VIRTUAL_NODE(container); -            edge->is_left = false;  /* TODO */ +            edge->is_left = true;  /* TODO */              r1 = g_graph_node_get_rank(G_GRAPH_NODE(edge->src_node));              r2 = g_graph_node_get_rank(G_GRAPH_NODE(edge->dest_node)); diff --git a/src/gtkext/graph/node.c b/src/gtkext/graph/node.c index 3801d1a..ec09941 100644 --- a/src/gtkext/graph/node.c +++ b/src/gtkext/graph/node.c @@ -24,6 +24,7 @@  #include "node.h" +#include <assert.h>  #include <malloc.h>  #include <stdio.h>  #include <string.h> @@ -258,6 +259,8 @@ void g_graph_node_reset_position(GGraphNode *node)      node->alloc.x = UNINITIALIZED_NODE_POS;      node->alloc.y = UNINITIALIZED_NODE_POS; +    node->pending_flag = PPF_NONE; +      if (node->reset_pos != NULL)          node->reset_pos(node); @@ -307,18 +310,21 @@ void g_graph_node_apply_position(GGraphNode *node)      switch (node->pending_flag)      {          case PPF_DIRECT_X: +            assert(g_graph_node_has_x_position(node->pending_rel));              g_graph_node_get_position(node->pending_rel, &x_pos, NULL);              x_pos += node->pending_pos.direct_x;              g_graph_node_set_x_position(node, x_pos);              break;          case PPF_LEFT_MARGIN: +            assert(g_graph_node_has_x_position(node->pending_rel));              g_graph_node_get_position(node->pending_rel, &x_pos, NULL);              x_pos += EDGE_SLOT_HORIZ_MARGIN + node->pending_pos.left_margin;              g_graph_node_set_x_position(node, x_pos);              break;          case PPF_RIGHT_MARGIN: +            assert(g_graph_node_has_x_position(node->pending_rel));              g_graph_node_get_position(node->pending_rel, &x_pos, NULL);              x_pos += node->pending_pos.right_margin;              x_pos -= (EDGE_SLOT_HORIZ_MARGIN + node->alloc.width); @@ -386,6 +392,9 @@ void g_graph_node_set_x_position(GGraphNode *node, gint x)  void g_graph_node_set_pending_position(GGraphNode *node, PendingPositionFlags flag, pending_position pos, GGraphNode *rel)  { +    if (node->pending_flag != PPF_NONE) +        return; +      node->pending_pos = pos;      node->pending_flag = flag;      node->pending_rel = rel; diff --git a/src/gtkext/graph/nodes/flow.c b/src/gtkext/graph/nodes/flow.c index 5173810..863d86c 100644 --- a/src/gtkext/graph/nodes/flow.c +++ b/src/gtkext/graph/nodes/flow.c @@ -299,6 +299,7 @@ static void g_flow_node_prepare_x_line(GFlowNode *node, GGraphNode *nodes)  {      GGraphNode *base;                       /* Autre vision de l'instance  */      GArchInstruction *last;                 /* Dernière instr. du noeud    */ +    size_t loop_index;                      /* Indice de sortie en boucle  */      GFlowNode *target;                      /* Bloc visé par le lien       */      node_slot_t *dest_slot;                 /* Accrochage d'arrivée        */      pending_position pos;                   /* Position à transmettre      */ @@ -312,25 +313,52 @@ static void g_flow_node_prepare_x_line(GFlowNode *node, GGraphNode *nodes)      g_flow_block_get_boundary(node->block, NULL, &last); -    switch (node->exits_count) +    for (loop_index = 0; loop_index < node->exits_count; loop_index++) +        if (node->exits[loop_index].type == ILT_LOOP) +            break; + +    switch (node->exits_count - (loop_index == node->exits_count ? 0 : 1))      {          case 0:              break;          case 1: -            if (node->exits[0].type == ILT_LOOP) -                break; +            if (loop_index == node->exits_count) +            { +                target = G_FLOW_NODE(find_node_for_instruction(nodes, node->exits[0].instr)); + +                dest_slot = g_flow_node_get_slot(target, true, +                                                 last, node->exits[0].group_index); -            target = G_FLOW_NODE(find_node_for_instruction(nodes, node->exits[0].instr)); +            } +            else +            { +                target = G_FLOW_NODE(find_node_for_instruction(nodes, node->exits[1].instr)); -            dest_slot = g_flow_node_get_slot(target, true, -                                             last, node->exits[0].group_index); +                dest_slot = g_flow_node_get_slot(target, true, +                                                 last, node->exits[1].group_index); + +            }              pos.direct_x = g_flow_node_get_slot_offset(target, true, dest_slot);              pos.direct_x = (G_GRAPH_NODE(target)->alloc.width / 2) - pos.direct_x; -            if (target->entries_count == 1) +            pos.direct_x -= (G_GRAPH_NODE(target)->alloc.width - G_GRAPH_NODE(node)->alloc.width) / 2; + +            size_t count_and_skip_loop(GFlowNode *n) +            { +                size_t counter; + +                for (counter = 0; counter < n->entries_count; counter++) +                    if (n->entries[counter].type == ILT_LOOP) +                        break; + +                return counter < n->entries_count ? n->entries_count - 1 : n->entries_count; + +            } + +            if (count_and_skip_loop(target) == 1)                  g_graph_node_set_pending_position(G_GRAPH_NODE(target), PPF_DIRECT_X, pos, base);              break; @@ -678,7 +706,7 @@ static void g_flow_node_setup_entry_slots(GFlowNode *node)                  node->entries[used].type = types[i];                  node->entries[used].group_index = g_arch_instruction_compute_group_index(&instrs[i], -                                                                                      instrs, icount); +                                                                                         instrs, icount);                  node->entries[used].slot_index = i;                  used++; @@ -769,7 +797,7 @@ static void g_flow_node_setup_exit_slots(GFlowNode *node)                  node->exits[used].type = types[i];                  node->exits[used].group_index = g_arch_instruction_compute_group_index(&instrs[i], -                                                                                    instrs, icount); +                                                                                       instrs, icount);                  node->exits[used].slot_index = i;                  used++; diff --git a/src/gtkext/graph/nodes/virtual.c b/src/gtkext/graph/nodes/virtual.c index e04ff5d..cb46aee 100644 --- a/src/gtkext/graph/nodes/virtual.c +++ b/src/gtkext/graph/nodes/virtual.c @@ -24,6 +24,7 @@  #include "virtual.h" +#include <assert.h>  #include <malloc.h>  #include <sys/param.h> @@ -365,7 +366,6 @@ static void g_virtual_node_finalize(GVirtualNode *node)  /******************************************************************************  *                                                                             *  *  Paramètres  : block = bloc virtuel représenté graphiquement.               * -*                view  = morceau d'affichage à représenter.                   *  *                                                                             *  *  Description : Encapsule graphiquement un bloc virtuel.                     *  *                                                                             * @@ -489,12 +489,14 @@ static void g_virtual_node_apply_position(GVirtualNode *node)      }      /* Espace pour les liens remontants */ +      if (node->left_count > 0)          offset = EDGE_SLOT_HORIZ_MARGIN + EDGE_HORIZONTAL_MIN_SEP * (node->left_count - 1);      else          offset = 0;      /* Ajout du décallage le plus grand */ +      offset += -min;      /* Traitement des sous-noeuds */ @@ -543,14 +545,14 @@ static void g_virtual_node_apply_x_line(GVirtualNode *node)      {          level = &node->levels[i]; -        /* Si l'ensemble de l'étage doit être aligné */ +        /* Si l'ensemble de l'étage doit être centré */          if (level->children[0]->pending_flag == PPF_NONE)          {              width_sum = 0;              for (j = 0; j < level->count; j++)              { -                /* BUG_ON(level->children[j]->pending_flag != PPF_NONE); */ +                assert(level->children[j]->pending_flag == PPF_NONE);                  g_graph_node_apply_position(level->children[j]);                  width_sum += level->children[j]->alloc.width; @@ -698,98 +700,6 @@ static void g_virtual_node_set_position(GVirtualNode *node, gint x)  /******************************************************************************  *                                                                             * -*  Paramètres  : node = noeud graphique à consulter.                          * -*                                                                             * -*  Description : Indique l'espace requis pour un noeud d'encapsulation.       * -*                                                                             * -*  Retour      : Espace constitué, entièrement ou non.                        * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -static GtkAllocation g_virtual_node_get_allocation(const GVirtualNode *node) -{ -    GtkAllocation result;                   /* Valeurs à retourner         */ -    gint margins;                           /* Bordures gauche et droite   */ -    unsigned int last_rank;                 /* Détection de saut de rangs  */ -    size_t vert_count;                      /* Quantité à la verticale     */ -    gint rank_width;                        /* Largeur d'un rang donné     */ -    gint rank_height;                       /* Hauteur d'un rang donné     */ -    size_t i;                               /* Boucle de parcours          */ -    GtkAllocation alloc;                    /* Allocation d'un sous-noeud  */ - -    result.x = node->x; -    result.y = node->y; - -    result.width = 0; -    margins = 0; -    if (node->left_count > 0) -    { -        margins += EDGE_SLOT_HORIZ_MARGIN; -        margins += (node->left_count - 1) * EDGE_HORIZONTAL_MIN_SEP; -    } -    if (node->right_count > 0) -    { -        margins += EDGE_SLOT_HORIZ_MARGIN; -        margins += (node->right_count - 1) * EDGE_HORIZONTAL_MIN_SEP; -    } -    result.height = 0; - -    last_rank = -1; - -    vert_count = 0; - -    rank_width = 0; -    rank_height = 0; - -    for (i = 0; i < node->count; i++) -    { -        alloc = g_graph_node_get_allocation(node->children[i]); - -        /* Prise en compte de l'étage précédent */ -        if (last_rank != g_graph_node_get_rank(node->children[i])) -        { -            last_rank = g_graph_node_get_rank(node->children[i]); - -            result.width = MAX(result.width, rank_width); -            result.height += rank_height; - -            rank_width = 0; -            rank_height = 0; - -            vert_count++; - -        } - -        /* Mise à jour de l'étage courant */ - -        if (node->x == UNINITIALIZED_NODE_POS) -        { -            rank_width += alloc.width; -            if (rank_width > 0) rank_width += NODE_LEFT_MARGIN; -        } -        else -            rank_width = MAX(alloc.x + alloc.width - node->x, rank_width); - -        rank_height = MAX(rank_height, alloc.height); - -    } - -    result.width = MAX(result.width, rank_width); - -    result.width += margins; - -    if (vert_count > 1) -        result.height += (vert_count - 1) * NODE_TOP_MARGIN; - -    return result; - -} - - -/****************************************************************************** -*                                                                             *  *  Paramètres  : node     = noeud graphique démarrant la visite.              *  *                callback = ensemble de blocs à parcourir.                    *  *                data     = donnée utilisateur à associer au parcours.        * @@ -1026,14 +936,14 @@ gint g_virtual_node_get_x_for_vspan_slot(const GVirtualNode *node, vspan_slot_t      gint result;                            /* Position à retourner        */      GtkAllocation alloc;                    /* Taille totale requise       */ -    alloc = g_virtual_node_get_allocation(node); +    alloc = G_GRAPH_NODE(node)->alloc;      if (left)      {          /*BUG_ON(slot >= node->left_count) */ -        result = (node->left_count - 1) * EDGE_HORIZONTAL_MIN_SEP/* + EDGE_SLOT_HORIZ_MARGIN*/; -        result -= (slot * EDGE_HORIZONTAL_MIN_SEP/* + EDGE_SLOT_HORIZ_MARGIN*/); +        result = -(node->left_count - 1) * EDGE_HORIZONTAL_MIN_SEP/* + EDGE_SLOT_HORIZ_MARGIN*/; +        result += (slot * EDGE_HORIZONTAL_MIN_SEP/* + EDGE_SLOT_HORIZ_MARGIN*/);          result += alloc.x;  | 
