diff options
Diffstat (limited to 'src/arch')
-rw-r--r-- | src/arch/instruction.c | 34 | ||||
-rw-r--r-- | src/arch/instruction.h | 8 |
2 files changed, 33 insertions, 9 deletions
diff --git a/src/arch/instruction.c b/src/arch/instruction.c index 88033c9..55aee49 100644 --- a/src/arch/instruction.c +++ b/src/arch/instruction.c @@ -741,7 +741,7 @@ bool g_arch_instruction_has_link_to(GArchInstruction *instr, const GArchInstruct bool result; /* Bilan à retourner */ size_t count; /* Nombre de liens à parcourir */ size_t i; /* Boucle de parcours */ - instr_link_t *dlink; /* Définition de destination */ + const instr_link_t *dlink; /* Définition de destination */ result = false; @@ -755,6 +755,8 @@ bool g_arch_instruction_has_link_to(GArchInstruction *instr, const GArchInstruct result = (dlink->linked == dest); + unref_instr_link(dlink); + } g_arch_instruction_unlock_dest(instr); @@ -833,6 +835,15 @@ bool g_arch_instruction_change_link(GArchInstruction *instr, GArchInstruction *d result = false; + /** + * Note : pour la récupération des liens de sources et de destinations, + * on n'utilise pas les fonctions g_arch_instruction_get_(source|destination)(), + * qui renvoient un pointeur non modifiable. + * + * On a en effet besoin de modifier le type de lien. + */ + + g_arch_instruction_lock_src(dest); /* Côté destination */ @@ -841,7 +852,7 @@ bool g_arch_instruction_change_link(GArchInstruction *instr, GArchInstruction *d for (i = 0; i < count; i++) { - slink = g_arch_instruction_get_source(dest, i); + slink = get_flat_array_item(dest->from, i, sizeof(instr_link_t)); if (slink->linked == instr && slink->type == old) break; @@ -857,7 +868,7 @@ bool g_arch_instruction_change_link(GArchInstruction *instr, GArchInstruction *d for (i = 0; i < count; i++) { - dlink = g_arch_instruction_get_destination(instr, i); + dlink = get_flat_array_item(instr->to, i, sizeof(instr_link_t)); if (dlink->linked == dest && dlink->type == old) break; @@ -920,12 +931,14 @@ size_t g_arch_instruction_count_sources(const GArchInstruction *instr) * * ******************************************************************************/ -instr_link_t *g_arch_instruction_get_source(GArchInstruction *instr, size_t index) +const instr_link_t *g_arch_instruction_get_source(GArchInstruction *instr, size_t index) { instr_link_t *result; /* Détails présents à renvoyer */ result = get_flat_array_item(instr->from, index, sizeof(instr_link_t)); + ref_instr_link(result); + return result; } @@ -967,12 +980,14 @@ size_t g_arch_instruction_count_destinations(const GArchInstruction *instr) * * ******************************************************************************/ -instr_link_t *g_arch_instruction_get_destination(GArchInstruction *instr, size_t index) +const instr_link_t *g_arch_instruction_get_destination(GArchInstruction *instr, size_t index) { instr_link_t *result; /* Détails présents à renvoyer */ result = get_flat_array_item(instr->to, index, sizeof(instr_link_t)); + ref_instr_link(result); + return result; } @@ -996,7 +1011,7 @@ GArchInstruction *g_arch_instruction_get_given_destination(GArchInstruction *ins GArchInstruction *result; /* Résultat à remonter */ size_t count; /* Nombre de liens à parcourir */ size_t i; /* Boucle de parcours */ - instr_link_t *dest; /* Destination à étudier */ + const instr_link_t *dest; /* Destination à étudier */ result = NULL; @@ -1014,6 +1029,8 @@ GArchInstruction *g_arch_instruction_get_given_destination(GArchInstruction *ins g_object_ref(G_OBJECT(result)); } + unref_instr_link(dest); + } g_arch_instruction_unlock_dest(instr); @@ -1287,7 +1304,7 @@ static bool g_arch_instruction_serialize(GArchInstruction *instr, GAsmStorage *s GArchOperand *op; /* Opérande à traiter */ off64_t pos; /* Position dans le flux */ size_t kept; /* Nombre de liens conservés */ - instr_link_t *link; /* Lien vers une instruction */ + const instr_link_t *link; /* Lien vers une instruction */ result = pack_mrange(&instr->range, pbuf); @@ -1370,6 +1387,8 @@ static bool g_arch_instruction_serialize(GArchInstruction *instr, GAsmStorage *s if (link->type != ILT_REF) kept++; + unref_instr_link(link); + } result = extend_packed_buffer(pbuf, &kept, sizeof(size_t), true); @@ -1378,6 +1397,7 @@ static bool g_arch_instruction_serialize(GArchInstruction *instr, GAsmStorage *s { link = g_arch_instruction_get_destination(instr, i); result = serialize_link(link); + unref_instr_link(link); } g_arch_instruction_unlock_dest(instr); diff --git a/src/arch/instruction.h b/src/arch/instruction.h index aadd2fc..34dc59f 100644 --- a/src/arch/instruction.h +++ b/src/arch/instruction.h @@ -211,6 +211,10 @@ typedef struct _instr_link_t } instr_link_t; +#define ref_instr_link(l) g_object_ref(G_OBJECT(l->linked)); +#define unref_instr_link(l) g_object_unref(G_OBJECT(l->linked)); + + /* Met à disposition un encadrement des accès aux liens. */ void g_arch_instruction_lock_unlock_links(GArchInstruction *, bool, bool); @@ -230,7 +234,7 @@ bool g_arch_instruction_change_link(GArchInstruction *, GArchInstruction *, Inst size_t g_arch_instruction_count_sources(const GArchInstruction *); /* Fournit les détails d'une origine d'une instruction donnée. */ -instr_link_t *g_arch_instruction_get_source(GArchInstruction *, size_t); +const instr_link_t *g_arch_instruction_get_source(GArchInstruction *, size_t); #define g_arch_instruction_lock_dest(ins) g_arch_instruction_lock_unlock_links(ins, false, true) #define g_arch_instruction_unlock_dest(ins) g_arch_instruction_lock_unlock_links(ins, false, false) @@ -239,7 +243,7 @@ instr_link_t *g_arch_instruction_get_source(GArchInstruction *, size_t); size_t g_arch_instruction_count_destinations(const GArchInstruction *); /* Fournit les détails d'une destination d'une instruction. */ -instr_link_t *g_arch_instruction_get_destination(GArchInstruction *, size_t); +const instr_link_t *g_arch_instruction_get_destination(GArchInstruction *, size_t); /* Fournit la destination d'une instruction et d'un type donné. */ GArchInstruction *g_arch_instruction_get_given_destination(GArchInstruction *, InstructionLinkType); |