diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2010-11-12 22:13:21 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2010-11-12 22:13:21 (GMT) |
commit | ae8cf6257c8d929de1b7ee86e29fcb45ab4af91c (patch) | |
tree | 59fa356b2f83020e23df4cf6975ca5d97567df4d /src | |
parent | abaf85fdc0edb2bfe67d07d52ae734d50c6fbf61 (diff) |
Changed the display of the pseudo registers by using an index.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@192 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'src')
-rw-r--r-- | src/arch/dalvik/dop_aget.c | 6 | ||||
-rw-r--r-- | src/arch/dalvik/dop_aput.c | 6 | ||||
-rw-r--r-- | src/arch/dalvik/dop_arithm.c | 14 | ||||
-rw-r--r-- | src/arch/dalvik/dop_array.c | 4 | ||||
-rw-r--r-- | src/arch/dalvik/dop_const.c | 4 | ||||
-rw-r--r-- | src/arch/dalvik/dop_invoke.c | 6 | ||||
-rw-r--r-- | src/arch/dalvik/operand.c | 30 | ||||
-rw-r--r-- | src/arch/dalvik/register.c | 29 | ||||
-rw-r--r-- | src/arch/dalvik/register.h | 3 | ||||
-rw-r--r-- | src/arch/operand-int.h | 5 | ||||
-rw-r--r-- | src/arch/operand.c | 27 | ||||
-rw-r--r-- | src/arch/operand.h | 3 | ||||
-rw-r--r-- | src/decomp/context.c | 55 | ||||
-rw-r--r-- | src/decomp/context.h | 5 | ||||
-rw-r--r-- | src/decomp/expr/pseudo.c | 30 | ||||
-rw-r--r-- | src/decomp/expr/pseudo.h | 3 | ||||
-rw-r--r-- | src/glibext/Makefile.am | 1 | ||||
-rw-r--r-- | src/glibext/gnhash.c | 52 | ||||
-rw-r--r-- | src/glibext/gnhash.h | 37 |
19 files changed, 295 insertions, 25 deletions
diff --git a/src/arch/dalvik/dop_aget.c b/src/arch/dalvik/dop_aget.c index 77e6ef2..5ea57cc 100644 --- a/src/arch/dalvik/dop_aget.c +++ b/src/arch/dalvik/dop_aget.c @@ -52,13 +52,13 @@ GDecInstruction *dalvik_decomp_instr_aget(const GArchInstruction *instr, GDecCon GDecInstruction *access; /* Représentation de l'accès */ operand = g_arch_instruction_get_operand(instr, 0); - content = g_pseudo_register_new(); + content = g_dec_context_convert_register(ctx, operand); operand = g_arch_instruction_get_operand(instr, 1); - array = g_pseudo_register_new(); + array = g_dec_context_convert_register(ctx, operand); operand = g_arch_instruction_get_operand(instr, 2); - index = g_pseudo_register_new(); + index = g_dec_context_convert_register(ctx, operand); access = g_array_access_new(G_DEC_EXPRESSION(array), G_DEC_EXPRESSION(index)); result = g_assign_expression_new(G_DEC_EXPRESSION(content), G_DEC_EXPRESSION(access)); diff --git a/src/arch/dalvik/dop_aput.c b/src/arch/dalvik/dop_aput.c index 2e4527e..3b75667 100644 --- a/src/arch/dalvik/dop_aput.c +++ b/src/arch/dalvik/dop_aput.c @@ -52,13 +52,13 @@ GDecInstruction *dalvik_decomp_instr_aput(const GArchInstruction *instr, GDecCon GDecInstruction *access; /* Représentation de l'accès */ operand = g_arch_instruction_get_operand(instr, 0); - content = g_pseudo_register_new(); + content = g_dec_context_convert_register(ctx, operand); operand = g_arch_instruction_get_operand(instr, 1); - array = g_pseudo_register_new(); + array = g_dec_context_convert_register(ctx, operand); operand = g_arch_instruction_get_operand(instr, 2); - index = g_pseudo_register_new(); + index = g_dec_context_convert_register(ctx, operand); access = g_array_access_new(G_DEC_EXPRESSION(array), G_DEC_EXPRESSION(index)); result = g_assign_expression_new(G_DEC_EXPRESSION(access), G_DEC_EXPRESSION(content)); diff --git a/src/arch/dalvik/dop_arithm.c b/src/arch/dalvik/dop_arithm.c index 388f906..7657f99 100644 --- a/src/arch/dalvik/dop_arithm.c +++ b/src/arch/dalvik/dop_arithm.c @@ -51,7 +51,6 @@ GDecInstruction *dalvik_decomp_instr_arithm_2addr(const GArchInstruction *instr, GArchOperand *operand; /* Opérande de l'instruction */ GDecInstruction *dest; /* Enregistrement du résultat */ GDecInstruction *op1; /* Premier opérande utilisé */ - GDecInstruction *op2; /* Second opérande utilisé */ GDecInstruction *arithm; /* Opération arithmétique */ switch (g_dalvik_instruction_get_opcode(G_DALVIK_INSTRUCTION(instr))) @@ -84,15 +83,12 @@ GDecInstruction *dalvik_decomp_instr_arithm_2addr(const GArchInstruction *instr, } operand = g_arch_instruction_get_operand(instr, 0); - dest = g_pseudo_register_new(); + dest = g_dec_context_convert_register(ctx, operand); operand = g_arch_instruction_get_operand(instr, 1); - op1 = g_pseudo_register_new(); - - operand = g_arch_instruction_get_operand(instr, 2); - op2 = g_pseudo_register_new(); + op1 = g_dec_context_convert_register(ctx, operand); - arithm = g_arithm_expression_new(G_DEC_EXPRESSION(op1), type, G_DEC_EXPRESSION(op2)); + arithm = g_arithm_expression_new(G_DEC_EXPRESSION(dest), type, G_DEC_EXPRESSION(op1)); result = g_assign_expression_new(G_DEC_EXPRESSION(dest), G_DEC_EXPRESSION(arithm)); return result; @@ -159,10 +155,10 @@ GDecInstruction *dalvik_decomp_instr_arithm_lit(const GArchInstruction *instr, G } operand = g_arch_instruction_get_operand(instr, 0); - dest = g_pseudo_register_new(); + dest = g_dec_context_convert_register(ctx, operand); operand = g_arch_instruction_get_operand(instr, 1); - op1 = g_pseudo_register_new(); + op1 = g_dec_context_convert_register(ctx, operand); operand = g_arch_instruction_get_operand(instr, 2); op2 = g_imm_expression_new(G_IMM_OPERAND(operand)); diff --git a/src/arch/dalvik/dop_array.c b/src/arch/dalvik/dop_array.c index 035b3eb..fa9f94f 100644 --- a/src/arch/dalvik/dop_array.c +++ b/src/arch/dalvik/dop_array.c @@ -60,11 +60,11 @@ GDecInstruction *dalvik_decomp_instr_array_length(const GArchInstruction *instr, operand = g_arch_instruction_get_operand(instr, 1); - reg = g_pseudo_register_new(); + reg = g_dec_context_convert_register(ctx, operand); len = g_dalvik_alength_new(G_DEC_EXPRESSION(reg)); operand = g_arch_instruction_get_operand(instr, 0); - reg = g_pseudo_register_new(); + reg = g_dec_context_convert_register(ctx, operand); result = g_assign_expression_new(G_DEC_EXPRESSION(reg), G_DEC_EXPRESSION(len)); diff --git a/src/arch/dalvik/dop_const.c b/src/arch/dalvik/dop_const.c index eab7acd..ea88089 100644 --- a/src/arch/dalvik/dop_const.c +++ b/src/arch/dalvik/dop_const.c @@ -59,8 +59,8 @@ GDecInstruction *dalvik_decomp_instr_const(const GArchInstruction *instr, GDecCo - operand = g_arch_instruction_get_operand(instr, 1); - reg = g_pseudo_register_new(); + operand = g_arch_instruction_get_operand(instr, 0); + reg = g_dec_context_convert_register(ctx, operand); operand = g_arch_instruction_get_operand(instr, 1); imm = g_imm_expression_new(G_IMM_OPERAND(operand)); diff --git a/src/arch/dalvik/dop_invoke.c b/src/arch/dalvik/dop_invoke.c index e4fa1fb..6fdca06 100644 --- a/src/arch/dalvik/dop_invoke.c +++ b/src/arch/dalvik/dop_invoke.c @@ -117,7 +117,7 @@ GDecInstruction *dalvik_decomp_instr_invoke_virtual(const GArchInstruction *inst //GDecInstruction *g_routine_call_new(GBinRoutine *routine, bool is_object) /* operand = g_arch_instruction_get_operand(instr, 1); - reg = g_pseudo_register_new(); + reg = g_dec_context_convert_register(ctx, operand); operand = g_arch_instruction_get_operand(instr, 1); imm = g_imm_expression_new(G_IMM_OPERAND(operand)); @@ -141,8 +141,8 @@ GDecInstruction *dalvik_decomp_instr_invoke_virtual(const GArchInstruction *inst { case DOP_MOVE_RESULT: - operand = g_arch_instruction_get_operand(instr, 0); - reg = g_pseudo_register_new(); + operand = g_arch_instruction_get_operand(iter, 0); + reg = g_dec_context_convert_register(ctx, operand); result = g_assign_expression_new(G_DEC_EXPRESSION(reg), G_DEC_EXPRESSION(result)); diff --git a/src/arch/dalvik/operand.c b/src/arch/dalvik/operand.c index 9c4a2c2..3227184 100644 --- a/src/arch/dalvik/operand.c +++ b/src/arch/dalvik/operand.c @@ -87,6 +87,9 @@ static void g_dalvik_register_operand_class_init(GDalvikRegisterOperandClass *); /* Initialise une instance d'opérande de registre Dalvik. */ static void g_dalvik_register_operand_init(GDalvikRegisterOperand *); +/* Compare un opérande avec un autre. */ +static bool g_dalvik_register_operand_compare(const GDalvikRegisterOperand *, const GDalvikRegisterOperand *); + /* Ajoute du texte simple à un fichier ouvert en écriture. */ static void g_dalvik_register_operand_add_text(const GDalvikRegisterOperand *, GRenderingOptions *, MainRendering, FILE *); @@ -325,13 +328,18 @@ static void g_dalvik_register_operand_class_init(GDalvikRegisterOperandClass *kl static void g_dalvik_register_operand_init(GDalvikRegisterOperand *operand) { - GContentExporter *parent; /* Instance parente */ + GContentExporter *parent; /* Instance parente #1 */ + GArchOperand *arch; /* Instance parente #2 */ parent = G_CONTENT_EXPORTER(operand); parent->add_text = (add_text_fc)g_dalvik_register_operand_add_text; parent->export_buffer = (export_buffer_fc)g_dalvik_register_operand_to_buffer; + arch = G_ARCH_OPERAND(operand); + + arch->compare = (operand_compare_fc)g_dalvik_register_operand_compare; + } @@ -400,6 +408,26 @@ GArchOperand *g_dalvik_register_operand_new(const bin_t *data, off_t *pos, off_t /****************************************************************************** * * +* Paramètres : a = premier opérande à consulter. * +* b = second opérande à consulter. * +* * +* Description : Compare un opérande avec un autre. * +* * +* Retour : Bilan de la comparaison. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_dalvik_register_operand_compare(const GDalvikRegisterOperand *a, const GDalvikRegisterOperand *b) +{ + return g_dalvik_register_compare(a->reg, b->reg); + +} + + +/****************************************************************************** +* * * Paramètres : operand = opérande à transcrire. * * options = options de rendu. * * rendering = support effectif final des lignes de code. * diff --git a/src/arch/dalvik/register.c b/src/arch/dalvik/register.c index fc7757d..dd5a512 100644 --- a/src/arch/dalvik/register.c +++ b/src/arch/dalvik/register.c @@ -134,6 +134,35 @@ GDalvikRegister *g_dalvik_register_new(uint16_t index) } +/****************************************************************************** +* * +* Paramètres : a = premier opérande à consulter. * +* b = second opérande à consulter. * +* * +* Description : Compare un registre avec un autre. * +* * +* Retour : Bilan de la comparaison. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_dalvik_register_compare(const GDalvikRegister *a, const GDalvikRegister *b) +{ + /* FIXME : GCC (Debian 4.4.5-4) trouble ? */ + + if (a == NULL) + printf("Alerte :: %hd & %hd\n", a->index, b->index); + + /* + printf("Compare :: %p & %p\n", a, b); + printf("Compare :: %hd & %hd\n", a->index, b->index); + */ + + return (a->index == b->index); + +} + /****************************************************************************** * * diff --git a/src/arch/dalvik/register.h b/src/arch/dalvik/register.h index 5ac5617..7767a9b 100644 --- a/src/arch/dalvik/register.h +++ b/src/arch/dalvik/register.h @@ -54,6 +54,9 @@ GType g_dalvik_register_get_type(void); /* Crée une réprésentation de registre Dalvik. */ GDalvikRegister *g_dalvik_register_new(uint16_t); +/* Compare un registre avec un autre. */ +bool g_dalvik_register_compare(const GDalvikRegister *, const GDalvikRegister *); + /* Indique si le registre correspond à ebp ou similaire. */ bool g_dalvik_register_is_base_pointer(const GDalvikRegister *); diff --git a/src/arch/operand-int.h b/src/arch/operand-int.h index f21b995..51f392b 100644 --- a/src/arch/operand-int.h +++ b/src/arch/operand-int.h @@ -30,17 +30,22 @@ +/* Compare un opérande avec un autre. */ +typedef bool (* operand_compare_fc) (const GArchOperand *, const GArchOperand *); + /* Traduit un opérande en version humainement lisible. */ typedef char * (* get_operand_text_fc) (const GArchOperand *, const GExeFormat *, AsmSyntax); /* Traduit un opérande en version humainement lisible. */ typedef void (* operand_print_fc) (const GArchOperand *, GBufferLine *, AsmSyntax); + /* Définition générique d'un opérande d'architecture (instance) */ struct _GArchOperand { GContentExporter parent; /* A laisser en premier */ + operand_compare_fc compare; /* Comparaison d'opérandes */ get_operand_text_fc get_text; /* Texte humain équivalent */ operand_print_fc print; /* Texte humain équivalent */ diff --git a/src/arch/operand.c b/src/arch/operand.c index 16fc073..f3aecb6 100644 --- a/src/arch/operand.c +++ b/src/arch/operand.c @@ -117,3 +117,30 @@ void g_arch_operand_print(const GArchOperand *operand, GBufferLine *line, AsmSyn return operand->print(operand, line, syntax); } + + +/****************************************************************************** +* * +* Paramètres : a = premier opérande à consulter. * +* b = second opérande à consulter. * +* * +* Description : Compare un opérande avec un autre. * +* * +* Retour : Bilan de la comparaison. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_arch_operand_compare(const GArchOperand *a, const GArchOperand *b) +{ + bool result; /* Bilan à faire remonter */ + + result = (G_OBJECT_TYPE(G_OBJECT(a)) == G_OBJECT_TYPE(G_OBJECT(b))); + + if (result) + result = a->compare(a, b); + + return result; + +} diff --git a/src/arch/operand.h b/src/arch/operand.h index 3745a80..d22235e 100644 --- a/src/arch/operand.h +++ b/src/arch/operand.h @@ -55,6 +55,9 @@ char *g_arch_operand_get_text(const GArchOperand *, const GExeFormat *, AsmSynta /* Traduit un opérande en version humainement lisible. */ void g_arch_operand_print(const GArchOperand *, GBufferLine *, AsmSyntax); +/* Compare un opérande avec un autre. */ +bool g_arch_operand_compare(const GArchOperand *, const GArchOperand *); + #endif /* _ARCH_OPERAND_H */ diff --git a/src/decomp/context.c b/src/decomp/context.c index 7fe6937..6440c56 100644 --- a/src/decomp/context.c +++ b/src/decomp/context.c @@ -24,6 +24,14 @@ #include "context.h" +#include <malloc.h> + + +#include "expr/pseudo.h" +#include "../arch/operand.h" +#include "../glibext/gnhash.h" + + /* Définition d'une context décompilée (instance) */ struct _GDecContext @@ -32,6 +40,12 @@ struct _GDecContext vmpa_t max; /* Première adresse à écarter */ + GHashTable *machine; /* Correspondance reg./pseudo */ + GHashTable *ssa; /* Remplacement des pseudos */ + + GDecInstruction **pseudos; /* Liste des pseudos-registre */ + size_t count; /* Taille de cette liste */ + }; @@ -87,6 +101,8 @@ static void g_dec_context_class_init(GDecContextClass *klass) static void g_dec_context_init(GDecContext *ctx) { + ctx->machine = g_hash_table_new(g_constant_hash, (GEqualFunc)g_arch_operand_compare); + ctx->ssa = g_hash_table_new(NULL, NULL); } @@ -151,3 +167,42 @@ void g_dec_context_set_max_address(GDecContext *ctx, vmpa_t max) ctx->max = max; } + + +/****************************************************************************** +* * +* Paramètres : ctx = instance à consulter, voire mettre à jour. * +* operand = opérande représentant un registre quelconque. * +* * +* Description : Convertit un registre machine en un pseudo-registre. * +* * +* Retour : Pseudo-registre, existant ou non, prêt à emploi. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GDecInstruction *g_dec_context_convert_register(GDecContext *ctx, gpointer operand) +{ + GDecInstruction *result; /* Instance à retourner */ + gpointer *found; /* Pseudo-registre trouvé */ + + found = g_hash_table_lookup(ctx->machine, operand); + + if (found != NULL) result = G_DEC_INSTRUCTION(found); + else + { + result = g_pseudo_register_new(); + g_pseudo_register_set_index(G_PSEUDO_REGISTER(result), ctx->count); + + g_hash_table_insert(ctx->machine, operand, result); + + ctx->pseudos = (GDecInstruction **)realloc(ctx->pseudos, + ++ctx->count * sizeof(GDecInstruction *)); + ctx->pseudos[ctx->count - 1] = result; + + } + + return result; + +} diff --git a/src/decomp/context.h b/src/decomp/context.h index 76105e6..926a372 100644 --- a/src/decomp/context.h +++ b/src/decomp/context.h @@ -28,7 +28,7 @@ #include <glib-object.h> -#include "expr/pseudo.h" +#include "instruction.h" #include "../arch/archbase.h" @@ -61,6 +61,9 @@ vmpa_t g_dec_context_get_max_address(const GDecContext *); /* Définit l'adresse où la décompilation n'est plus souhaitée. */ void g_dec_context_set_max_address(GDecContext *, vmpa_t); +/* Convertit un registre machine en un pseudo-registre. */ +GDecInstruction *g_dec_context_convert_register(GDecContext *, gpointer); + #endif /* _DECOMP_CONTEXT_H */ diff --git a/src/decomp/expr/pseudo.c b/src/decomp/expr/pseudo.c index 393f32c..abfcd4d 100644 --- a/src/decomp/expr/pseudo.c +++ b/src/decomp/expr/pseudo.c @@ -24,6 +24,10 @@ #include "pseudo.h" +#include <stdio.h> +#include <string.h> + + #include "../expression-int.h" @@ -33,6 +37,8 @@ struct _GPseudoRegister { GDecExpression parent; /* A laisser en premier */ + size_t index; /* Position dans l'ensemble */ + }; @@ -141,8 +147,30 @@ GDecInstruction *g_pseudo_register_new(void) static void g_pseudo_register_print(const GPseudoRegister *reg, GCodeBuffer *buffer, GBufferLine *line, GLangOutput *output) { + char label[32]; + + snprintf(label, 32, "var%d", reg->index); + + g_buffer_line_insert_text(line, BLC_ASSEMBLY, label, strlen(label), RTT_RAW); - g_buffer_line_insert_text(line, BLC_ASSEMBLY, "varX", 4, RTT_RAW); +} + + +/****************************************************************************** +* * +* Paramètres : reg = expression représentant un pseudo-registre à traiter.* +* index = indice à associer au pseudo-registre. * +* * +* Description : Définit un indice unique pour un pseudo-registre donné. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ +void g_pseudo_register_set_index(GPseudoRegister *reg, size_t index) +{ + reg->index = index; } diff --git a/src/decomp/expr/pseudo.h b/src/decomp/expr/pseudo.h index 9734625..95612a9 100644 --- a/src/decomp/expr/pseudo.h +++ b/src/decomp/expr/pseudo.h @@ -54,6 +54,9 @@ GType g_pseudo_register_get_type(void); /* Assigne le contenu d'une expression dans une autre. */ GDecInstruction *g_pseudo_register_new(void); +/* Définit un indice unique pour un pseudo-registre donné. */ +void g_pseudo_register_set_index(GPseudoRegister *, size_t); + #endif /* _DECOMP_EXPR_PSEUDO_H */ diff --git a/src/glibext/Makefile.am b/src/glibext/Makefile.am index 1e21b58..2365190 100644 --- a/src/glibext/Makefile.am +++ b/src/glibext/Makefile.am @@ -7,6 +7,7 @@ libglibext_la_SOURCES = \ gbufferline.h gbufferline.c \ gbuffersegment.h gbuffersegment.c \ gcodebuffer.h gcodebuffer.c \ + gnhash.h gnhash.c \ proto.h libglibext_la_LDFLAGS = diff --git a/src/glibext/gnhash.c b/src/glibext/gnhash.c new file mode 100644 index 0000000..cdd4dd1 --- /dev/null +++ b/src/glibext/gnhash.c @@ -0,0 +1,52 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * gnhash.c - nouvelle fonction offrant une empreinte constante + * + * Copyright (C) 2010 Cyrille Bagard + * + * This file is part of OpenIDA. + * + * OpenIDA is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * OpenIDA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +#include "gnhash.h" + + + +/****************************************************************************** +* * +* Paramètres : v = pointeur quelconque. * +* * +* Description : Convertit un pointeur en une empreinte constante. * +* * +* Retour : 2. * +* * +* Remarques : L'algorithme actuel (12/11/10) de la GLib impose qu'une * +* même empreinte impose une même clef. Deux clefs distinctes, * +* pourtant égales, ont deux empreintes distinctes, donc on * +* définit une seule empreinte possible. Pas terrible, mais * +* cela répond au besoin (association simple clef <-> valeur). * +* * +******************************************************************************/ + +guint g_constant_hash(gconstpointer v) +{ + /** + * La valeur doit être supérieure à 1 pour ne + * pas être totalement inéfficace. + */ + return 2; + +} diff --git a/src/glibext/gnhash.h b/src/glibext/gnhash.h new file mode 100644 index 0000000..4c49357 --- /dev/null +++ b/src/glibext/gnhash.h @@ -0,0 +1,37 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * gnhash.h - prototype pour une nouvelle fonction offrant une empreinte constante + * + * Copyright (C) 2010 Cyrille Bagard + * + * This file is part of OpenIDA. + * + * OpenIDA is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * OpenIDA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +#ifndef _GLIBEXT_GNHASH_H +#define _GLIBEXT_GNHASH_H + + +#include <glib-object.h> + + + +/* Convertit un pointeur en une empreinte constante. */ +guint g_constant_hash(gconstpointer); + + + +#endif /* _GLIBEXT_GNHASH_H */ |