/* OpenIDA - Outil d'analyse de fichiers binaires * instruction.c - gestion générique des instructions * * Copyright (C) 2008 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 . */ #include "instruction.h" #include #include "instruction-int.h" #include "../common/extstr.h" /* Initialise la classe générique des instructions. */ static void g_arch_instruction_class_init(GArchInstructionClass *); /* Initialise une instance d'opérande d'architecture. */ static void g_arch_instruction_init(GArchInstruction *); /* Indique le type défini pour une instruction d'architecture. */ G_DEFINE_TYPE(GArchInstruction, g_arch_instruction, G_TYPE_OBJECT); /****************************************************************************** * * * Paramètres : klass = classe à initialiser. * * * * Description : Initialise la classe générique des instructions. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void g_arch_instruction_class_init(GArchInstructionClass *klass) { } /****************************************************************************** * * * Paramètres : instr = instance à initialiser. * * * * Description : Initialise une instance d'instruction d'architecture. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void g_arch_instruction_init(GArchInstruction *instr) { } /****************************************************************************** * * * Paramètres : instr = instruction quelconque à modifier. * * offset = position physique dans le code binaire. * * length = taille de l'instruction. * * address = adresse virtuelle ou position physique. * * * * Description : Définit la localisation d'une instruction. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ void g_arch_instruction_set_location(GArchInstruction *instr, off_t offset, off_t length, vmpa_t address) { instr->offset = offset; instr->length = length; instr->address = address; } /****************************************************************************** * * * Paramètres : instr = instruction quelconque à consulter. * * offset = position physique dans le code binaire/NULL. [OUT] * * length = taille de l'instruction ou NULL. [OUT] * * address = adresse virtuelle ou position physique/NULL. [OUT] * * * * Description : Fournit la localisation d'une instruction. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ void g_arch_instruction_get_location(GArchInstruction *instr, off_t *offset, off_t *length, vmpa_t *address) { if (offset != NULL) *offset = instr->offset; if (length != NULL) *length = instr->length; if (address != NULL) *address = instr->address; } /****************************************************************************** * * * Paramètres : instr = instance à mettre à jour. * * opererand = instruction à venir associer. * * * * Description : Attache un seul opérande à un instruction. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ void g_arch_instruction_attach_one_operand(GArchInstruction *instr, GArchOperand *operand) { instr->operands = (GArchOperand **)calloc(1, sizeof(GArchOperand *)); instr->operands_count = 1; instr->operands[0] = operand; } /****************************************************************************** * * * Paramètres : instr = instance à mettre à jour. * * operand1 = première instruction à venir associer. * * operand2 = seconde instruction à venir associer. * * * * Description : Attache deux opérandes à un instruction. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ void g_arch_instruction_attach_two_operands(GArchInstruction *instr, GArchOperand *operand1, GArchOperand *operand2) { instr->operands = (GArchOperand **)calloc(2, sizeof(GArchOperand *)); instr->operands_count = 2; instr->operands[0] = operand1; instr->operands[1] = operand2; } /****************************************************************************** * * * Paramètres : instr = instance à mettre à jour. * * opererand = instruction à venir associer. * * * * Description : Attache un opérande supplémentaire à une instruction. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ void g_arch_instruction_attach_extra_operand(GArchInstruction *instr, GArchOperand *operand) { instr->operands_count++; instr->operands = (GArchOperand **)realloc(instr->operands, instr->operands_count * sizeof(GArchOperand *)); instr->operands[instr->operands_count - 1] = operand; } /****************************************************************************** * * * Paramètres : instr = instance à consulter. * * * * Description : Indique la quantité d'opérandes présents dans l'instruction. * * * * Retour : Nombre d'opérandes attachés. * * * * Remarques : - * * * ******************************************************************************/ size_t g_arch_instruction_count_operands(const GArchInstruction *instr) { return instr->operands_count; } /****************************************************************************** * * * Paramètres : instr = instance à mettre à jour. * * index = indice de l'opérande concernée. * * * * Description : Fournit un opérande donné d'une instruction. * * * * Retour : Opérande trouvée ou NULL si aucune. * * * * Remarques : - * * * ******************************************************************************/ const GArchOperand *g_arch_instruction_get_operand(GArchInstruction *instr, size_t index) { const GArchOperand *result; /* Opérande à retourner */ if (index >= instr->operands_count) result = NULL; else result = instr->operands[index]; return result; } /****************************************************************************** * * * Paramètres : instr = instance à mettre à jour. * * new = nouvelle opérande à attacher. * * old = ancienne opérande à détacher. * * * * Description : Replace un opérande d'une instruction par un autre. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ void g_arch_instruction_replace_operand(GArchInstruction *instr, GArchOperand *new, const GArchOperand *old) { size_t i; /* Boucle de parcours */ for (i = 0; i < instr->operands_count; i++) if (instr->operands[i] == old) break; if (i < instr->operands_count) instr->operands[i] = new; } /****************************************************************************** * * * Paramètres : instr = instance à mettre à jour. * * opererand = instruction à venir dissocier. * * * * Description : Détache un opérande liée d'une instruction. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ void g_arch_instruction_detach_operand(GArchInstruction *instr, GArchOperand *operand) { size_t i; /* Boucle de parcours */ for (i = 0; i < instr->operands_count; i++) if (instr->operands[i] == operand) break; if ((i + 1) < instr->operands_count) memmove(&instr->operands[i], &instr->operands[i + 1], (instr->operands_count - i - 1) * sizeof(GArchOperand *)); instr->operands_count--; instr->operands = (GArchOperand **)realloc(instr->operands, instr->operands_count * sizeof(GArchOperand *)); } /****************************************************************************** * * * Paramètres : instr = instruction à traiter. * * format = format du binaire manipulé. * * syntax = type de représentation demandée. * * * * Description : Traduit une instruction en version humainement lisible. * * * * Retour : Chaîne de caractères à libérer de la mémoire. * * * * Remarques : - * * * ******************************************************************************/ char *g_arch_instruction_get_text(const GArchInstruction *instr, const GExeFormat *format, AsmSyntax syntax) { char *result; /* Chaîne à retourner */ size_t i; /* Boucle de parcours */ char *opstr; /* Chaîne d'opérande */ if (instr->operands_count == 0) result = strdup(instr->get_text(instr, format, syntax)); else { result = g_arch_operand_get_text(G_ARCH_INSTRUCTION(instr)->operands[0], format, syntax); for (i = 1; i < instr->operands_count; i++) { result = stradd(result, ", "); opstr = g_arch_operand_get_text(G_ARCH_INSTRUCTION(instr)->operands[i], format, syntax); result = stradd(result, opstr); free(opstr); } result = strprep(result, "\t"); result = strprep(result, instr->get_text(instr, format, syntax)); } return result; } /****************************************************************************** * * * Paramètres : instr = instruction à consulter. * * addr = eventuelle adresse associée à faire connaître. [OUT] * * * * Description : Informe sur une éventuelle référence à une autre instruction.* * * * Retour : Type de lien trouvé ou ILT_NONE si aucun. * * * * Remarques : - * * * ******************************************************************************/ InstructionLinkType g_arch_instruction_get_link(const GArchInstruction *instr, vmpa_t *addr) { return instr->get_link(instr, addr); } /****************************************************************************** * * * Paramètres : instr = instruction à consulter. * * * * Description : Indique si l'instruction correspond à un retour de fonction. * * * * Retour : true si l'instruction est un 'return' quelconque ou false. * * * * Remarques : - * * * ******************************************************************************/ bool g_arch_instruction_is_return(const GArchInstruction *instr) { return instr->is_return(instr); }