summaryrefslogtreecommitdiff
path: root/src/gtkext/graph
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2018-08-08 19:59:34 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2018-08-08 19:59:34 (GMT)
commitb3b515ba37ef58751e5407bfcdff2dd67932b99a (patch)
tree88dabcde3d63e87e7ac0c7509629346dde066429 /src/gtkext/graph
parent0442cf03782e65bd680449cc213ace9a21bb081b (diff)
Defined a new kind of code blocks.
Diffstat (limited to 'src/gtkext/graph')
-rw-r--r--src/gtkext/graph/cluster.c273
-rw-r--r--src/gtkext/graph/cluster.h4
2 files changed, 74 insertions, 203 deletions
diff --git a/src/gtkext/graph/cluster.c b/src/gtkext/graph/cluster.c
index a156bfa..8e33671 100644
--- a/src/gtkext/graph/cluster.c
+++ b/src/gtkext/graph/cluster.c
@@ -34,7 +34,6 @@
#include "../gtkbufferdisplay.h"
#include "../gtkdisplaypanel.h"
#include "../../common/sort.h"
-#include "../../glibext/gbinarycursor.h" // REMME
#include "../../glibext/gloadedpanel.h"
@@ -75,7 +74,7 @@ typedef struct _hspace_booking
/* Découpage vertical */
typedef struct _graph_rank
{
- unsigned int level; /* Niveau des blocs */
+ size_t level; /* Niveau des blocs */
hspace_booking **right2left; /* Réservations de D -> G */
size_t r2l_count; /* Quantité de ces réservations*/
@@ -105,7 +104,7 @@ struct _GGraphCluster
incoming_edge **top_anchors; /* Accroches supérieures */
size_t ta_count; /* Quantité de ces accroches */
- GBasicBlock *block; /* Bloc d'origine représenté */
+ GCodeBlock *block; /* Bloc d'origine représenté */
GtkWidget *display; /* Vue graphique associée */
GtkAllocation alloc; /* Emplacement final du bloc */
@@ -113,7 +112,7 @@ struct _GGraphCluster
size_t ba_count; /* Quantité de ces accroches */
bool has_straight; /* Présence d'une ligne droite */
- unsigned int straight_level; /* Rang atteint en ligne droite*/
+ size_t straight_level; /* Rang atteint en ligne droite*/
size_t straight_index; /* Indice du lien vertical */
graph_rank *ranks; /* Répartition verticale */
@@ -152,7 +151,7 @@ static void g_graph_cluster_dispose(GGraphCluster *);
static void g_graph_cluster_finalize(GGraphCluster *);
/* Complète un graphique avec un sous-ensemble de blocs. */
-static void g_graph_cluster_add_sub(GGraphCluster *, GGraphCluster *, GBasicBlock *);
+static void g_graph_cluster_add_sub(GGraphCluster *, GGraphCluster *, GCodeBlock *);
/* Organisation la disposition d'un ensemble de blocs basiques. */
static void g_graph_cluster_dispatch_x(GGraphCluster *);
@@ -285,12 +284,11 @@ static void g_graph_cluster_finalize(GGraphCluster *cluster)
/******************************************************************************
* *
-* Paramètres : binary = binaire charger dont le code est à représenter.*
-* list = ensemble de blocs basiques à manipuler. *
-* index = indice du bloc principal à mettre en place. *
+* Paramètres : block = premier bloc du groupe. *
* highlighted = gestionnaire de surbrillance pour segments. *
+* binary = binaire charger dont le code est à représenter.*
* *
-* Description : Construit un graphique à partir de blocs basiques. *
+* Description : *
* *
* Retour : Adresse de la structure mise en place. *
* *
@@ -298,14 +296,9 @@ static void g_graph_cluster_finalize(GGraphCluster *cluster)
* *
******************************************************************************/
-GGraphCluster *g_graph_cluster_new(GLoadedBinary *binary, const GBlockList *list, size_t index, segcnt_list *highlighted)
+GGraphCluster *g_graph_cluster_new(GCodeBlock *block, segcnt_list *highlighted, GLoadedBinary *binary)
{
GGraphCluster *result; /* Structure à retourner */
- vmpa2t first; /* Début d'un groupe de lignes */
- vmpa2t last; /* Fin d'un groupe de lignes */
- GLineCursor *___tmp_first;
- GLineCursor *___tmp_last;
- GBufferCache *cache; /* Tampon brut à découper */
GBufferView *view; /* Partie affichée du tampon */
GtkRequisition requisition; /* Taille à l'écran actuelle */
@@ -313,10 +306,12 @@ GGraphCluster *g_graph_cluster_new(GLoadedBinary *binary, const GBlockList *list
/* Encapsulation du bloc d'entrée */
- result->block = g_block_list_get_block(list, index);
- g_object_ref(G_OBJECT(result->block));
+ result->block = block;
+ g_object_ref(G_OBJECT(block));
- result->display = gtk_block_display_new();
+ view = g_code_block_get_view(result->block, highlighted);
+
+ result->display = gtk_block_display_new(view);
gtk_widget_show(result->display);
g_loaded_panel_set_content(G_LOADED_PANEL(result->display), G_LOADED_CONTENT(binary));
@@ -325,25 +320,6 @@ GGraphCluster *g_graph_cluster_new(GLoadedBinary *binary, const GBlockList *list
gtk_display_panel_show_border(GTK_DISPLAY_PANEL(result->display), true);
- /* Restriction au bloc basique */
-
- g_basic_block_get_boundary_addresses(result->block, &first, &last);
-
-
- ///////////////////////
- ___tmp_first = g_binary_cursor_new();
- g_binary_cursor_update(G_BINARY_CURSOR(___tmp_first), &first);
- ___tmp_last = g_binary_cursor_new();
- g_binary_cursor_update(G_BINARY_CURSOR(___tmp_last), &last);
- ///////////////////////
-
-
- cache = g_loaded_binary_get_disassembled_cache(binary);
-
- view = g_buffer_view_new(cache, highlighted);
- g_buffer_view_restrict(view, ___tmp_first, ___tmp_last);
- gtk_buffer_display_set_view(GTK_BUFFER_DISPLAY(result->display), view);
-
/* Détermination d'une position initiale centrée */
gtk_widget_get_preferred_size(result->display, NULL, &requisition);
@@ -375,14 +351,14 @@ GGraphCluster *g_graph_cluster_new(GLoadedBinary *binary, const GBlockList *list
* *
******************************************************************************/
-static void g_graph_cluster_add_sub(GGraphCluster *cluster, GGraphCluster *sub, GBasicBlock *block)
+static void g_graph_cluster_add_sub(GGraphCluster *cluster, GGraphCluster *sub, GCodeBlock *block)
{
- unsigned int level; /* Niveau du nouvel ensemble */
+ size_t level; /* Niveau du nouvel ensemble */
size_t i; /* Boucle de parcours */
graph_rank new; /* Nouvel étage à insérer */
graph_rank *rank; /* Nouvel étage à compléter */
- level = g_basic_block_get_rank(block);
+ level = g_code_block_get_rank(block);
for (i = 0; i < cluster->ranks_count; i++)
if (cluster->ranks[i].level == level)
@@ -917,30 +893,27 @@ static GGraphCluster *g_graph_cluster_find_lower_dest_cluster(const GGraphCluste
static void g_graph_cluster_define_links(GGraphCluster *cluster, GHashTable *all)
{
- unsigned int level; /* Niveau du nouvel ensemble */
- GArchInstruction *last; /* Dernière instruction du bloc*/
+ size_t level; /* Niveau du nouvel ensemble */
size_t dcount; /* Nombre de liens de dest. */
size_t i; /* Boucle de parcours #1 */
- const instr_link_t *dest; /* Instr. visée par une autre */
+ const block_link_t *dest; /* Bloc visé par une autre */
GGraphCluster *target; /* Bloc ciblé par un lien */
leaving_edge *leaving; /* Point de départ d'un lien */
- unsigned int target_level; /* Rang du bloc ciblé */
+ size_t target_level; /* Rang du bloc ciblé */
size_t j; /* Boucle de parcours #2 */
size_t k; /* Boucle de parcours #3 */
incoming_edge *incoming; /* Définitions d'arrivée */
/* Au niveau du bloc courant */
- level = g_basic_block_get_rank(cluster->block);
+ level = g_code_block_get_rank(cluster->block);
- g_basic_block_get_boundary(cluster->block, NULL, &last);
-
- g_arch_instruction_lock_dest(last);
- dcount = g_arch_instruction_count_destinations(last);
+ g_code_block_lock_dest(cluster->block);
+ dcount = g_code_block_count_destinations(cluster->block);
for (i = 0; i < dcount; i++)
{
- dest = g_arch_instruction_get_destination(last, i);
+ dest = g_code_block_get_destination(cluster->block, i);
switch (dest->type)
{
@@ -1045,11 +1018,11 @@ static void g_graph_cluster_define_links(GGraphCluster *cluster, GHashTable *all
}
- unref_instr_link(dest);
+ unref_block_link(dest);
}
- g_arch_instruction_unlock_dest(last);
+ g_code_block_unlock_dest(cluster->block);
@@ -1489,7 +1462,7 @@ static void g_graph_cluster_resolve_links(const GGraphCluster *cluster)
typedef struct _pending_blocks
{
size_t count; /* Taille de la liste */
- GBasicBlock *list[0]; /* Liste de blocs à traiter */
+ GCodeBlock *list[0]; /* Liste de blocs à traiter */
} pending_blocks;
@@ -1524,43 +1497,38 @@ static GGraphCluster *setup_graph_clusters(GLoadedBinary *, const GBlockList *,
static GGraphCluster *setup_graph_clusters(GLoadedBinary *binary, const GBlockList *list, size_t index, segcnt_list *highlighted, pending_blocks *pending, GHashTable *all)
{
GGraphCluster *result; /* Instance nouvelle à renvoyer*/
- GBasicBlock *block; /* Bloc à manipuler */
- GArchInstruction *first; /* Première instruction du bloc*/
- GArchInstruction *last; /* Dernière instruction du bloc*/
+ GCodeBlock *block; /* Bloc à manipuler */
#ifndef NDEBUG
gboolean new; /* Bloc déjà traité ? */
#endif
size_t dcount; /* Nombre de liens de dest. */
size_t i; /* Boucle de parcours #1 */
- const instr_link_t *dest; /* Instr. visée par une autre */
- GBasicBlock *target; /* Bloc ciblé par un lien */
+ const block_link_t *dest; /* Bloc visé par une autre */
size_t j; /* Boucle de parcours #2 */
bool changed; /* Un ajout a été effectué ? */
const bitfield_t *dominators; /* Blocs dominant ce même bloc */
size_t next; /* Indice du prochain bloc */
GGraphCluster *sub; /* Sous-ensemble à intégrer */
- result = g_graph_cluster_new(binary, list, index, highlighted);
-
block = g_block_list_get_block(list, index);
- g_basic_block_get_boundary(block, &first, &last);
+ result = g_graph_cluster_new(block, highlighted, binary);
#ifndef NDEBUG
- new = g_hash_table_insert(all, first, result);
+ new = g_hash_table_insert(all, block, result);
assert(new);
#else
- g_hash_table_insert(all, first, result);
+ g_hash_table_insert(all, block, result);
#endif
/* Détermination des blocs suivants */
- g_arch_instruction_lock_dest(last);
- dcount = g_arch_instruction_count_destinations(last);
+ g_code_block_lock_dest(block);
+ dcount = g_code_block_count_destinations(block);
for (i = 0; i < dcount; i++)
{
- dest = g_arch_instruction_get_destination(last, i);
+ dest = g_code_block_get_destination(block, i);
switch (dest->type)
{
@@ -1570,69 +1538,40 @@ static GGraphCluster *setup_graph_clusters(GLoadedBinary *binary, const GBlockLi
case ILT_JUMP_IF_TRUE:
case ILT_JUMP_IF_FALSE:
- 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.
- * Par exemple sous ARM :
- *
- * 00008358 <call_gmon_start>:
- * ....
- * 8362: f7ff bfcf b.w 8304 <_init+0x38>
- * ....
- *
- */
-
- printf(" NEW BLK :: %d -> %p\n", dest->type, target);
+ for (j = 0; j < pending->count; j++)
+ if (pending->list[j] == dest->linked)
+ break;
- if (target != NULL)
+ if (j == pending->count)
{
- for (j = 0; j < pending->count; j++)
- if (pending->list[j] == target)
- break;
-
- if (j == pending->count)
+ /**
+ * Il faut vérifier ici si la destination n'a pas déjà été
+ * empruntée, sauf peine de faire réagir l'assertion plus
+ * haut au moment de l'insertion.
+ *
+ * Le type de code à problème est le suivant :
+ *
+ * ...
+ * if (...)
+ * ...
+ * ...
+ *
+ * Le code suivant le bloc conditionnel a deux origines,
+ * qui vont chacune poursuivre le traitement vers ce code
+ * commun.
+ *
+ * Et comme les origines ne sont pas dominantes, on utilise
+ * la table globale.
+ */
+
+ if (!g_hash_table_contains(all, dest->linked))
{
- /**
- * Il faut vérifier ici si la destination n'a pas déjà été
- * empruntée, sauf peine de faire réagir l'assertion plus
- * haut au moment de l'insertion.
- *
- * Le type de code à problème est le suivant :
- *
- * ...
- * if (...)
- * ...
- * ...
- *
- * Le code suivant le bloc conditionnel a deux origines,
- * qui vont chacune poursuivre le traitement vers ce code
- * commun.
- *
- * Et comme les origines ne sont pas dominantes, on utilise
- * la table globale.
- */
-
- if (!g_hash_table_contains(all, dest->linked))
- {
- assert((pending->count + 1) < g_block_list_count_blocks(list));
- pending->list[pending->count++] = target;
- printf(" --push-- %d -> %p\n", dest->type, target);
- }
+ g_object_ref(G_OBJECT(dest->linked));
- }
+ assert((pending->count + 1) < g_block_list_count_blocks(list));
+ pending->list[pending->count++] = dest->linked;
- do
- {
- size_t k;
- printf(" --stack-- ");
- for (k = 0; k < pending->count; k++)
- printf("%p ", pending->list[k]);
- printf("\n");
}
- while (0);
-
-
}
@@ -1643,11 +1582,13 @@ static GGraphCluster *setup_graph_clusters(GLoadedBinary *binary, const GBlockLi
}
- unref_instr_link(dest);
+ unref_block_link(dest);
}
- g_arch_instruction_unlock_dest(last);
+ g_code_block_unlock_dest(block);
+
+ g_object_unref(G_OBJECT(block));
/* Intégration de tous les blocs en attente */
@@ -1658,7 +1599,7 @@ static GGraphCluster *setup_graph_clusters(GLoadedBinary *binary, const GBlockLi
for (i = 0; i < pending->count && !changed; i++)
{
block = pending->list[i];
- dominators = g_basic_block_get_domination(block);
+ dominators = g_code_block_get_domination(block);
if (test_in_bit_field(dominators, index))
{
@@ -1668,23 +1609,23 @@ static GGraphCluster *setup_graph_clusters(GLoadedBinary *binary, const GBlockLi
if ((i + 1) < pending->count)
memmove(&pending->list[i], &pending->list[i + 1],
- (pending->count - i - 1) * sizeof(GBasicBlock *));
+ (pending->count - i - 1) * sizeof(GCodeBlock *));
pending->count--;
/* Intégration */
- next = g_block_list_get_index(list, block);
+ next = g_code_block_get_index(block);
assert(next < g_block_list_count_blocks(list));
- printf(" --pop-- block=%p index=%zu\n", block, next);
-
sub = setup_graph_clusters(binary, list, next, highlighted, pending, all);
g_graph_cluster_add_sub(result, sub, block);
}
+ g_object_ref(G_OBJECT(block));
+
}
}
@@ -1725,77 +1666,7 @@ GGraphCluster *bootstrap_graph_cluster(GLoadedBinary *binary, const GBlockList *
count = g_block_list_count_blocks(list);
- pending = (pending_blocks *)calloc(1, sizeof(pending_blocks) + count * sizeof(GBasicBlock *));
-
-
-
-#if 0
- do
- {
- size_t i;
- GBasicBlock *block;
- const bitfield_t *domination;
- GArchInstruction *first; /* Première instruction du bloc*/
- GArchInstruction *last; /* Dernière instruction du bloc*/
-
-
- printf("DBG // count : %zu\n", count);
-
- for (i = 0; i < count; i++)
- {
- block = g_block_list_get_block(list, i);
- domination = g_basic_block_get_domination(block);
-
- g_basic_block_get_boundary(block, &first, &last);
-
- printf("DBG // block [%zu] @ 0x%08x : 0x%08lx -- rank = %u\n",
- i,
- (unsigned int)first->range.addr.virtual,
- gfw(domination), g_basic_block_get_rank(block));
-
- }
-
- fflush(NULL);
-
- }
- while (0);
-
-
-
- void show_tree(GGraphCluster *cluster, int depth)
- {
- int i;
- GArchInstruction *first;
- size_t j;
- size_t k;
-
- printf("TREE | ");
-
- for (i = 0; i < depth; i++)
- printf(" ");
-
- g_basic_block_get_boundary(cluster->block, &first, NULL);
-
- printf("cluster @ 0x%08x\n", (unsigned int)first->range.addr.virtual);
-
- for (j = 0; j < cluster->ranks_count; j++)
- {
- printf("TREE | ");
-
- for (i = 0; i < depth; i++)
- printf(" ");
-
- printf(" + rank %u +\n", cluster->ranks[j].level);
-
- for (k = 0; k < cluster->ranks[j].count; k++)
- show_tree(cluster->ranks[j].clusters[k], depth + 1);
-
- }
-
-
- }
-#endif
-
+ pending = (pending_blocks *)calloc(1, sizeof(pending_blocks) + count * sizeof(GCodeBlock *));
result = setup_graph_clusters(binary, list, 0, highlighted, pending, all);
diff --git a/src/gtkext/graph/cluster.h b/src/gtkext/graph/cluster.h
index 70e1608..abd8a87 100644
--- a/src/gtkext/graph/cluster.h
+++ b/src/gtkext/graph/cluster.h
@@ -50,8 +50,8 @@ typedef struct _GGraphClusterClass GGraphClusterClass;
/* Indique le type définit par la GLib pour les mises en disposition graphique. */
GType g_graph_cluster_get_type(void);
-/* Construit un graphique à partir de blocs basiques. */
-GGraphCluster *g_graph_cluster_new(GLoadedBinary *, const GBlockList *, size_t, segcnt_list *);
+/* Construit un graphique à partir de blocs de code. */
+GGraphCluster *g_graph_cluster_new(GCodeBlock *, segcnt_list *, GLoadedBinary *);
/* Détermine l'emplacement requis d'un ensemble de blocs. */
void g_graph_cluster_compute_needed_alloc(const GGraphCluster *, GtkAllocation *);