diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2018-08-08 19:59:34 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2018-08-08 19:59:34 (GMT) |
commit | b3b515ba37ef58751e5407bfcdff2dd67932b99a (patch) | |
tree | 88dabcde3d63e87e7ac0c7509629346dde066429 /src/gtkext/graph | |
parent | 0442cf03782e65bd680449cc213ace9a21bb081b (diff) |
Defined a new kind of code blocks.
Diffstat (limited to 'src/gtkext/graph')
-rw-r--r-- | src/gtkext/graph/cluster.c | 273 | ||||
-rw-r--r-- | src/gtkext/graph/cluster.h | 4 |
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 *); |