summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog62
-rw-r--r--configure.ac1
-rw-r--r--src/analysis/binary.c12
-rw-r--r--src/arch/Makefile.am3
-rw-r--r--src/arch/immediate.c20
-rw-r--r--src/arch/instruction.c58
-rw-r--r--src/arch/instruction.h8
-rw-r--r--src/arch/mips/Makefile.am30
-rw-r--r--src/arch/mips/instruction.c285
-rw-r--r--src/arch/mips/instruction.h105
-rw-r--r--src/arch/mips/op_add.c95
-rw-r--r--src/arch/mips/op_and.c62
-rw-r--r--src/arch/mips/op_branch.c161
-rw-r--r--src/arch/mips/op_jump.c114
-rw-r--r--src/arch/mips/op_load.c128
-rw-r--r--src/arch/mips/op_nop.c58
-rw-r--r--src/arch/mips/op_sr.c62
-rw-r--r--src/arch/mips/op_store.c95
-rw-r--r--src/arch/mips/op_sub.c95
-rw-r--r--src/arch/mips/opcodes.h107
-rw-r--r--src/arch/mips/operand.c649
-rw-r--r--src/arch/mips/operand.h156
-rw-r--r--src/arch/mips/processor.c253
-rw-r--r--src/arch/mips/processor.h53
-rw-r--r--src/arch/mips/registers.c249
-rw-r--r--src/arch/mips/registers.h51
-rw-r--r--src/arch/processor.c4
-rw-r--r--src/arch/processor.h3
-rw-r--r--src/arch/x86/instruction.c507
-rw-r--r--src/arch/x86/op_jump.c2
-rw-r--r--src/arch/x86/op_scas.c63
-rw-r--r--src/arch/x86/operand.c14
-rw-r--r--src/arch/x86/operand.h10
-rw-r--r--src/arch/x86/registers.c530
-rw-r--r--src/arch/x86/registers.h54
-rw-r--r--src/format/elf/e_elf.c20
-rw-r--r--src/format/exe_format.c20
-rw-r--r--src/format/exe_format.h3
38 files changed, 4172 insertions, 30 deletions
diff --git a/ChangeLog b/ChangeLog
index 48619cb..a722f65 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,65 @@
+09-05-31 Cyrille Bagard <nocbos@gmail.com>
+
+ * configure.ac:
+ Add the new Makefile from 'src/arch/mips' directory to AC_CONFIG_FILES.
+
+ * src/analysis/binary.c:
+ Support a new architecture (MIPS).
+
+ * src/arch/immediate.c:
+ Fix a bug when printing positive signed values.
+
+ * src/arch/instruction.c:
+ * src/arch/instruction.h:
+ Improve the way operands are handled.
+
+ * src/arch/Makefile.am:
+ Add mips/libarchmips.la to libarch_la_LIBADD and mips to SUBDIRS.
+
+ * src/arch/mips/instruction.c:
+ * src/arch/mips/instruction.h:
+ * src/arch/mips/Makefile.am:
+ * src/arch/mips/op_add.c:
+ * src/arch/mips/op_and.c:
+ * src/arch/mips/op_branch.c:
+ * src/arch/mips/opcodes.h:
+ * src/arch/mips/operand.c:
+ * src/arch/mips/operand.h:
+ * src/arch/mips/op_jump.c:
+ * src/arch/mips/op_load.c:
+ * src/arch/mips/op_nop.c:
+ * src/arch/mips/op_sr.c:
+ * src/arch/mips/op_store.c:
+ * src/arch/mips/op_sub.c:
+ * src/arch/mips/processor.c:
+ * src/arch/mips/processor.h:
+ * src/arch/mips/registers.c:
+ * src/arch/mips/registers.h:
+ New entries: add enough support of the MIPS architecture to disassemble
+ a basic 'hello world' program.
+
+ * src/arch/processor.c:
+ * src/arch/processor.h:
+ Support a new architecture (MIPS).
+
+ * src/arch/x86/instruction.c:
+ New entries: add missing files from previous commit.
+
+ * src/arch/x86/operand.c:
+ * src/arch/x86/operand.h:
+ * src/arch/x86/op_jump.c:
+ Typo.
+
+ * src/arch/x86/op_scas.c:
+ * src/arch/x86/registers.c:
+ * src/arch/x86/registers.h:
+ New entries: add missing files from previous commit.
+
+ * src/format/elf/e_elf.c:
+ * src/format/exe_format.c:
+ * src/format/exe_format.h:
+ Support a new architecture (MIPS). Make the loading more verbose.
+
09-05-25 Cyrille Bagard <nocbos@gmail.com>
* src/analysis/binary.c:
diff --git a/configure.ac b/configure.ac
index 68195e0..e533967 100644
--- a/configure.ac
+++ b/configure.ac
@@ -220,6 +220,7 @@ AC_CONFIG_FILES([Makefile
src/analysis/Makefile
src/arch/Makefile
src/arch/jvm/Makefile
+ src/arch/mips/Makefile
src/arch/x86/Makefile
src/common/Makefile
src/debug/Makefile
diff --git a/src/analysis/binary.c b/src/analysis/binary.c
index 2c9166c..84401a3 100644
--- a/src/analysis/binary.c
+++ b/src/analysis/binary.c
@@ -116,14 +116,18 @@ openida_binary *load_binary_file(const char *filename)
switch (get_exe_target_machine(result->format))
{
- case FTM_386:
- result->proc = get_arch_processor_for_type(APT_386);
- break;
-
case FTM_JVM:
result->proc = get_arch_processor_for_type(APT_JVM);
break;
+ case FTM_MIPS:
+ result->proc = get_arch_processor_for_type(APT_MIPS);
+ break;
+
+ case FTM_386:
+ result->proc = get_arch_processor_for_type(APT_386);
+ break;
+
default:
goto lbf_error;
break;
diff --git a/src/arch/Makefile.am b/src/arch/Makefile.am
index 0f4c9f5..6a1d45b 100644
--- a/src/arch/Makefile.am
+++ b/src/arch/Makefile.am
@@ -14,6 +14,7 @@ libarch_la_SOURCES = \
libarch_la_LIBADD = \
jvm/libarchjvm.la \
+ mips/libarchmips.la \
x86/libarchx86.la
libarch_la_LDFLAGS =
@@ -26,4 +27,4 @@ AM_CPPFLAGS =
AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS)
-SUBDIRS = jvm x86
+SUBDIRS = jvm mips x86
diff --git a/src/arch/immediate.c b/src/arch/immediate.c
index 7ef1220..f8c2474 100644
--- a/src/arch/immediate.c
+++ b/src/arch/immediate.c
@@ -370,16 +370,28 @@ static char *g_imm_operand_get_text(const GImmOperand *operand, const exe_format
snprintf(result, 19, "0x%llx", operand->unsigned_imm.val64);
break;
case AOS_8_BITS_SIGNED:
- snprintf(result, 19, "0x%hhx", ~operand->signed_imm.val8 + 1);
+ if (g_imm_operand_is_negative(operand))
+ snprintf(result, 19, "0x%hhx", ~operand->signed_imm.val8 + 1);
+ else
+ snprintf(result, 19, "0x%hhx", operand->signed_imm.val8);
break;
case AOS_16_BITS_SIGNED:
- snprintf(result, 19, "0x%hx", ~operand->signed_imm.val16 + 1);
+ if (g_imm_operand_is_negative(operand))
+ snprintf(result, 19, "0x%hx", ~operand->signed_imm.val16 + 1);
+ else
+ snprintf(result, 19, "0x%hx", operand->signed_imm.val16);
break;
case AOS_32_BITS_SIGNED:
- snprintf(result, 19, "0x%x", ~operand->signed_imm.val32 + 1);
+ if (g_imm_operand_is_negative(operand))
+ snprintf(result, 19, "0x%x", ~operand->signed_imm.val32 + 1);
+ else
+ snprintf(result, 19, "0x%x", operand->signed_imm.val32);
break;
case AOS_64_BITS_SIGNED:
- snprintf(result, 19, "0x%llx", ~operand->signed_imm.val64 + 1);
+ if (g_imm_operand_is_negative(operand))
+ snprintf(result, 19, "0x%llx", ~operand->signed_imm.val64 + 1);
+ else
+ snprintf(result, 19, "0x%llx", operand->signed_imm.val64);
break;
}
break;
diff --git a/src/arch/instruction.c b/src/arch/instruction.c
index 073f55c..21e72b7 100644
--- a/src/arch/instruction.c
+++ b/src/arch/instruction.c
@@ -134,7 +134,7 @@ void g_arch_instruction_get_location(GArchInstruction *instr, off_t *offset, off
* Paramètres : instr = instance à mettre à jour. *
* opererand = instruction à venir associer. *
* *
-* Description : Attache une seule opérande à une instruction. *
+* Description : Attache un seul opérande à un instruction. *
* *
* Retour : - *
* *
@@ -158,7 +158,7 @@ void g_arch_instruction_attach_one_operand(GArchInstruction *instr, GArchOperand
* operand1 = première instruction à venir associer. *
* operand2 = seconde instruction à venir associer. *
* *
-* Description : Attache deux opérandes à une instruction. *
+* Description : Attache deux opérandes à un instruction. *
* *
* Retour : - *
* *
@@ -179,6 +179,60 @@ void g_arch_instruction_attach_two_operands(GArchInstruction *instr, GArchOperan
/******************************************************************************
* *
+* 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 à 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. *
diff --git a/src/arch/instruction.h b/src/arch/instruction.h
index 08f459f..ff0fd4a 100644
--- a/src/arch/instruction.h
+++ b/src/arch/instruction.h
@@ -73,12 +73,18 @@ void g_arch_instruction_set_location(GArchInstruction *, off_t, off_t, vmpa_t);
/* Fournit la localisation d'une instruction. */
void g_arch_instruction_get_location(GArchInstruction *, off_t *, off_t *, vmpa_t *);
-/* Attache une seule opérande à une instruction. */
+/* Attache un seul opérande à une instruction. */
void g_arch_instruction_attach_one_operand(GArchInstruction *, GArchOperand *);
/* Attache deux opérandes à une instruction. */
void g_arch_instruction_attach_two_operands(GArchInstruction *, GArchOperand *, GArchOperand *);
+/* Attache un opérande supplémentaire à une instruction. */
+void g_arch_instruction_attach_extra_operand(GArchInstruction *, GArchOperand *);
+
+/* Détache un opérande liée d'une instruction. */
+void g_arch_instruction_detach_operand(GArchInstruction *, GArchOperand *);
+
/* Traduit une instruction en version humainement lisible. */
char *g_arch_instruction_get_text(const GArchInstruction *, const exe_format *, AsmSyntax);
diff --git a/src/arch/mips/Makefile.am b/src/arch/mips/Makefile.am
new file mode 100644
index 0000000..7b25864
--- /dev/null
+++ b/src/arch/mips/Makefile.am
@@ -0,0 +1,30 @@
+
+noinst_LTLIBRARIES = libarchmips.la
+
+libarchmips_la_SOURCES = \
+ instruction.h instruction.c \
+ op_add.c \
+ op_and.c \
+ op_branch.c \
+ op_jump.c \
+ op_load.c \
+ op_nop.c \
+ op_sr.c \
+ op_store.c \
+ op_sub.c \
+ opcodes.h \
+ operand.h operand.c \
+ processor.h processor.c \
+ registers.h registers.c
+
+libarchmips_la_CFLAGS = $(AM_CFLAGS)
+
+
+INCLUDES = $(LIBGTK_CFLAGS)
+
+AM_CPPFLAGS =
+
+AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS)
+
+
+SUBDIRS =
diff --git a/src/arch/mips/instruction.c b/src/arch/mips/instruction.c
new file mode 100644
index 0000000..54999a1
--- /dev/null
+++ b/src/arch/mips/instruction.c
@@ -0,0 +1,285 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * instruction.c - gestion des instructions de l'architecture MIPS
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "instruction.h"
+
+
+#include "../instruction-int.h"
+#include "../../common/endianness.h"
+
+
+
+
+
+
+
+/* Définition générique d'une instruction d'architecture mips (instance) */
+struct _GMipsInstruction
+{
+ GArchInstruction parent; /* A laisser en premier */
+
+ MipsOpcodes type; /* Position dans la liste */
+
+};
+
+/* Définition générique d'une instruction d'architecture mips (classe) */
+struct _GMipsInstructionClass
+{
+ GArchInstructionClass parent; /* A laisser en premier */
+
+};
+
+
+/* Initialise la classe des instructions pour mips. */
+static void g_mips_instruction_class_init(GMipsInstructionClass *);
+
+/* Initialise une instance d'opérande d'architecture mips. */
+static void g_mips_instruction_init(GMipsInstruction *);
+
+
+
+/* --------------------- AIDE A LA MISE EN PLACE D'INSTRUCTIONS --------------------- */
+
+
+/* Répertoire de toutes les instructions MIPS */
+typedef struct _mips_instruction
+{
+ bin_t opcode; /* Opcode de l'instruction */
+
+ bool has_rt_mask; /* Condition sur les bits rt ? */
+ bin_t rt_mask; /* Masque à retrouver 16<->20 */
+
+ bool has_funct; /* Extension d'opcode ? */
+ bin_t funct; /* Seconde partie de l'opcode */
+
+ const char *keyword; /* Mot clef de la commande */
+
+} mips_instruction;
+
+
+
+static mips_instruction _instructions[MOP_COUNT] = {
+
+ [MOP_NOP] = { 0x00, false, 0x00, true, 0x00, "nop" },
+
+ [MOP_SRA] = { 0x00, false, 0x00, true, 0x03, "sra" },
+
+
+ [MOP_JR] = { 0x00, false, 0x00, true, 0x08, "jr" },
+ [MOP_JALR] = { 0x00, false, 0x00, true, 0x09, "jalr" },
+ [MOP_JALR_HB] = { 0x00, false, 0x00, true, 0x09, "jalr.hb" }, /* Présent uniquement pour l'affichage */
+
+
+
+ [MOP_ADDU] = { 0x00, false, 0x00, true, 0x21, "addu" },
+ [MOP_SUB] = { 0x00, false, 0x00, true, 0x22, "sub" },
+ [MOP_SUBU] = { 0x00, false, 0x00, true, 0x23, "subu" },
+
+ [MOP_AND] = { 0x00, false, 0x00, true, 0x24, "and" },
+
+
+ [MOP_BGEZAL] = { 0x04, true, 0x11, false, 0x00, "bgezal" },
+
+
+ [MOP_BEQ] = { 0x10, false, 0x00, false, 0x00, "beq" },
+
+ [MOP_BNE] = { 0x14, false, 0x00, false, 0x00, "bne" },
+
+ [MOP_ADDIU] = { 0x24, false, 0x00, false, 0x00, "addiu" },
+
+ [MOP_BEQL] = { 0x50, false, 0x00, false, 0x00, "beql" },
+
+
+ [MOP_LW] = { 0x8c, false, 0x00, false, 0x00, "lw" },
+
+ [MOP_LUI] = { 0x3c, false, 0x00, false, 0x00, "lui" },
+
+
+ [MOP_LBU] = { 0x90, false, 0x00, false, 0x00, "lbu" },
+
+ [MOP_SB] = { 0xa0, false, 0x00, false, 0x00, "sb" },
+ [MOP_SW] = { 0xac, false, 0x00, false, 0x00, "sw" }
+
+};
+
+
+
+
+/* Traduit une instruction en version humainement lisible. */
+static const char *mips_get_instruction_text(const GMipsInstruction *, const exe_format *, AsmSyntax);
+
+
+
+
+
+
+
+
+
+/* Indique le type défini pour une instruction d'architecture mips. */
+G_DEFINE_TYPE(GMipsInstruction, g_mips_instruction, G_TYPE_ARCH_INSTRUCTION);
+
+
+
+/******************************************************************************
+* *
+* Paramètres : klass = classe à initialiser. *
+* *
+* Description : Initialise la classe des instructions pour MIPS. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_mips_instruction_class_init(GMipsInstructionClass *klass)
+{
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : instr = instance à initialiser. *
+* *
+* Description : Initialise une instance d'instruction d'architecture MIPS. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_mips_instruction_init(GMipsInstruction *instr)
+{
+ GArchInstruction *parent; /* Instance parente */
+
+ parent = G_ARCH_INSTRUCTION(instr);
+
+ parent->get_text = (get_instruction_text_fc)mips_get_instruction_text;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : type = type d'instruction à représenter. *
+* *
+* Description : Crée une instruction pour l'architecture MIPS. *
+* *
+* Retour : Architecture mise en place. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GArchInstruction *g_mips_instruction_new(MipsOpcodes type)
+{
+ GArchInstruction *result; /* Structure à retourner */
+
+ result = g_object_new(G_TYPE_MIPS_INSTRUCTION, NULL);
+
+ G_MIPS_INSTRUCTION(result)->type = type;
+
+ return result;
+
+}
+
+
+
+
+
+
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* AIDE A LA MISE EN PLACE D'INSTRUCTIONS */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+* *
+* Paramètres : data = flux de données à analyser. *
+* pos = position courante dans ce flux. *
+* len = taille totale des données à analyser. *
+* *
+* Description : Recherche l'identifiant de la prochaine instruction. *
+* *
+* Retour : Identifiant de la prochaine instruction à tenter de charger. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+MipsOpcodes mips_guess_next_instruction(const bin_t *data, off_t pos, off_t len)
+{
+ MipsOpcodes result; /* Identifiant à retourner */
+ uint32_t code; /* Code binaire à décoder */
+
+ if (!read_u32(&code, data, &pos, len, SRE_LITTLE/* FIXME */))
+ return MOP_COUNT;
+
+ for (result = 0; result < MOP_COUNT; result++)
+ {
+ if ((code & 0xfc000000) != (_instructions[result].opcode << 24)) continue;
+
+ if (_instructions[result].has_rt_mask
+ && (code & 0x001f0000) != (_instructions[result].rt_mask << 16)) continue;
+
+ if (_instructions[result].has_funct
+ && (code & 0x0000003f) != _instructions[result].funct) continue;
+
+ break;
+
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* 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 : - *
+* *
+******************************************************************************/
+
+static const char *mips_get_instruction_text(const GMipsInstruction *instr, const exe_format *format, AsmSyntax syntax)
+{
+ const char *result; /* Chaîne à retourner */
+
+ result = strdup(_instructions[instr->type].keyword);
+
+ return result;
+
+}
diff --git a/src/arch/mips/instruction.h b/src/arch/mips/instruction.h
new file mode 100644
index 0000000..79b63f9
--- /dev/null
+++ b/src/arch/mips/instruction.h
@@ -0,0 +1,105 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * instruction.h - prototypes pour la gestion des instructions de l'architecture MIPS
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _ARCH_MIPS_INSTRUCTION_H
+#define _ARCH_MIPS_INSTRUCTION_H
+
+
+#include "../instruction.h"
+
+
+
+
+
+
+/* Enumération de tous les opcodes */
+typedef enum _MipsOpcodes
+{
+ MOP_NOP, /* nop (0x00 ... 0x00) */
+
+ MOP_SRA, /* sra (0x00 ... 0x03) */
+
+ MOP_JR, /* jr (0x00 ... 0x08) */
+ MOP_JALR, /* jalr (0x00 ... 0x09) */
+ MOP_JALR_HB, /* jalr.hb (0x00 ... 0x09) */
+
+
+ MOP_ADDU, /* addu (0x00 ... 0x21) */
+ MOP_SUB, /* sub (0x00 ... 0x22) */
+ MOP_SUBU, /* subu (0x00 ... 0x23) */
+
+ MOP_AND, /* and (0x00 ... 0x24) */
+
+ MOP_BGEZAL, /* bgezal (0x04 ... 0x11 ...) */
+
+ MOP_BEQ, /* beq (0x10) */
+ MOP_BNE, /* bne (0x14) */
+
+ MOP_ADDIU, /* addiu (0x24) */
+
+ MOP_BEQL, /* beql (0x50) */
+
+ MOP_LW, /* lw (0x8c) */
+ MOP_LUI, /* lui (0x3c) */
+
+ MOP_LBU, /* lbu (0x90) */
+
+ MOP_SB, /* sb (0xa0) */
+ MOP_SW, /* sw (0xac) */
+
+ MOP_COUNT
+
+
+} MipsOpcodes;
+
+
+#define G_TYPE_MIPS_INSTRUCTION g_mips_instruction_get_type()
+#define G_MIPS_INSTRUCTION(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_mips_instruction_get_type(), GMipsInstruction))
+#define G_IS_MIPS_INSTRUCTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_mips_instruction_get_type()))
+#define G_MIPS_INSTRUCTION_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE((inst), g_mips_instruction_get_type(), GMipsInstructionIface))
+
+
+/* Définition générique d'une instruction d'architecture MIPS (instance) */
+typedef struct _GMipsInstruction GMipsInstruction;
+
+/* Définition générique d'une instruction d'architecture MIPS (classe) */
+typedef struct _GMipsInstructionClass GMipsInstructionClass;
+
+
+/* Indique le type défini pour une instruction d'architecture MIPS. */
+GType g_mips_instruction_get_type(void);
+
+/* Crée une instruction pour l'architecture MIPS. */
+GArchInstruction *g_mips_instruction_new(MipsOpcodes);
+
+
+
+/* --------------------- AIDE A LA MISE EN PLACE D'INSTRUCTIONS --------------------- */
+
+
+/* Recherche l'identifiant de la prochaine instruction. */
+MipsOpcodes mips_guess_next_instruction(const bin_t *, off_t, off_t);
+
+
+
+#endif /* _ARCH_MIPS_INSTRUCTION_H */
diff --git a/src/arch/mips/op_add.c b/src/arch/mips/op_add.c
new file mode 100644
index 0000000..a82cbf4
--- /dev/null
+++ b/src/arch/mips/op_add.c
@@ -0,0 +1,95 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * op_add.c - décodage des additions
+ *
+ * Copyright (C) 2009 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 "opcodes.h"
+
+
+#include "../instruction-int.h"
+#include "operand.h"
+
+
+
+/******************************************************************************
+* *
+* Paramètres : data = flux de données à analyser. *
+* pos = position courante dans ce flux. [OUT] *
+* len = taille totale des données à analyser. *
+* addr = adresse virtuelle de l'instruction. *
+* proc = architecture ciblée par le désassemblage. *
+* *
+* Description : Décode une instruction de type 'addiu rt, rs, imm'. *
+* *
+* Retour : Instruction mise en place ou NULL. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GArchInstruction *mips_read_instr_add_immediate_unsigned(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GMipsProcessor *proc)
+{
+ GArchInstruction *result; /* Instruction à retourner */
+
+ result = g_mips_instruction_new(MOP_ADDIU);
+
+ if (!mips_read_n_operands(result, data, pos, len, 3, MIPS_OTP_RT, MIPS_OTP_RS, MIPS_OTP_IMMEDIATE))
+ {
+ /* TODO free(result);*/
+ return NULL;
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : data = flux de données à analyser. *
+* pos = position courante dans ce flux. [OUT] *
+* len = taille totale des données à analyser. *
+* addr = adresse virtuelle de l'instruction. *
+* proc = architecture ciblée par le désassemblage. *
+* *
+* Description : Décode une instruction de type 'addu rd, rs, rt'. *
+* *
+* Retour : Instruction mise en place ou NULL. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GArchInstruction *mips_read_instr_add_unsigned(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GMipsProcessor *proc)
+{
+ GArchInstruction *result; /* Instruction à retourner */
+
+ result = g_mips_instruction_new(MOP_ADDU);
+
+ if (!mips_read_n_operands(result, data, pos, len, 3, MIPS_OTP_RD, MIPS_OTP_RS, MIPS_OTP_RT))
+ {
+ /* TODO free(result);*/
+ return NULL;
+ }
+
+ return result;
+
+}
diff --git a/src/arch/mips/op_and.c b/src/arch/mips/op_and.c
new file mode 100644
index 0000000..1d3aae2
--- /dev/null
+++ b/src/arch/mips/op_and.c
@@ -0,0 +1,62 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * op_and.c - décodage des ET logiques
+ *
+ * Copyright (C) 2009 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 "opcodes.h"
+
+
+#include "../instruction-int.h"
+#include "operand.h"
+
+
+
+/******************************************************************************
+* *
+* Paramètres : data = flux de données à analyser. *
+* pos = position courante dans ce flux. [OUT] *
+* len = taille totale des données à analyser. *
+* addr = adresse virtuelle de l'instruction. *
+* proc = architecture ciblée par le désassemblage. *
+* *
+* Description : Décode une instruction de type 'and rd, rs, rt'. *
+* *
+* Retour : Instruction mise en place ou NULL. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GArchInstruction *mips_read_instr_and(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GMipsProcessor *proc)
+{
+ GArchInstruction *result; /* Instruction à retourner */
+
+ result = g_mips_instruction_new(MOP_AND);
+
+ if (!mips_read_n_operands(result, data, pos, len, 3, MIPS_OTP_RD, MIPS_OTP_RS, MIPS_OTP_RT))
+ {
+ /* TODO free(result);*/
+ return NULL;
+ }
+
+ return result;
+
+}
diff --git a/src/arch/mips/op_branch.c b/src/arch/mips/op_branch.c
new file mode 100644
index 0000000..04de039
--- /dev/null
+++ b/src/arch/mips/op_branch.c
@@ -0,0 +1,161 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * op_branch.c - décodage des sauts conditionnels
+ *
+ * Copyright (C) 2009 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 "opcodes.h"
+
+
+#include "../instruction-int.h"
+#include "operand.h"
+
+
+
+/******************************************************************************
+* *
+* Paramètres : data = flux de données à analyser. *
+* pos = position courante dans ce flux. [OUT] *
+* len = taille totale des données à analyser. *
+* addr = adresse virtuelle de l'instruction. *
+* proc = architecture ciblée par le désassemblage. *
+* *
+* Description : Décode une instruction de type 'beq rs, rt, offset'. *
+* *
+* Retour : Instruction mise en place ou NULL. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GArchInstruction *mips_read_instr_branch_on_equal(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GMipsProcessor *proc)
+{
+ GArchInstruction *result; /* Instruction à retourner */
+
+ result = g_mips_instruction_new(MOP_BEQ);
+
+ if (!mips_read_n_operands(result, data, pos, len, 3, MIPS_OTP_RS, MIPS_OTP_RT, MIPS_OTP_OFFSET))
+ {
+ /* TODO free(result);*/
+ return NULL;
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : data = flux de données à analyser. *
+* pos = position courante dans ce flux. [OUT] *
+* len = taille totale des données à analyser. *
+* addr = adresse virtuelle de l'instruction. *
+* proc = architecture ciblée par le désassemblage. *
+* *
+* Description : Décode une instruction de type 'beql rs, rt, offset'. *
+* *
+* Retour : Instruction mise en place ou NULL. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GArchInstruction *mips_read_instr_branch_on_equal_likely(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GMipsProcessor *proc)
+{
+ GArchInstruction *result; /* Instruction à retourner */
+
+ result = g_mips_instruction_new(MOP_BEQL);
+
+ if (!mips_read_n_operands(result, data, pos, len, 3, MIPS_OTP_RS, MIPS_OTP_RT, MIPS_OTP_OFFSET))
+ {
+ /* TODO free(result);*/
+ return NULL;
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : data = flux de données à analyser. *
+* pos = position courante dans ce flux. [OUT] *
+* len = taille totale des données à analyser. *
+* addr = adresse virtuelle de l'instruction. *
+* proc = architecture ciblée par le désassemblage. *
+* *
+* Description : Décode une instruction de type 'bgezal rs, offset'. *
+* *
+* Retour : Instruction mise en place ou NULL. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GArchInstruction *mips_read_instr_branch_on_greater_than_or_equal_to_zero_and_link(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GMipsProcessor *proc)
+{
+ GArchInstruction *result; /* Instruction à retourner */
+
+ result = g_mips_instruction_new(MOP_BGEZAL);
+
+ if (!mips_read_n_operands(result, data, pos, len, 2, MIPS_OTP_RS, MIPS_OTP_OFFSET))
+ {
+ /* TODO free(result);*/
+ return NULL;
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : data = flux de données à analyser. *
+* pos = position courante dans ce flux. [OUT] *
+* len = taille totale des données à analyser. *
+* addr = adresse virtuelle de l'instruction. *
+* proc = architecture ciblée par le désassemblage. *
+* *
+* Description : Décode une instruction de type 'bne rs, rt, offset'. *
+* *
+* Retour : Instruction mise en place ou NULL. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GArchInstruction *mips_read_instr_branch_on_not_equal(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GMipsProcessor *proc)
+{
+ GArchInstruction *result; /* Instruction à retourner */
+
+ result = g_mips_instruction_new(MOP_BNE);
+
+ if (!mips_read_n_operands(result, data, pos, len, 3, MIPS_OTP_RS, MIPS_OTP_RT, MIPS_OTP_OFFSET))
+ {
+ /* TODO free(result);*/
+ return NULL;
+ }
+
+ return result;
+
+}
diff --git a/src/arch/mips/op_jump.c b/src/arch/mips/op_jump.c
new file mode 100644
index 0000000..4faa6c6
--- /dev/null
+++ b/src/arch/mips/op_jump.c
@@ -0,0 +1,114 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * op_jump.c - décodage des sauts inconditionnels
+ *
+ * Copyright (C) 2009 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 "opcodes.h"
+
+
+#include "../instruction-int.h"
+#include "operand.h"
+
+
+
+/******************************************************************************
+* *
+* Paramètres : data = flux de données à analyser. *
+* pos = position courante dans ce flux. [OUT] *
+* len = taille totale des données à analyser. *
+* addr = adresse virtuelle de l'instruction. *
+* proc = architecture ciblée par le désassemblage. *
+* *
+* Description : Décode une instruction de type 'jr rs'. *
+* *
+* Retour : Instruction mise en place ou NULL. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GArchInstruction *mips_read_instr_jump_register(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GMipsProcessor *proc)
+{
+ GArchInstruction *result; /* Instruction à retourner */
+
+ result = g_mips_instruction_new(MOP_JR);
+
+ if (!mips_read_n_operands(result, data, pos, len, 1, MIPS_OTP_RS))
+ {
+ /* TODO free(result);*/
+ return NULL;
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : data = flux de données à analyser. *
+* pos = position courante dans ce flux. [OUT] *
+* len = taille totale des données à analyser. *
+* addr = adresse virtuelle de l'instruction. *
+* proc = architecture ciblée par le désassemblage. *
+* *
+* Description : Décode une instruction de type 'jalr[.hb] [rd, ]rs'. *
+* *
+* Retour : Instruction mise en place ou NULL. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GArchInstruction *mips_read_instr_jump_and_link_register(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GMipsProcessor *proc)
+{
+ GArchInstruction *result; /* Instruction à retourner */
+ off_t tmp; /* Pour ne pas toucher à 'pos' */
+ uint32_t code; /* Code binaire à décoder */
+ GArchOperand *operand; /* Opérande à analyser */
+ const mips_register *reg; /* Registre implicite ? */
+
+ tmp = *pos;
+
+ if (!read_u32(&code, data, &tmp, len, SRE_LITTLE/* FIXME */))
+ return NULL;
+
+ if (code & 0x400) result = g_mips_instruction_new(MOP_JALR_HB);
+ else result = g_mips_instruction_new(MOP_JALR);
+
+ if (!mips_read_n_operands(result, data, pos, len, 2, MIPS_OTP_RD, MIPS_OTP_RS))
+ {
+ /* TODO free(result);*/
+ return NULL;
+ }
+
+ operand = G_ARCH_INSTRUCTION(result)->operands[0];
+ reg = g_mips_register_operand_get_register(G_MIPS_REGISTER_OPERAND(operand));
+
+ if (is_mips_register_return_address(reg))
+ {
+ g_arch_instruction_detach_operand(G_ARCH_INSTRUCTION(result), operand);
+ /* TODO free(operand);*/
+ }
+
+ return result;
+
+}
diff --git a/src/arch/mips/op_load.c b/src/arch/mips/op_load.c
new file mode 100644
index 0000000..c8a308a
--- /dev/null
+++ b/src/arch/mips/op_load.c
@@ -0,0 +1,128 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * op_load.c - décodage des chargements de données
+ *
+ * Copyright (C) 2009 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 "opcodes.h"
+
+
+#include "../instruction-int.h"
+#include "operand.h"
+
+
+
+/******************************************************************************
+* *
+* Paramètres : data = flux de données à analyser. *
+* pos = position courante dans ce flux. [OUT] *
+* len = taille totale des données à analyser. *
+* addr = adresse virtuelle de l'instruction. *
+* proc = architecture ciblée par le désassemblage. *
+* *
+* Description : Décode une instruction de type 'lbu rt, offset(rs)'. *
+* *
+* Retour : Instruction mise en place ou NULL. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GArchInstruction *mips_read_instr_load_byte_unisgned(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GMipsProcessor *proc)
+{
+ GArchInstruction *result; /* Instruction à retourner */
+
+ result = g_mips_instruction_new(MOP_LBU);
+
+ if (!mips_read_n_operands(result, data, pos, len, 2, MIPS_OTP_RT, MIPS_OTP_MEM_CONTENT))
+ {
+ /* TODO free(result);*/
+ return NULL;
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : data = flux de données à analyser. *
+* pos = position courante dans ce flux. [OUT] *
+* len = taille totale des données à analyser. *
+* addr = adresse virtuelle de l'instruction. *
+* proc = architecture ciblée par le désassemblage. *
+* *
+* Description : Décode une instruction de type 'lui rt, imm'. *
+* *
+* Retour : Instruction mise en place ou NULL. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GArchInstruction *mips_read_instr_load_upper_immediate(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GMipsProcessor *proc)
+{
+ GArchInstruction *result; /* Instruction à retourner */
+
+ result = g_mips_instruction_new(MOP_LUI);
+
+ if (!mips_read_n_operands(result, data, pos, len, 2, MIPS_OTP_RT, MIPS_OTP_IMMEDIATE))
+ {
+ /* TODO free(result);*/
+ return NULL;
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : data = flux de données à analyser. *
+* pos = position courante dans ce flux. [OUT] *
+* len = taille totale des données à analyser. *
+* addr = adresse virtuelle de l'instruction. *
+* proc = architecture ciblée par le désassemblage. *
+* *
+* Description : Décode une instruction de type 'lw rt, offset(rs)'. *
+* *
+* Retour : Instruction mise en place ou NULL. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GArchInstruction *mips_read_instr_load_word(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GMipsProcessor *proc)
+{
+ GArchInstruction *result; /* Instruction à retourner */
+
+ result = g_mips_instruction_new(MOP_LW);
+
+ if (!mips_read_n_operands(result, data, pos, len, 2, MIPS_OTP_RT, MIPS_OTP_MEM_CONTENT))
+ {
+ /* TODO free(result);*/
+ return NULL;
+ }
+
+ return result;
+
+}
diff --git a/src/arch/mips/op_nop.c b/src/arch/mips/op_nop.c
new file mode 100644
index 0000000..972f4c0
--- /dev/null
+++ b/src/arch/mips/op_nop.c
@@ -0,0 +1,58 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * op_nop.c - décodage de l'instruction nulle
+ *
+ * Copyright (C) 2009 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 "opcodes.h"
+
+
+#include "../instruction-int.h"
+
+
+
+/******************************************************************************
+* *
+* Paramètres : data = flux de données à analyser. *
+* pos = position courante dans ce flux. [OUT] *
+* len = taille totale des données à analyser. *
+* addr = adresse virtuelle de l'instruction. *
+* prefix = éventuel(s) préfixe(s) remarqué(s). *
+* proc = architecture ciblée par le désassemblage. *
+* *
+* Description : Décode une instruction de type 'nop'. *
+* *
+* Retour : Instruction mise en place ou NULL. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GArchInstruction *mips_read_instr_nop(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GMipsProcessor *proc)
+{
+ GArchInstruction *result; /* Instruction à retourner */
+
+ result = g_mips_instruction_new(MOP_NOP);
+
+ *pos += 4;
+
+ return result;
+
+}
diff --git a/src/arch/mips/op_sr.c b/src/arch/mips/op_sr.c
new file mode 100644
index 0000000..f0ccf31
--- /dev/null
+++ b/src/arch/mips/op_sr.c
@@ -0,0 +1,62 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * op_sr.c - décodage des décallages à droite
+ *
+ * Copyright (C) 2009 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 "opcodes.h"
+
+
+#include "../instruction-int.h"
+#include "operand.h"
+
+
+
+/******************************************************************************
+* *
+* Paramètres : data = flux de données à analyser. *
+* pos = position courante dans ce flux. [OUT] *
+* len = taille totale des données à analyser. *
+* addr = adresse virtuelle de l'instruction. *
+* proc = architecture ciblée par le désassemblage. *
+* *
+* Description : Décode une instruction de type 'sra rd, rt, sa'. *
+* *
+* Retour : Instruction mise en place ou NULL. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GArchInstruction *mips_read_instr_shift_word_right_arithmetic(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GMipsProcessor *proc)
+{
+ GArchInstruction *result; /* Instruction à retourner */
+
+ result = g_mips_instruction_new(MOP_SRA);
+
+ if (!mips_read_n_operands(result, data, pos, len, 3, MIPS_OTP_RD, MIPS_OTP_RT, MIPS_OTP_SA))
+ {
+ /* TODO free(result);*/
+ return NULL;
+ }
+
+ return result;
+
+}
diff --git a/src/arch/mips/op_store.c b/src/arch/mips/op_store.c
new file mode 100644
index 0000000..91307dd
--- /dev/null
+++ b/src/arch/mips/op_store.c
@@ -0,0 +1,95 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * op_store.c - décodage des déchargements de données
+ *
+ * Copyright (C) 2009 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 "opcodes.h"
+
+
+#include "../instruction-int.h"
+#include "operand.h"
+
+
+
+/******************************************************************************
+* *
+* Paramètres : data = flux de données à analyser. *
+* pos = position courante dans ce flux. [OUT] *
+* len = taille totale des données à analyser. *
+* addr = adresse virtuelle de l'instruction. *
+* proc = architecture ciblée par le désassemblage. *
+* *
+* Description : Décode une instruction de type 'sb rt, offset(rs)'. *
+* *
+* Retour : Instruction mise en place ou NULL. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GArchInstruction *mips_read_instr_store_byte(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GMipsProcessor *proc)
+{
+ GArchInstruction *result; /* Instruction à retourner */
+
+ result = g_mips_instruction_new(MOP_SB);
+
+ if (!mips_read_n_operands(result, data, pos, len, 2, MIPS_OTP_RT, MIPS_OTP_MEM_CONTENT))
+ {
+ /* TODO free(result);*/
+ return NULL;
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : data = flux de données à analyser. *
+* pos = position courante dans ce flux. [OUT] *
+* len = taille totale des données à analyser. *
+* addr = adresse virtuelle de l'instruction. *
+* proc = architecture ciblée par le désassemblage. *
+* *
+* Description : Décode une instruction de type 'sw rt, offset(rs)'. *
+* *
+* Retour : Instruction mise en place ou NULL. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GArchInstruction *mips_read_instr_store_word(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GMipsProcessor *proc)
+{
+ GArchInstruction *result; /* Instruction à retourner */
+
+ result = g_mips_instruction_new(MOP_SW);
+
+ if (!mips_read_n_operands(result, data, pos, len, 2, MIPS_OTP_RT, MIPS_OTP_MEM_CONTENT))
+ {
+ /* TODO free(result);*/
+ return NULL;
+ }
+
+ return result;
+
+}
diff --git a/src/arch/mips/op_sub.c b/src/arch/mips/op_sub.c
new file mode 100644
index 0000000..c6815a2
--- /dev/null
+++ b/src/arch/mips/op_sub.c
@@ -0,0 +1,95 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * op_sub.c - décodage des soustractions
+ *
+ * Copyright (C) 2009 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 "opcodes.h"
+
+
+#include "../instruction-int.h"
+#include "operand.h"
+
+
+
+/******************************************************************************
+* *
+* Paramètres : data = flux de données à analyser. *
+* pos = position courante dans ce flux. [OUT] *
+* len = taille totale des données à analyser. *
+* addr = adresse virtuelle de l'instruction. *
+* proc = architecture ciblée par le désassemblage. *
+* *
+* Description : Décode une instruction de type 'subu rd, rs, rt'. *
+* *
+* Retour : Instruction mise en place ou NULL. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GArchInstruction *mips_read_instr_subtract_unsigned_word(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GMipsProcessor *proc)
+{
+ GArchInstruction *result; /* Instruction à retourner */
+
+ result = g_mips_instruction_new(MOP_SUBU);
+
+ if (!mips_read_n_operands(result, data, pos, len, 3, MIPS_OTP_RD, MIPS_OTP_RS, MIPS_OTP_RT))
+ {
+ /* TODO free(result);*/
+ return NULL;
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : data = flux de données à analyser. *
+* pos = position courante dans ce flux. [OUT] *
+* len = taille totale des données à analyser. *
+* addr = adresse virtuelle de l'instruction. *
+* proc = architecture ciblée par le désassemblage. *
+* *
+* Description : Décode une instruction de type 'sub rd, rs, rt'. *
+* *
+* Retour : Instruction mise en place ou NULL. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GArchInstruction *mips_read_instr_subtract_word(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, const GMipsProcessor *proc)
+{
+ GArchInstruction *result; /* Instruction à retourner */
+
+ result = g_mips_instruction_new(MOP_SUB);
+
+ if (!mips_read_n_operands(result, data, pos, len, 3, MIPS_OTP_RD, MIPS_OTP_RS, MIPS_OTP_RT))
+ {
+ /* TODO free(result);*/
+ return NULL;
+ }
+
+ return result;
+
+}
diff --git a/src/arch/mips/opcodes.h b/src/arch/mips/opcodes.h
new file mode 100644
index 0000000..276e752
--- /dev/null
+++ b/src/arch/mips/opcodes.h
@@ -0,0 +1,107 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * opcodes.h - prototypes pour la liste de tous les opcodes de l'architecture MIPS
+ *
+ * Copyright (C) 2009 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 _ARCH_MIPS_OPCODES_H
+#define _ARCH_MIPS_OPCODES_H
+
+
+#include "processor.h"
+#include "instruction.h"
+
+
+
+/* Décode une instruction de type 'addiu rt, rs, imm'. */
+GArchInstruction *mips_read_instr_add_immediate_unsigned(const bin_t *, off_t *, off_t, vmpa_t, const GMipsProcessor *);
+
+/* Décode une instruction de type 'addu rd, rs, rt'. */
+GArchInstruction *mips_read_instr_add_unsigned(const bin_t *, off_t *, off_t, vmpa_t, const GMipsProcessor *);
+
+
+
+/* Décode une instruction de type 'and rd, rs, rt'. */
+GArchInstruction *mips_read_instr_and(const bin_t *, off_t *, off_t, vmpa_t, const GMipsProcessor *);
+
+
+
+/* Décode une instruction de type 'beq rs, rt, offset'. */
+GArchInstruction *mips_read_instr_branch_on_equal(const bin_t *, off_t *, off_t, vmpa_t, const GMipsProcessor *);
+
+/* Décode une instruction de type 'beql rs, rt, offset'. */
+GArchInstruction *mips_read_instr_branch_on_equal_likely(const bin_t *, off_t *, off_t, vmpa_t, const GMipsProcessor *);
+
+/* Décode une instruction de type 'bgezal rs, offset'. */
+GArchInstruction *mips_read_instr_branch_on_greater_than_or_equal_to_zero_and_link(const bin_t *, off_t *, off_t, vmpa_t, const GMipsProcessor *);
+
+/* Décode une instruction de type 'bne rs, rt, offset'. */
+GArchInstruction *mips_read_instr_branch_on_not_equal(const bin_t *, off_t *, off_t, vmpa_t, const GMipsProcessor *);
+
+
+
+/* Décode une instruction de type 'jr rs'. */
+GArchInstruction *mips_read_instr_jump_register(const bin_t *, off_t *, off_t, vmpa_t, const GMipsProcessor *);
+
+/* Décode une instruction de type 'jalr[.hb] [rd, ]rs'. */
+GArchInstruction *mips_read_instr_jump_and_link_register(const bin_t *, off_t *, off_t, vmpa_t, const GMipsProcessor *);
+
+
+
+/* Décode une instruction de type 'lbu rt, offset(rs)'. */
+GArchInstruction *mips_read_instr_load_byte_unisgned(const bin_t *, off_t *, off_t, vmpa_t, const GMipsProcessor *);
+
+/* Décode une instruction de type 'lui rt, imm'. */
+GArchInstruction *mips_read_instr_load_upper_immediate(const bin_t *, off_t *, off_t, vmpa_t, const GMipsProcessor *);
+
+/* Décode une instruction de type 'lw rt, offset(rs)'. */
+GArchInstruction *mips_read_instr_load_word(const bin_t *, off_t *, off_t, vmpa_t, const GMipsProcessor *);
+
+
+
+/* Décode une instruction de type 'nop'. */
+GArchInstruction *mips_read_instr_nop(const bin_t *, off_t *, off_t, vmpa_t, const GMipsProcessor *);
+
+
+
+/* Décode une instruction de type 'sra rd, rt, sa'. */
+GArchInstruction *mips_read_instr_shift_word_right_arithmetic(const bin_t *, off_t *, off_t, vmpa_t, const GMipsProcessor *);
+
+
+
+/* Décode une instruction de type 'sb rt, offset(rs)'. */
+GArchInstruction *mips_read_instr_store_byte(const bin_t *, off_t *, off_t, vmpa_t, const GMipsProcessor *);
+
+/* Décode une instruction de type 'sw rt, offset(rs)'. */
+GArchInstruction *mips_read_instr_store_word(const bin_t *, off_t *, off_t, vmpa_t, const GMipsProcessor *);
+
+
+
+
+/* Décode une instruction de type 'subu rd, rs, rt'. */
+GArchInstruction *mips_read_instr_subtract_unsigned_word(const bin_t *, off_t *, off_t, vmpa_t, const GMipsProcessor *);
+
+/* Décode une instruction de type 'sub rd, rs, rt'. */
+GArchInstruction *mips_read_instr_subtract_word(const bin_t *, off_t *, off_t, vmpa_t, const GMipsProcessor *);
+
+
+
+
+#endif /* _ARCH_MIPS_OPCODES_H */
diff --git a/src/arch/mips/operand.c b/src/arch/mips/operand.c
new file mode 100644
index 0000000..68599a4
--- /dev/null
+++ b/src/arch/mips/operand.c
@@ -0,0 +1,649 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * operand.h - prototypes pour la gestion des operandes de l'architecture MIPS
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "operand.h"
+
+
+#include <stdarg.h>
+
+
+#include "../immediate.h"
+#include "../operand-int.h"
+#include "../../common/endianness.h"
+#include "../../common/extstr.h"
+
+
+
+/* ------------------------ COQUILLE VIDE POUR OPERANDE MIPS ------------------------ */
+
+
+/* Définition d'un opérande de la MIPS (instance) */
+struct _GMipsOperand
+{
+ GArchOperand parent; /* Instance parente */
+
+};
+
+
+/* Définition d'un opérande de la MIPS (classe) */
+struct _GMipsOperandClass
+{
+ GArchOperandClass parent; /* Classe parente */
+
+};
+
+
+/* Initialise la classe des opérandes MIPS de base. */
+static void g_mips_operand_class_init(GMipsOperandClass *);
+
+/* Initialise une instance d'opérande de base pour MIPS. */
+static void g_mips_operand_init(GMipsOperand *);
+
+
+
+/* ----------------------- OPERANDES OFFRANT UN REGISTRE MIPS ----------------------- */
+
+
+/* Définition d'un opérande visant un registre MIPS (instance) */
+struct _GMipsRegisterOperand
+{
+ GMipsOperand parent; /* Instance parente */
+
+ mips_register *reg; /* Registre représenté */
+
+};
+
+
+/* Définition d'un opérande visant un registre MIPS (classe) */
+struct _GMipsRegisterOperandClass
+{
+ GMipsOperandClass parent; /* Classe parente */
+
+};
+
+
+/* Initialise la classe des opérandes de registre MIPS. */
+static void g_mips_register_operand_class_init(GMipsRegisterOperandClass *);
+
+/* Initialise une instance d'opérande de registre MIPS. */
+static void g_mips_register_operand_init(GMipsRegisterOperand *);
+
+/* Traduit un opérande en version humainement lisible. */
+static char *g_mips_register_operand_get_text(const GMipsRegisterOperand *, const exe_format *, AsmSyntax);
+
+
+
+/* -------------------------- OPERANDES DE CONTENU MEMOIRE -------------------------- */
+
+
+/* Définition d'un opérande MIPS pointeur un contenu mémoire (instance) */
+struct _GMipsMemContentOperand
+{
+ GMipsOperand parent; /* Instance parente */
+
+ mips_register *base; /* Base de la lecture */
+ GArchOperand *offset; /* Décallage à appliquer */
+
+};
+
+
+/* Définition d'un opérande MIPS pointeur un contenu mémoire (classe) */
+struct _GMipsMemContentOperandClass
+{
+ GMipsOperandClass parent; /* Classe parente */
+
+};
+
+
+/* Initialise la classe des opérandes MIPS de contenu mémoire. */
+static void g_mips_mem_content_operand_class_init(GMipsMemContentOperandClass *);
+
+/* Initialise une instance d'opérande MIPS de contenu mémoire. */
+static void g_mips_mem_content_operand_init(GMipsMemContentOperand *);
+
+/* Traduit un opérande en version humainement lisible. */
+static char *g_mips_mem_content_operand_get_text(const GMipsMemContentOperand *, const exe_format *, AsmSyntax);
+
+
+
+/* ----------------------------- OPERANDES DE DECALLAGE ----------------------------- */
+
+
+/* Définition d'un opérande MIPS de décallage (instance) */
+struct _GMipsOffsetOperand
+{
+ GMipsOperand parent; /* Instance parente */
+
+ GArchOperand *offset; /* Décallage à appliquer */
+
+};
+
+
+/* Définition d'un opérande MIPS de décallage (classe) */
+struct _GMipsOffsetOperandClass
+{
+ GMipsOperandClass parent; /* Classe parente */
+
+};
+
+
+/* Initialise la classe des opérandes MIPS de décallage. */
+static void g_mips_offset_operand_class_init(GMipsOffsetOperandClass *);
+
+/* Initialise une instance d'opérande MIPS de décallage. */
+static void g_mips_offset_operand_init(GMipsOffsetOperand *);
+
+/* Traduit un opérande en version humainement lisible. */
+static char *g_mips_offset_operand_get_text(const GMipsOffsetOperand *, const exe_format *, AsmSyntax);
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* COQUILLE VIDE POUR OPERANDE MIPS */
+/* ---------------------------------------------------------------------------------- */
+
+
+/* Indique le type défini par la GLib pour un opérande de MIPS. */
+G_DEFINE_TYPE(GMipsOperand, g_mips_operand, G_TYPE_ARCH_OPERAND);
+
+
+/******************************************************************************
+* *
+* Paramètres : klass = classe à initialiser. *
+* *
+* Description : Initialise la classe des opérandes MIPS de base. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_mips_operand_class_init(GMipsOperandClass *klass)
+{
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : operand = instance à initialiser. *
+* *
+* Description : Initialise une instance d'opérande de base pour MIPS. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_mips_operand_init(GMipsOperand *operand)
+{
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* OPERANDES OFFRANT UN REGISTRE MIPS */
+/* ---------------------------------------------------------------------------------- */
+
+
+/* Indique le type défini par la GLib pour un opérande de registre MIPS. */
+G_DEFINE_TYPE(GMipsRegisterOperand, g_mips_register_operand, G_TYPE_MIPS_OPERAND);
+
+
+/******************************************************************************
+* *
+* Paramètres : klass = classe à initialiser. *
+* *
+* Description : Initialise la classe des opérandes de registre MIPS. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_mips_register_operand_class_init(GMipsRegisterOperandClass *klass)
+{
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : operand = instance à initialiser. *
+* *
+* Description : Initialise une instance d'opérande de registre MIPS. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_mips_register_operand_init(GMipsRegisterOperand *operand)
+{
+ GArchOperand *parent; /* Instance parente */
+
+ parent = G_ARCH_OPERAND(operand);
+
+ parent->get_text = (get_operand_text_fc)g_mips_register_operand_get_text;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : index = identifiant du registre à représenter. *
+* *
+* Description : Crée un opérande visant un registre MIPS. *
+* *
+* Retour : Opérande mis en place. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GArchOperand *g_mips_register_operand_new(bin_t index)
+{
+ GMipsRegisterOperand *result; /* Structure à retourner */
+ mips_register *reg; /* Registre lu */
+
+ reg = get_mips_register(index);
+
+ if (reg != NULL)
+ {
+ result = g_object_new(G_TYPE_MIPS_REGISTER_OPERAND, NULL);
+
+ result->reg = reg;
+
+ }
+ else result = NULL;
+
+ return G_ARCH_OPERAND(result);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : operand = opérande à traiter. *
+* format = format du binaire manipulé. *
+* syntax = type de représentation demandée. *
+* *
+* Description : Traduit un opérande en version humainement lisible. *
+* *
+* Retour : Chaîne de caractères à libérer de la mémoire. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static char *g_mips_register_operand_get_text(const GMipsRegisterOperand *operand, const exe_format *format, AsmSyntax syntax)
+{
+ char *result; /* Chaîne à retourner */
+
+ result = mips_register_as_text(operand->reg, syntax);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : operand = opérande à consulter. *
+* *
+* Description : Fournit le registre MIPS représenté. *
+* *
+* Retour : Régistre MIPS représenté. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+const mips_register *g_mips_register_operand_get_register(const GMipsRegisterOperand *operand)
+{
+ return operand->reg;
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* OPERANDES DE CONTENU MEMOIRE */
+/* ---------------------------------------------------------------------------------- */
+
+
+/* Indique le type défini par la GLib pour un opérande MIPS de contenu mémoire. */
+G_DEFINE_TYPE(GMipsMemContentOperand, g_mips_mem_content_operand, G_TYPE_MIPS_OPERAND);
+
+
+/******************************************************************************
+* *
+* Paramètres : klass = classe à initialiser. *
+* *
+* Description : Initialise la classe des opérandes MIPS de contenu mémoire. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_mips_mem_content_operand_class_init(GMipsMemContentOperandClass *klass)
+{
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : operand = instance à initialiser. *
+* *
+* Description : Initialise une instance d'opérande MIPS de contenu mémoire. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_mips_mem_content_operand_init(GMipsMemContentOperand *operand)
+{
+ GArchOperand *parent; /* Instance parente */
+
+ parent = G_ARCH_OPERAND(operand);
+
+ parent->get_text = (get_operand_text_fc)g_mips_mem_content_operand_get_text;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : index = indice du registre de base. *
+* offset = décallage supplémentaire à appliquer. *
+* *
+* Description : Crée un opérande MIPS de contenu mémoire. *
+* *
+* Retour : Opérande mis en place. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GArchOperand *g_mips_mem_content_operand_new(bin_t index, int16_t offset)
+{
+ GMipsMemContentOperand *result; /* Structure à retourner */
+ mips_register *base; /* Registre lu */
+
+ base = get_mips_register(index);
+
+ if (base != NULL)
+ {
+ result = g_object_new(G_TYPE_MIPS_MEM_CONTENT_OPERAND, NULL);
+
+ result->base = base;
+ result->offset = g_imm_operand_new_from_value(AOS_16_BITS_SIGNED, offset);
+
+ }
+ else result = NULL;
+
+ return G_ARCH_OPERAND(result);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : operand = opérande à traiter. *
+* format = format du binaire manipulé. *
+* syntax = type de représentation demandée. *
+* *
+* Description : Traduit un opérande en version humainement lisible. *
+* *
+* Retour : Chaîne de caractères à libérer de la mémoire. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static char *g_mips_mem_content_operand_get_text(const GMipsMemContentOperand *operand, const exe_format *format, AsmSyntax syntax)
+{
+ char *result; /* Chaîne à retourner */
+ char *tmp; /* Déplacement */
+
+ result = mips_register_as_text(operand->base, syntax);
+
+ result = strprep(result, "[");
+
+ if (g_imm_operand_is_negative(operand->offset)) result = stradd(result, "-");
+ else result = stradd(result, "+");
+
+ tmp = g_arch_operand_get_text(G_ARCH_OPERAND(operand->offset), format, syntax);
+ result = stradd(result, tmp);
+ free(tmp);
+
+ result = stradd(result, "]");
+
+ return result;
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* OPERANDES DE DECALLAGE */
+/* ---------------------------------------------------------------------------------- */
+
+
+/* Indique le type défini par la GLib pour un opérande MIPS de décallage. */
+G_DEFINE_TYPE(GMipsOffsetOperand, g_mips_offset_operand, G_TYPE_MIPS_OPERAND);
+
+
+/******************************************************************************
+* *
+* Paramètres : klass = classe à initialiser. *
+* *
+* Description : Initialise la classe des opérandes MIPS de décallage. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_mips_offset_operand_class_init(GMipsOffsetOperandClass *klass)
+{
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : operand = instance à initialiser. *
+* *
+* Description : Initialise une instance d'opérande MIPS de décallage. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_mips_offset_operand_init(GMipsOffsetOperand *operand)
+{
+ GArchOperand *parent; /* Instance parente */
+
+ parent = G_ARCH_OPERAND(operand);
+
+ parent->get_text = (get_operand_text_fc)g_mips_offset_operand_get_text;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : offset = valeur de décallage à représenter. *
+* *
+* Description : Crée un opérande MIPS de décallage. *
+* *
+* Retour : Opérande mis en place. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GArchOperand *g_mips_offset_operand_new(int16_t offset)
+{
+ GMipsOffsetOperand *result; /* Structure à retourner */
+
+ result = g_object_new(G_TYPE_MIPS_OFFSET_OPERAND, NULL);
+
+ result->offset = g_imm_operand_new_from_value(AOS_16_BITS_SIGNED, offset);
+
+ return G_ARCH_OPERAND(result);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : operand = opérande à traiter. *
+* format = format du binaire manipulé. *
+* syntax = type de représentation demandée. *
+* *
+* Description : Traduit un opérande en version humainement lisible. *
+* *
+* Retour : Chaîne de caractères à libérer de la mémoire. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static char *g_mips_offset_operand_get_text(const GMipsOffsetOperand *operand, const exe_format *format, AsmSyntax syntax)
+{
+ return g_arch_operand_get_text(G_ARCH_OPERAND(operand->offset), format, syntax);
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* AIDE A LA CREATION D'OPERANDES */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+* *
+* Paramètres : instr = instruction dont la définition est à compléter. [OUT]*
+* data = flux de données à analyser. *
+* pos = position courante dans ce flux. [OUT] *
+* len = taille totale des données à analyser. *
+* count = type du premier opérande. *
+* ... = type des opérandes à interpréter. *
+* *
+* Description : Procède à la lecture de deux opérandes donnés. *
+* *
+* Retour : Bilan de l'opération : true en cas de succès, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool mips_read_n_operands(GArchInstruction *instr, const bin_t *data, off_t *pos, off_t len, unsigned int count, ...)
+{
+ bool result; /* Statut à retourner */
+ uint32_t code; /* Code binaire à décoder */
+ MipsOperandType type; /* Type d'opérand interprétée */
+ va_list ap; /* Arguments potentiels */
+ unsigned int i; /* Boucle de parcours */
+ bin_t reg; /* Identifiant de registre */
+ GArchOperand *op; /* Opérande décodé */
+
+ if (!read_u32(&code, data, pos, len, SRE_LITTLE/* FIXME */))
+ return false;
+
+ result = true;
+
+ va_start(ap, count);
+
+ for (i = 0; i < count; i++)
+ {
+ type = va_arg(ap, MipsOperandType);
+
+ switch (type)
+ {
+ case MIPS_OTP_RS:
+ reg = (code & 0x3e00000) >> 21;
+ op = g_mips_register_operand_new(reg);
+ break;
+
+ case MIPS_OTP_RT:
+ reg = (code & 0x1f0000) >> 16;
+ op = g_mips_register_operand_new(reg);
+ break;
+
+ case MIPS_OTP_RD:
+ reg = (code & 0xf800) >> 11;
+ op = g_mips_register_operand_new(reg);
+ break;
+
+ case MIPS_OTP_IMMEDIATE:
+ op = g_imm_operand_new_from_value(AOS_16_BITS, code & 0xffff);
+ break;
+
+
+
+
+ case MIPS_OTP_MEM_CONTENT:
+ op = g_mips_mem_content_operand_new((code & 0x3e00000) >> 21, code & 0xffff);
+ break;
+
+ case MIPS_OTP_OFFSET:
+ op = g_mips_offset_operand_new(code & 0xffff);
+ break;
+
+ case MIPS_OTP_SA:
+ op = g_imm_operand_new_from_value(AOS_8_BITS, (code & 0x7c0) >> 6);
+ break;
+
+ default:
+ op = NULL;
+ break;
+
+ }
+
+ if (op == NULL) result = false;
+ else g_arch_instruction_attach_extra_operand(instr, op);
+
+ }
+
+ va_end(ap);
+
+ return result;
+
+}
diff --git a/src/arch/mips/operand.h b/src/arch/mips/operand.h
new file mode 100644
index 0000000..22bd080
--- /dev/null
+++ b/src/arch/mips/operand.h
@@ -0,0 +1,156 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * operand.h - prototypes pour la gestion des operandes de l'architecture MIPS
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _ARCH_MIPS_OPERAND_H
+#define _ARCH_MIPS_OPERAND_H
+
+
+#include <stdbool.h>
+
+
+#include "registers.h"
+#include "../instruction.h"
+
+
+
+/* ------------------------ COQUILLE VIDE POUR OPERANDE MIPS ------------------------ */
+
+
+#define G_TYPE_MIPS_OPERAND g_mips_operand_get_type()
+#define G_MIPS_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_mips_operand_get_type(), GMipsOperand))
+#define G_IS_MIPS_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_mips_operand_get_type()))
+#define G_MIPS_OPERAND_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE((inst), g_mips_operand_get_type(), GMipsOperandIface))
+
+
+/* Définition d'un opérande de MIPS (instance) */
+typedef struct _GMipsOperand GMipsOperand;
+
+/* Définition d'un opérande de MIPS (classe) */
+typedef struct _GMipsOperandClass GMipsOperandClass;
+
+
+/* Indique le type défini par la GLib pour un opérande de MIPS. */
+GType g_mips_operand_get_type(void);
+
+
+
+/* ----------------------- OPERANDES OFFRANT UN REGISTRE MIPS ----------------------- */
+
+
+#define G_TYPE_MIPS_REGISTER_OPERAND g_mips_register_operand_get_type()
+#define G_MIPS_REGISTER_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_mips_register_operand_get_type(), GMipsRegisterOperand))
+#define G_IS_MIPS_REGISTER_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_mips_register_operand_get_type()))
+#define G_MIPS_REGISTER_OPERAND_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE((inst), g_mips_register_operand_get_type(), GMipsRegisterOperandIface))
+
+
+/* Définition d'un opérande visant un registre MIPS (instance) */
+typedef struct _GMipsRegisterOperand GMipsRegisterOperand;
+
+/* Définition d'un opérande visant un registre MIPS (classe) */
+typedef struct _GMipsRegisterOperandClass GMipsRegisterOperandClass;
+
+
+/* Indique le type défini par la GLib pour un opérande de registre MIPS. */
+GType g_mips_register_operand_get_type(void);
+
+/* Crée un opérande visant un registre MIPS. */
+GArchOperand *g_mips_register_operand_new(bin_t);
+
+/* Fournit le registre MIPS représenté. */
+const mips_register *g_mips_register_operand_get_register(const GMipsRegisterOperand *);
+
+
+
+/* -------------------------- OPERANDES DE CONTENU MEMOIRE -------------------------- */
+
+
+#define G_TYPE_MIPS_MEM_CONTENT_OPERAND g_mips_mem_content_operand_get_type()
+#define G_MIPS_MEM_CONTENT_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_mips_mem_content_operand_get_type(), GMipsMemContentOperand))
+#define G_IS_MIPS_MEM_CONTENT_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_mips_mem_content_operand_get_type()))
+#define G_MIPS_MEM_CONTENT_OPERAND_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE((inst), g_mips_mem_content_operand_get_type(), GMipsMemContentOperandIface))
+
+
+/* Définition d'un opérande MIPS pointeur un contenu mémoire (instance) */
+typedef struct _GMipsMemContentOperand GMipsMemContentOperand;
+
+/* Définition d'un opérande MIPS pointeur un contenu mémoire (classe) */
+typedef struct _GMipsMemContentOperandClass GMipsMemContentOperandClass;
+
+
+/* Indique le type défini par la GLib pour un opérande MIPS de contenu mémoire. */
+GType g_mips_mem_content_operand_get_type(void);
+
+/* Crée un opérande MIPS de contenu mémoire. */
+GArchOperand *g_mips_mem_content_operand_new(bin_t, int16_t);
+
+
+
+/* ----------------------------- OPERANDES DE DECALLAGE ----------------------------- */
+
+
+#define G_TYPE_MIPS_OFFSET_OPERAND g_mips_offset_operand_get_type()
+#define G_MIPS_OFFSET_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_mips_offset_operand_get_type(), GMipsOffsetOperand))
+#define G_IS_MIPS_OFFSET_OPERAND(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_mips_offset_operand_get_type()))
+#define G_MIPS_OFFSET_OPERAND_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE((inst), g_mips_offset_operand_get_type(), GMipsOffsetOperandIface))
+
+
+/* Définition d'un opérande MIPS de décallage (instance) */
+typedef struct _GMipsOffsetOperand GMipsOffsetOperand;
+
+/* Définition d'un opérande MIPS de décallage (classe) */
+typedef struct _GMipsOffsetOperandClass GMipsOffsetOperandClass;
+
+
+/* Indique le type défini par la GLib pour un opérande MIPS de décallage. */
+GType g_mips_offset_operand_get_type(void);
+
+/* Crée un opérande MIPS de décallage. */
+GArchOperand *g_mips_offset_operand_new(int16_t);
+
+
+
+/* ------------------------- AIDE A LA CREATION D'OPERANDES ------------------------- */
+
+
+/* Types d'opérandes supportés */
+typedef enum _MIPSOperandType
+{
+ MIPS_OTP_RS, /* Registre rs (bits 21 -> 25) */
+ MIPS_OTP_RT, /* Registre rs (bits 16 -> 20) */
+ MIPS_OTP_RD, /* Registre rs (bits 11 -> 15) */
+ MIPS_OTP_IMMEDIATE, /* Valeur imm. (bits 0 -> 15) */
+ MIPS_OTP_TARGET_ADDRESS, /* Adresse (bits 0 -> 25) */
+
+ MIPS_OTP_MEM_CONTENT, /* Contenu mémoire [base+off] */
+ MIPS_OTP_OFFSET, /* Décallage */
+ MIPS_OTP_SA /* Valeur arithmétique */
+
+} MipsOperandType;
+
+
+/* Procède à la lecture de n opérandes donnés. */
+bool mips_read_n_operands(GArchInstruction *, const bin_t *data, off_t *pos, off_t, unsigned int, ...);
+
+
+
+#endif /* _ARCH_MIPS_OPERAND_H */
diff --git a/src/arch/mips/processor.c b/src/arch/mips/processor.c
new file mode 100644
index 0000000..c28c7b4
--- /dev/null
+++ b/src/arch/mips/processor.c
@@ -0,0 +1,253 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * processor.c - gestion de l'architecture mips
+ *
+ * Copyright (C) 2009 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 "processor.h"
+
+
+#include "../processor-int.h"
+#include "opcodes.h"
+
+
+
+/* Définition du processeur de la mips (instance) */
+struct _GMipsProcessor
+{
+ GArchProcessor parent; /* Instance parente */
+
+};
+
+
+/* Définition du processeur de la mips (classe) */
+struct _GMipsProcessorClass
+{
+ GArchProcessorClass parent; /* Classe parente */
+
+};
+
+
+/* Initialise la classe des lignes de descriptions initiales. */
+static void g_mips_processor_class_init(GMipsProcessorClass *);
+
+/* Initialise la classe des lignes de descriptions initiales. */
+static void g_mips_processor_init(GMipsProcessor *);
+
+/* Décode une instruction dans un flux de données. */
+static GArchInstruction *g_mips_processor_decode_instruction(const GMipsProcessor *, const bin_t *, off_t *, off_t, vmpa_t);
+
+
+/* Indique le type défini par la GLib pour le processeur mips. */
+G_DEFINE_TYPE(GMipsProcessor, g_mips_processor, G_TYPE_ARCH_PROCESSOR);
+
+
+
+/******************************************************************************
+* *
+* Paramètres : klass = classe à initialiser. *
+* *
+* Description : Initialise la classe des lignes de descriptions initiales. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_mips_processor_class_init(GMipsProcessorClass *klass)
+{
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : proc = instance à initialiser. *
+* *
+* Description : Initialise la classe des lignes de descriptions initiales. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_mips_processor_init(GMipsProcessor *proc)
+{
+ GArchProcessor *parent; /* Instance parente */
+
+ parent = G_ARCH_PROCESSOR(proc);
+
+ parent->endianness = SRE_BIG;
+
+ parent->decode = (decode_instruction_fc)g_mips_processor_decode_instruction;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : - *
+* *
+* Description : Crée le support de l'architecture mips. *
+* *
+* Retour : Architecture mise en place. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GArchProcessor *g_mips_processor_new(void)
+{
+ GArchProcessor *result; /* Structure à retourner */
+
+ result = g_object_new(G_TYPE_MIPS_PROCESSOR, NULL);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : proc = architecture visée par la procédure. *
+* data = flux de données à analyser. *
+* pos = position courante dans ce flux. [OUT] *
+* len = taille totale des données à analyser. *
+* addr = adresse virtuelle de l'instruction. *
+* *
+* Description : Décode une instruction dans un flux de données. *
+* *
+* Retour : Instruction mise en place. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static GArchInstruction *g_mips_processor_decode_instruction(const GMipsProcessor *proc, const bin_t *data, off_t *pos, off_t len, vmpa_t addr)
+{
+ GArchInstruction *result; /* Instruction à renvoyer */
+ MipsOpcodes id; /* Identifiant d'instruction */
+
+ id = mips_guess_next_instruction(data, *pos, len);
+
+ switch (id)
+ {
+ case MOP_NOP:
+ result = mips_read_instr_nop(data, pos, len, addr, proc);
+ break;
+
+
+ case MOP_SRA:
+ result = mips_read_instr_shift_word_right_arithmetic(data, pos, len, addr, proc);
+ break;
+
+
+ case MOP_JR:
+ result = mips_read_instr_jump_register(data, pos, len, addr, proc);
+ break;
+
+ case MOP_JALR:
+ case MOP_JALR_HB:
+ result = mips_read_instr_jump_and_link_register(data, pos, len, addr, proc);
+ break;
+
+
+
+ case MOP_ADDU:
+ result = mips_read_instr_add_unsigned(data, pos, len, addr, proc);
+ break;
+
+ case MOP_SUB:
+ result = mips_read_instr_subtract_word(data, pos, len, addr, proc);
+ break;
+
+ case MOP_SUBU:
+ result = mips_read_instr_subtract_unsigned_word(data, pos, len, addr, proc);
+ break;
+
+
+
+ case MOP_AND:
+ result = mips_read_instr_and(data, pos, len, addr, proc);
+ break;
+
+
+
+ case MOP_BGEZAL:
+ result = mips_read_instr_branch_on_greater_than_or_equal_to_zero_and_link(data, pos, len, addr, proc);
+ break;
+
+
+ case MOP_BEQ:
+ result = mips_read_instr_branch_on_equal(data, pos, len, addr, proc);
+ break;
+
+
+ case MOP_BNE:
+ result = mips_read_instr_branch_on_not_equal(data, pos, len, addr, proc);
+ break;
+
+
+ case MOP_ADDIU:
+ result = mips_read_instr_add_immediate_unsigned(data, pos, len, addr, proc);
+ break;
+
+
+ case MOP_BEQL:
+ result = mips_read_instr_branch_on_equal_likely(data, pos, len, addr, proc);
+ break;
+
+
+ case MOP_LW:
+ result = mips_read_instr_load_word(data, pos, len, addr, proc);
+ break;
+
+
+ case MOP_LUI:
+ result = mips_read_instr_load_upper_immediate(data, pos, len, addr, proc);
+ break;
+
+
+
+ case MOP_LBU:
+ result = mips_read_instr_load_byte_unisgned(data, pos, len, addr, proc);
+ break;
+
+
+ case MOP_SB:
+ result = mips_read_instr_store_byte(data, pos, len, addr, proc);
+ break;
+
+ case MOP_SW:
+ result = mips_read_instr_store_word(data, pos, len, addr, proc);
+ break;
+
+
+ default:
+ result = NULL;
+ break;
+
+ }
+
+ return result;
+
+}
diff --git a/src/arch/mips/processor.h b/src/arch/mips/processor.h
new file mode 100644
index 0000000..87a9ab1
--- /dev/null
+++ b/src/arch/mips/processor.h
@@ -0,0 +1,53 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * processor.h - prototypes pour la gestion de l'architecture mips
+ *
+ * Copyright (C) 2009 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 _ARCH_MIPS_PROCESSOR_H
+#define _ARCH_MIPS_PROCESSOR_H
+
+
+#include "../processor.h"
+
+
+
+#define G_TYPE_MIPS_PROCESSOR g_mips_processor_get_type()
+#define G_MIPS_PROCESSOR(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_mips_processor_get_type(), GMipsProcessor))
+#define G_IS_MIPS_PROCESSOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_mips_processor_get_type()))
+#define G_MIPS_PROCESSOR_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE((inst), g_mips_processor_get_type(), GMipsProcessorIface))
+
+
+/* Définition du processeur de la mips (instance) */
+typedef struct _GMipsProcessor GMipsProcessor;
+
+/* Définition du processeur de la mips (classe) */
+typedef struct _GMipsProcessorClass GMipsProcessorClass;
+
+
+/* Indique le type défini par la GLib pour le processeur mips. */
+GType g_mips_processor_get_type(void);
+
+/* Crée le support de l'architecture mips. */
+GArchProcessor *g_mips_processor_new(void);
+
+
+
+#endif /* _ARCH_MIPS_PROCESSOR_H */
diff --git a/src/arch/mips/registers.c b/src/arch/mips/registers.c
new file mode 100644
index 0000000..89e13ca
--- /dev/null
+++ b/src/arch/mips/registers.c
@@ -0,0 +1,249 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * registers.c - aides auxiliaires relatives aux registres MIPS
+ *
+ * Copyright (C) 2009 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 "registers.h"
+
+
+#include <malloc.h>
+#include <stdio.h>
+
+
+
+/* Registre MIPS */
+enum _mips_register
+{
+ MIPS_REG_ZERO = 0, /* Constante zéro */
+ MIPS_REG_AT = 1, /* Temporaire assemblage */
+ MIPS_REG_V_0 = 2, /* Retours et évaluations */
+ MIPS_REG_V_1 = 3, /* Retours et évaluations */
+ MIPS_REG_ARG_0 = 4, /* Arguments de fonction */
+ MIPS_REG_ARG_1 = 5, /* Arguments de fonction */
+ MIPS_REG_ARG_2 = 6, /* Arguments de fonction */
+ MIPS_REG_ARG_3 = 7, /* Arguments de fonction */
+ MIPS_REG_TMP_0 = 8, /* Stockage temporaire */
+ MIPS_REG_TMP_1 = 9, /* Stockage temporaire */
+ MIPS_REG_TMP_2 = 10, /* Stockage temporaire */
+ MIPS_REG_TMP_3 = 11, /* Stockage temporaire */
+ MIPS_REG_TMP_4 = 12, /* Stockage temporaire */
+ MIPS_REG_TMP_5 = 13, /* Stockage temporaire */
+ MIPS_REG_TMP_6 = 14, /* Stockage temporaire */
+ MIPS_REG_TMP_7 = 15, /* Stockage temporaire */
+ MIPS_REG_SAV_0 = 16, /* Sauvegarde des registres */
+ MIPS_REG_SAV_1 = 17, /* Sauvegarde des registres */
+ MIPS_REG_SAV_2 = 18, /* Sauvegarde des registres */
+ MIPS_REG_SAV_3 = 19, /* Sauvegarde des registres */
+ MIPS_REG_SAV_4 = 20, /* Sauvegarde des registres */
+ MIPS_REG_SAV_5 = 21, /* Sauvegarde des registres */
+ MIPS_REG_SAV_6 = 22, /* Sauvegarde des registres */
+ MIPS_REG_SAV_7 = 23, /* Sauvegarde des registres */
+ MIPS_REG_TMP_8 = 24, /* Stockage temporaire */
+ MIPS_REG_TMP_9 = 25, /* Stockage temporaire */
+ MIPS_REG_KERN_0 = 26, /* Réservé pour le noyau */
+ MIPS_REG_KERN_1 = 27, /* Réservé pour le noyau */
+ MIPS_REG_GLOBAL = 28, /* Pointeur global */
+ MIPS_REG_STACK = 29, /* Pointeur de pile */
+ MIPS_REG_FRAME = 30, /* Pointeur de frame */
+ MIPS_REG_RET = 31 /* Adresse de retour */
+
+};
+
+
+
+/******************************************************************************
+* *
+* Paramètres : value = valeur correspondant au registre. *
+* *
+* Description : Récupère l'indentifiant interne d'un registre. *
+* *
+* Retour : Registre définit ou NULL. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+mips_register *get_mips_register(bin_t value)
+{
+ mips_register *result; /* Représentation à renvoyer */
+
+ if (value > 31) return NULL;
+
+ result = (mips_register *)calloc(1, sizeof(mips_register));
+
+ *result = value;
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : reg = registre à supprimer. *
+* *
+* Description : Efface de la mémoire l'indentifiant interne d'un registre. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void free_mips_register(mips_register *reg)
+{
+ free(reg);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : reg = registre à consulter. *
+* *
+* Description : Indique si le registre correspond à ra. *
+* *
+* Retour : true si la correspondance est avérée, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool is_mips_register_return_address(const mips_register *reg)
+{
+ return (*reg == MIPS_REG_RET);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : reg = registre à imprimer. *
+* syntax = type de représentation demandée. *
+* *
+* Description : Traduit un registre MIPS en texte. *
+* *
+* Retour : Traduction en chaîne à libérer de la mémoire. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+char *mips_register_as_text(const mips_register *reg, AsmSyntax syntax)
+{
+ char *result; /* Chaîne à renvoyer */
+
+ result = (char *)calloc(6, sizeof(char));
+
+ switch (syntax)
+ {
+ case ASX_INTEL:
+ switch (*reg)
+ {
+ case MIPS_REG_ZERO:
+ snprintf(result, 6, "zero");
+ break;
+ case MIPS_REG_AT:
+ snprintf(result, 6, "at");
+ break;
+ case MIPS_REG_V_0 ... MIPS_REG_V_1:
+ snprintf(result, 6, "v%c", '0' + *reg - MIPS_REG_V_0);
+ break;
+ case MIPS_REG_ARG_0 ... MIPS_REG_ARG_3:
+ snprintf(result, 6, "a%c", '0' + *reg - MIPS_REG_ARG_0);
+ break;
+ case MIPS_REG_TMP_0 ... MIPS_REG_TMP_7:
+ snprintf(result, 6, "t%c", '0' + *reg - MIPS_REG_TMP_0);
+ break;
+ case MIPS_REG_SAV_0 ... MIPS_REG_SAV_7:
+ snprintf(result, 6, "s%c", '0' + *reg - MIPS_REG_SAV_0);
+ break;
+ case MIPS_REG_TMP_8 ... MIPS_REG_TMP_9:
+ snprintf(result, 6, "t%c", '8' + *reg - MIPS_REG_TMP_8);
+ break;
+ case MIPS_REG_KERN_0 ... MIPS_REG_KERN_1:
+ snprintf(result, 6, "k%c", '0' + *reg - MIPS_REG_KERN_0);
+ break;
+ case MIPS_REG_GLOBAL:
+ snprintf(result, 6, "gp");
+ break;
+ case MIPS_REG_STACK:
+ snprintf(result, 6, "sp");
+ break;
+ case MIPS_REG_FRAME:
+ snprintf(result, 6, "fp");
+ break;
+ case MIPS_REG_RET:
+ snprintf(result, 6, "ra");
+ break;
+ }
+ break;
+
+ case ASX_ATT:
+ switch (*reg)
+ {
+ case MIPS_REG_ZERO:
+ snprintf(result, 6, "%%zero");
+ break;
+ case MIPS_REG_AT:
+ snprintf(result, 6, "%%at");
+ break;
+ case MIPS_REG_V_0 ... MIPS_REG_V_1:
+ snprintf(result, 6, "%%v%c", '0' + *reg - MIPS_REG_V_0);
+ break;
+ case MIPS_REG_ARG_0 ... MIPS_REG_ARG_3:
+ snprintf(result, 6, "%%a%c", '0' + *reg - MIPS_REG_ARG_0);
+ break;
+ case MIPS_REG_TMP_0 ... MIPS_REG_TMP_7:
+ snprintf(result, 6, "%%t%c", '0' + *reg - MIPS_REG_TMP_0);
+ break;
+ case MIPS_REG_SAV_0 ... MIPS_REG_SAV_7:
+ snprintf(result, 6, "%%s%c", '0' + *reg - MIPS_REG_SAV_0);
+ break;
+ case MIPS_REG_TMP_8 ... MIPS_REG_TMP_9:
+ snprintf(result, 6, "%%t%c", '8' + *reg - MIPS_REG_TMP_8);
+ break;
+ case MIPS_REG_KERN_0 ... MIPS_REG_KERN_1:
+ snprintf(result, 6, "%%k%c", '0' + *reg - MIPS_REG_KERN_0);
+ break;
+ case MIPS_REG_GLOBAL:
+ snprintf(result, 6, "%%gp");
+ break;
+ case MIPS_REG_STACK:
+ snprintf(result, 6, "%%sp");
+ break;
+ case MIPS_REG_FRAME:
+ snprintf(result, 6, "%%fp");
+ break;
+ case MIPS_REG_RET:
+ snprintf(result, 6, "%%ra");
+ break;
+ }
+ break;
+
+ default:
+ break;
+
+ }
+
+ return result;
+
+}
diff --git a/src/arch/mips/registers.h b/src/arch/mips/registers.h
new file mode 100644
index 0000000..a9aaaae
--- /dev/null
+++ b/src/arch/mips/registers.h
@@ -0,0 +1,51 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * registers.h - prototypes pour les aides auxiliaires relatives aux registres MIPS
+ *
+ * Copyright (C) 2009 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 _ARCH_MIPS_REGISTERS_H
+#define _ARCH_MIPS_REGISTERS_H
+
+
+#include "../archbase.h"
+#include "../operand.h"
+
+
+
+/* Registre MIPS */
+typedef enum _mips_register mips_register;
+
+
+/* Récupère l'indentifiant interne d'un registre. */
+mips_register *get_mips_register(bin_t);
+
+/* Efface de la mémoire l'indentifiant interne d'un registre. */
+void free_mips_register(mips_register *);
+
+/* Indique si le registre correspond à ra. */
+bool is_mips_register_return_address(const mips_register *);
+
+/* Traduit un registre MIPS en texte. */
+char *mips_register_as_text(const mips_register *, AsmSyntax);
+
+
+
+#endif /* _ARCH_MIPS_REGISTERS_H */
diff --git a/src/arch/processor.c b/src/arch/processor.c
index 191fa10..317e893 100644
--- a/src/arch/processor.c
+++ b/src/arch/processor.c
@@ -43,6 +43,7 @@
#include "artificial.h"
#include "jvm/processor.h"
+#include "mips/processor.h"
#include "x86/processor.h"
@@ -189,8 +190,9 @@ GArchInstruction *g_arch_processor_decode_instruction(const GArchProcessor *proc
bool init_all_processors(void)
{
- _processors_list[APT_386] = g_x86_processor_new();
_processors_list[APT_JVM] = g_jvm_processor_new();
+ _processors_list[APT_MIPS] = g_mips_processor_new();
+ _processors_list[APT_386] = g_x86_processor_new();
return true;
diff --git a/src/arch/processor.h b/src/arch/processor.h
index c37811f..5726197 100644
--- a/src/arch/processor.h
+++ b/src/arch/processor.h
@@ -84,8 +84,9 @@ GArchInstruction *g_arch_processor_decode_instruction(const GArchProcessor *, co
/* Type de processeurs disponibles */
typedef enum _ArchProcessorType
{
- APT_386, /* Intel 80386 */
APT_JVM, /* Java Virtual Machine */
+ APT_MIPS, /* Mips 32 ou 64 bits */
+ APT_386, /* Intel 80386 */
APT_COUNT
diff --git a/src/arch/x86/instruction.c b/src/arch/x86/instruction.c
new file mode 100644
index 0000000..f68ec59
--- /dev/null
+++ b/src/arch/x86/instruction.c
@@ -0,0 +1,507 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * instruction.c - gestion des instructions de l'architecture x86
+ *
+ * Copyright (C) 2009 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 "instruction.h"
+
+
+#include "../instruction-int.h"
+#include "../../common/extstr.h"
+
+
+
+/* Définition générique d'une instruction d'architecture x86 (instance) */
+struct _GX86Instruction
+{
+ GArchInstruction parent; /* A laisser en premier */
+
+ X86Opcodes type; /* Position dans la liste */
+
+ X86Prefix prefixes; /* Préfixes finalement trouvés */
+
+};
+
+/* Définition générique d'une instruction d'architecture x86 (classe) */
+struct _GX86InstructionClass
+{
+ GArchInstructionClass parent; /* A laisser en premier */
+
+};
+
+
+/* Initialise la classe des instructions pour x86. */
+static void g_x86_instruction_class_init(GX86InstructionClass *);
+
+/* Initialise une instance d'opérande d'architecture x86. */
+static void g_x86_instruction_init(GX86Instruction *);
+
+
+
+/* --------------------- AIDE A LA MISE EN PLACE D'INSTRUCTIONS --------------------- */
+
+
+/* Répertoire de toutes les instructions x86 */
+typedef struct _x86_instruction
+{
+ bool care_of_data; /* Devinette = repas ? */
+ bin_t opcode; /* Opcode de l'instruction */
+ bin_t op_extension; /* Extension de l'opcode */
+
+ const char *keyword; /* Mot clef de la commande */
+
+ X86Prefix prefix; /* Eventuel(s) préfixe(s) */
+
+} x86_instruction;
+
+
+#define OPCODE_EXT(eop) ((eop) & 0x38)
+#define IDX_TO_EXT(idx) (idx == -1 ? 0xff : idx << 3)
+
+
+static x86_instruction _instructions[XOP_COUNT] = {
+
+ [XOP_ADD_RM8_R8] = { false, 0x00, IDX_TO_EXT(-1), "add", XPX_NONE },
+ [XOP_ADD_RM1632_R1632] = { false, 0x01, IDX_TO_EXT(-1), "add", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_ADD_R8_RM8] = { false, 0x02, IDX_TO_EXT(-1), "add", XPX_NONE },
+ [XOP_ADD_R1632_RM1632] = { false, 0x03, IDX_TO_EXT(-1), "add", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_ADD_AL_IMM8] = { false, 0x04, IDX_TO_EXT(-1), "add", XPX_NONE },
+ [XOP_ADD_E_AX_IMM1632] = { false, 0x05, IDX_TO_EXT(-1), "add", XPX_OPERAND_SIZE_OVERRIDE },
+
+ [XOP_OR_R8_RM8] = { false, 0x0a, IDX_TO_EXT(-1), "or", XPX_NONE },
+ [XOP_OR_AL_IMM8] = { false, 0x0c, IDX_TO_EXT(-1), "or", XPX_NONE },
+
+ [XOP_ADC_RM8_R8] = { false, 0x10, IDX_TO_EXT(-1), "adc", XPX_NONE },
+
+ [XOP_AND_RM8_R8] = { false, 0x20, IDX_TO_EXT(-1), "and", XPX_NONE },
+
+ [XOP_SUB_RM1632_R1632] = { false, 0x29, IDX_TO_EXT(-1), "sub", XPX_OPERAND_SIZE_OVERRIDE },
+
+ [XOP_SUB_R8_RM8] = { false, 0x2a, IDX_TO_EXT(-1), "sub", XPX_NONE },
+ [XOP_SUB_AL_IMM8] = { false, 0x2c, IDX_TO_EXT(-1), "sub", XPX_NONE },
+
+ [XOP_SUB_E_AX_IMM1632] = { false, 0x2d, IDX_TO_EXT(-1), "sub", XPX_OPERAND_SIZE_OVERRIDE },
+
+
+
+ [XOP_XOR_RM8_R8] = { false, 0x30, IDX_TO_EXT(-1), "xor", XPX_NONE},
+ [XOP_XOR_RM1632_R1632] = { false, 0x31, IDX_TO_EXT(-1), "xor", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_XOR_R8_RM8] = { false, 0x32, IDX_TO_EXT(-1), "xor", XPX_NONE},
+ [XOP_XOR_R1632_RM1632] = { false, 0x33, IDX_TO_EXT(-1), "xor", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_XOR_AL_IMM8] = { false, 0x34, IDX_TO_EXT(-1), "xor", XPX_NONE },
+ [XOP_XOR_E_AX_IMM1632] = { false, 0x35, IDX_TO_EXT(-1), "xor", XPX_OPERAND_SIZE_OVERRIDE },
+
+
+
+
+
+ [XOP_CMP_RM1632_R1632] = { false, 0x39, IDX_TO_EXT(-1), "cmp", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_INC_E_AX] = { true, 0x40, IDX_TO_EXT(-1), "inc", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_INC_E_CX] = { true, 0x41, IDX_TO_EXT(-1), "inc", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_INC_E_DX] = { true, 0x42, IDX_TO_EXT(-1), "inc", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_INC_E_BX] = { true, 0x43, IDX_TO_EXT(-1), "inc", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_INC_E_SP] = { true, 0x44, IDX_TO_EXT(-1), "inc", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_INC_E_BP] = { true, 0x45, IDX_TO_EXT(-1), "inc", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_INC_E_SI] = { true, 0x46, IDX_TO_EXT(-1), "inc", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_INC_E_DI] = { true, 0x47, IDX_TO_EXT(-1), "inc", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_DEC_E_AX] = { true, 0x48, IDX_TO_EXT(-1), "dec", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_DEC_E_CX] = { true, 0x49, IDX_TO_EXT(-1), "dec", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_DEC_E_DX] = { true, 0x4a, IDX_TO_EXT(-1), "dec", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_DEC_E_BX] = { true, 0x4b, IDX_TO_EXT(-1), "dec", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_DEC_E_SP] = { true, 0x4c, IDX_TO_EXT(-1), "dec", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_DEC_E_BP] = { true, 0x4d, IDX_TO_EXT(-1), "dec", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_DEC_E_SI] = { true, 0x4e, IDX_TO_EXT(-1), "dec", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_DEC_E_DI] = { true, 0x4f, IDX_TO_EXT(-1), "dec", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_PUSH_E_AX] = { true, 0x50, IDX_TO_EXT(-1), "push", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_PUSH_E_CX] = { true, 0x51, IDX_TO_EXT(-1), "push", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_PUSH_E_DX] = { true, 0x52, IDX_TO_EXT(-1), "push", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_PUSH_E_BX] = { true, 0x53, IDX_TO_EXT(-1), "push", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_PUSH_E_SP] = { true, 0x54, IDX_TO_EXT(-1), "push", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_PUSH_E_BP] = { true, 0x55, IDX_TO_EXT(-1), "push", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_PUSH_E_SI] = { true, 0x56, IDX_TO_EXT(-1), "push", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_PUSH_E_DI] = { true, 0x57, IDX_TO_EXT(-1), "push", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_POP_E_AX] = { true, 0x58, IDX_TO_EXT(-1), "pop", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_POP_E_CX] = { true, 0x59, IDX_TO_EXT(-1), "pop", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_POP_E_DX] = { true, 0x5a, IDX_TO_EXT(-1), "pop", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_POP_E_BX] = { true, 0x5b, IDX_TO_EXT(-1), "pop", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_POP_E_SP] = { true, 0x5c, IDX_TO_EXT(-1), "pop", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_POP_E_BP] = { true, 0x5d, IDX_TO_EXT(-1), "pop", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_POP_E_SI] = { true, 0x5e, IDX_TO_EXT(-1), "pop", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_POP_E_DI] = { true, 0x5f, IDX_TO_EXT(-1), "pop", XPX_OPERAND_SIZE_OVERRIDE },
+
+
+ [XOP_PUSH_IMM1632] = { false, 0x68, IDX_TO_EXT(-1), "push", XPX_OPERAND_SIZE_OVERRIDE },
+
+
+
+ [XOP_JO_REL8] = { false, 0x70, IDX_TO_EXT(-1), "jo", XPX_NONE },
+ [XOP_JNO_REL8] = { false, 0x71, IDX_TO_EXT(-1), "jno", XPX_NONE },
+ [XOP_JB_REL8] = { false, 0x72, IDX_TO_EXT(-1), "jb", XPX_NONE },
+ [XOP_JNB_REL8] = { false, 0x73, IDX_TO_EXT(-1), "jnb", XPX_NONE },
+ [XOP_JE_REL8] = { false, 0x74, IDX_TO_EXT(-1), "je", XPX_NONE },
+ [XOP_JNE_REL8] = { false, 0x75, IDX_TO_EXT(-1), "jne", XPX_NONE },
+ [XOP_JNA_REL8] = { false, 0x76, IDX_TO_EXT(-1), "jna", XPX_NONE },
+ [XOP_JA_REL8] = { false, 0x77, IDX_TO_EXT(-1), "ja", XPX_NONE },
+ [XOP_JS_REL8] = { false, 0x78, IDX_TO_EXT(-1), "js", XPX_NONE },
+ [XOP_JNS_REL8] = { false, 0x79, IDX_TO_EXT(-1), "jns", XPX_NONE },
+ [XOP_JP_REL8] = { false, 0x7a, IDX_TO_EXT(-1), "jp", XPX_NONE },
+ [XOP_JNP_REL8] = { false, 0x7b, IDX_TO_EXT(-1), "jnp", XPX_NONE },
+ [XOP_JL_REL8] = { false, 0x7c, IDX_TO_EXT(-1), "jl", XPX_NONE },
+ [XOP_JNL_REL8] = { false, 0x7d, IDX_TO_EXT(-1), "jnl", XPX_NONE },
+ [XOP_JNG_REL8] = { false, 0x7e, IDX_TO_EXT(-1), "jng", XPX_NONE },
+ [XOP_JG_REL8] = { false, 0x7f, IDX_TO_EXT(-1), "jg", XPX_NONE },
+ [XOP_ADD_RM8_IMM8] = { false, 0x80, IDX_TO_EXT(0), "add", XPX_NONE },
+ [XOP_OR_RM8_IMM8] = { false, 0x80, IDX_TO_EXT(1), "or", XPX_NONE },
+ [XOP_ADC_RM8_IMM8] = { false, 0x80, IDX_TO_EXT(2), "adc", XPX_NONE },
+ [XOP_SBB_RM8_IMM8] = { false, 0x80, IDX_TO_EXT(3), "sbb", XPX_NONE },
+ [XOP_AND_RM8_IMM8] = { false, 0x80, IDX_TO_EXT(4), "and", XPX_NONE },
+ [XOP_SUB_RM8_IMM8] = { false, 0x80, IDX_TO_EXT(5), "sub", XPX_NONE },
+ [XOP_XOR_RM8_IMM8] = { false, 0x80, IDX_TO_EXT(6), "xor", XPX_NONE },
+ [XOP_CMP_RM8_IMM8] = { false, 0x80, IDX_TO_EXT(7), "cmp", XPX_NONE },
+ [XOP_ADD_RM1632_IMM1632] = { false, 0x81, IDX_TO_EXT(0), "add", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_OR_RM1632_IMM1632] = { false, 0x81, IDX_TO_EXT(0), "add", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_ADC_RM1632_IMM1632] = { false, 0x81, IDX_TO_EXT(2), "adc", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_SBB_RM1632_IMM1632] = { false, 0x81, IDX_TO_EXT(3), "sbb", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_AND_RM1632_IMM1632] = { false, 0x81, IDX_TO_EXT(4), "and", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_SUB_RM1632_IMM1632] = { false, 0x81, IDX_TO_EXT(5), "sub", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_XOR_RM1632_IMM1632] = { false, 0x81, IDX_TO_EXT(6), "xor", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_CMP_RM1632_IMM1632] = { false, 0x81, IDX_TO_EXT(7), "cmp", XPX_OPERAND_SIZE_OVERRIDE },
+
+
+
+ [XOP_ADD_RM1632_IMM8] = { false, 0x83, IDX_TO_EXT(0), "add", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_OR_RM1632_IMM8] = { false, 0x83, IDX_TO_EXT(1), "or", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_ADC_RM1632_IMM8] = { false, 0x83, IDX_TO_EXT(2), "adc", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_SBB_RM1632_IMM8] = { false, 0x83, IDX_TO_EXT(3), "sbb", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_AND_RM1632_IMM8] = { false, 0x83, IDX_TO_EXT(4), "and", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_SUB_RM1632_IMM8] = { false, 0x83, IDX_TO_EXT(5), "sub", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_XOR_RM1632_IMM8] = { false, 0x83, IDX_TO_EXT(6), "xor", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_CMP_RM1632_IMM8] = { false, 0x83, IDX_TO_EXT(7), "cmp", XPX_OPERAND_SIZE_OVERRIDE },
+
+
+ [XOP_TEST_RM8_R8] = { false, 0x84, IDX_TO_EXT(-1), "test", XPX_NONE },
+ [XOP_TEST_RM1632_R1632] = { false, 0x85, IDX_TO_EXT(-1), "test", XPX_OPERAND_SIZE_OVERRIDE },
+
+ [XOP_MOV_RM8_R8] = { false, 0x88, IDX_TO_EXT(-1), "mov", XPX_NONE },
+ [XOP_MOV_RM1632_R1632] = { false, 0x89, IDX_TO_EXT(-1), "mov", XPX_OPERAND_SIZE_OVERRIDE },
+
+
+ [XOP_MOV_R1632_RM1632] = { false, 0x8b, IDX_TO_EXT(-1), "mov", XPX_OPERAND_SIZE_OVERRIDE },
+
+
+ [XOP_LEA_R1632_M] = { false, 0x8d, IDX_TO_EXT(-1), "lea", XPX_OPERAND_SIZE_OVERRIDE },
+
+
+ [XOP_NOP] = { false, 0x90, IDX_TO_EXT(-1), "nop", XPX_NONE },
+ [XOP_XCHG_R1632_E_AX] = { true, 0x90, IDX_TO_EXT(-1), "xchg", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_XCHG_R1632_E_CX] = { true, 0x91, IDX_TO_EXT(-1), "xchg", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_XCHG_R1632_E_DX] = { true, 0x92, IDX_TO_EXT(-1), "xchg", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_XCHG_R1632_E_BX] = { true, 0x93, IDX_TO_EXT(-1), "xchg", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_XCHG_R1632_E_SP] = { true, 0x94, IDX_TO_EXT(-1), "xchg", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_XCHG_R1632_E_BP] = { true, 0x95, IDX_TO_EXT(-1), "xchg", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_XCHG_R1632_E_SI] = { true, 0x96, IDX_TO_EXT(-1), "xchg", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_XCHG_R1632_E_DI] = { true, 0x97, IDX_TO_EXT(-1), "xchg", XPX_OPERAND_SIZE_OVERRIDE },
+
+
+
+ [XOP_MOV_AL_MOFFS8] = { false, 0xa0, IDX_TO_EXT(-1), "mov", XPX_NONE },
+ [XOP_MOV_E_AX_MOFFS1632] = { false, 0xa1, IDX_TO_EXT(-1), "mov", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_MOV_MOFFS8_AL] = { false, 0xa2, IDX_TO_EXT(-1), "mov", XPX_NONE },
+ [XOP_MOV_MOFFS1632_E_AX] = { false, 0xa3, IDX_TO_EXT(-1), "mov", XPX_OPERAND_SIZE_OVERRIDE },
+
+
+ [XOP_TEST_AL_IMM8] = { false, 0xa8, IDX_TO_EXT(-1), "test", XPX_NONE },
+ [XOP_TEST_E_AX_IMM1632] = { false, 0xa9, IDX_TO_EXT(-1), "test", XPX_OPERAND_SIZE_OVERRIDE },
+
+
+ [XOP_SCAS_AL_M8] = { false, 0xae, IDX_TO_EXT(-1), "scas", XPX_NONE },
+
+
+ [XOP_MOV_AL_IMM8] = { true, 0xb0, IDX_TO_EXT(-1), "mov", XPX_NONE },
+ [XOP_MOV_CL_IMM8] = { true, 0xb1, IDX_TO_EXT(-1), "mov", XPX_NONE },
+ [XOP_MOV_DL_IMM8] = { true, 0xb2, IDX_TO_EXT(-1), "mov", XPX_NONE },
+ [XOP_MOV_BL_IMM8] = { true, 0xb3, IDX_TO_EXT(-1), "mov", XPX_NONE },
+ [XOP_MOV_AH_IMM8] = { true, 0xb4, IDX_TO_EXT(-1), "mov", XPX_NONE },
+ [XOP_MOV_CH_IMM8] = { true, 0xb5, IDX_TO_EXT(-1), "mov", XPX_NONE },
+ [XOP_MOV_DH_IMM8] = { true, 0xb6, IDX_TO_EXT(-1), "mov", XPX_NONE },
+ [XOP_MOV_BH_IMM8] = { true, 0xb7, IDX_TO_EXT(-1), "mov", XPX_NONE },
+ [XOP_MOV_E_AX_IMM1632] = { true, 0xb8, IDX_TO_EXT(-1), "mov", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_MOV_E_CX_IMM1632] = { true, 0xb9, IDX_TO_EXT(-1), "mov", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_MOV_E_DX_IMM1632] = { true, 0xba, IDX_TO_EXT(-1), "mov", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_MOV_E_BX_IMM1632] = { true, 0xbb, IDX_TO_EXT(-1), "mov", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_MOV_E_SP_IMM1632] = { true, 0xbc, IDX_TO_EXT(-1), "mov", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_MOV_E_BP_IMM1632] = { true, 0xbd, IDX_TO_EXT(-1), "mov", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_MOV_E_SI_IMM1632] = { true, 0xbe, IDX_TO_EXT(-1), "mov", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_MOV_E_DI_IMM1632] = { true, 0xbf, IDX_TO_EXT(-1), "mov", XPX_OPERAND_SIZE_OVERRIDE },
+
+
+
+ [XOP_ROL_RM1632_IMM8] = { false, 0xc1, IDX_TO_EXT(0), "rol", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_ROR_RM1632_IMM8] = { false, 0xc1, IDX_TO_EXT(1), "ror", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_RCL_RM1632_IMM8] = { false, 0xc1, IDX_TO_EXT(2), "rcl", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_RCR_RM1632_IMM8] = { false, 0xc1, IDX_TO_EXT(3), "rcr", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_SHL_RM1632_IMM8] = { false, 0xc1, IDX_TO_EXT(4), "shl", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_SHR_RM1632_IMM8] = { false, 0xc1, IDX_TO_EXT(5), "shr", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_SAL_RM1632_IMM8] = { false, 0xc1, IDX_TO_EXT(6), "sal", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_SAR_RM1632_IMM8] = { false, 0xc1, IDX_TO_EXT(7), "sar", XPX_OPERAND_SIZE_OVERRIDE },
+
+
+ [XOP_RET] = { false, 0xc3, IDX_TO_EXT(-1), "ret", XPX_NONE },
+
+
+ [XOP_MOV_RM8_IMM8] = { false, 0xc6, IDX_TO_EXT(0), "mov", XPX_NONE },
+ [XOP_MOV_RM1632_IMM1632] = { false, 0xc7, IDX_TO_EXT(0), "mov", XPX_OPERAND_SIZE_OVERRIDE },
+
+
+
+ [XOP_LEAVE] = { false, 0xc9, IDX_TO_EXT(-1), "leave", XPX_NONE },
+
+
+ [XOP_INT_3] = { false, 0xcc, IDX_TO_EXT(-1), "int", XPX_NONE },
+ [XOP_INT] = { false, 0xcd, IDX_TO_EXT(-1), "int", XPX_NONE },
+
+
+ [XOP_SHL_RM1632_CL] = { false, 0xd3, IDX_TO_EXT(4), "shl", XPX_OPERAND_SIZE_OVERRIDE },
+
+
+ [XOP_CALL_REL1632] = { false, 0xe8, IDX_TO_EXT(-1), "call", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_JMP_REL1632] = { false, 0xe9, IDX_TO_EXT(-1), "jmp", XPX_OPERAND_SIZE_OVERRIDE },
+
+ [XOP_JMP_REL8] = { false, 0xeb, IDX_TO_EXT(-1), "jmp", XPX_NONE },
+
+ [XOP_HLT] = { false, 0xf4, IDX_TO_EXT(-1), "hlt", XPX_NONE },
+
+ [XOP_NOT_RM1632] = { false, 0xf7, IDX_TO_EXT(2), "not", XPX_OPERAND_SIZE_OVERRIDE },
+
+
+ [XOP_CLD] = { false, 0xfc, IDX_TO_EXT(-1), "cld", XPX_NONE },
+
+ [XOP_CALL_RM1632] = { false, 0xff, IDX_TO_EXT(2), "call", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_JMP_RM1632] = { false, 0xff, IDX_TO_EXT(4), "jmp", XPX_OPERAND_SIZE_OVERRIDE },
+ [XOP_PUSH_RM1632] = { false, 0xff, IDX_TO_EXT(6), "push", XPX_OPERAND_SIZE_OVERRIDE }
+
+};
+
+
+
+
+
+/* Traduit une instruction en version humainement lisible. */
+static const char *x86_get_instruction_text(const GX86Instruction *, const exe_format *, AsmSyntax);
+
+
+
+
+
+
+/* Indique le type défini pour une instruction d'architecture x86. */
+G_DEFINE_TYPE(GX86Instruction, g_x86_instruction, G_TYPE_ARCH_INSTRUCTION);
+
+
+
+/******************************************************************************
+* *
+* Paramètres : klass = classe à initialiser. *
+* *
+* Description : Initialise la classe des instructions pour x86. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_x86_instruction_class_init(GX86InstructionClass *klass)
+{
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : instr = instance à initialiser. *
+* *
+* Description : Initialise une instance d'instruction d'architecture x86. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_x86_instruction_init(GX86Instruction *instr)
+{
+ GArchInstruction *parent; /* Instance parente */
+
+ parent = G_ARCH_INSTRUCTION(instr);
+
+ parent->get_text = (get_instruction_text_fc)x86_get_instruction_text;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : type = type d'instruction à représenter. *
+* *
+* Description : Crée une instruction pour l'architecture x86. *
+* *
+* Retour : Architecture mise en place. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GArchInstruction *g_x86_instruction_new(X86Opcodes type)
+{
+ GArchInstruction *result; /* Structure à retourner */
+
+ result = g_object_new(G_TYPE_X86_INSTRUCTION, NULL);
+
+ G_X86_INSTRUCTION(result)->type = type;
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : instr = instruction à venir compléter. *
+* prefixes = listes des préfixes rencontrés. *
+* *
+* Description : Attache à une instructions ses préfixes associés. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_x86_instruction_set_prefixes(GX86Instruction *instr, X86Prefix prefixes)
+{
+ instr->prefixes = prefixes;
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* AIDE A LA MISE EN PLACE D'INSTRUCTIONS */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+* *
+* Paramètres : data = flux de données à analyser. *
+* pos = position courante dans ce flux. *
+* len = taille totale des données à analyser. *
+* prefix = éventuel(s) préfixe(s) remarqué(s). [OUT] *
+* care = la lecture de l'instr. veut-elle les opcodes ? [OUT]*
+* *
+* Description : Recherche l'identifiant de la prochaine instruction. *
+* *
+* Retour : Identifiant de la prochaine instruction à tenter de charger. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+X86Opcodes x86_guess_next_instruction(const bin_t *data, off_t pos, off_t len, X86Prefix *prefix, bool *care)
+{
+ X86Opcodes result; /* Identifiant à retourner */
+ X86Prefix extra; /* Préfixes n'intervenant pas */
+ bin_t opcode; /* Opcode à trouver */
+
+ extra = XPX_NONE;
+ *prefix = XPX_NONE;
+
+ while (pos < len)
+ switch (data[pos])
+ {
+ case 0x66:
+ pos++;
+ *prefix |= XPX_OPERAND_SIZE_OVERRIDE;
+ break;
+ case 0xf2:
+ pos++;
+ extra |= XPX_REPEAT_STRING_OPERATION;
+ break;
+ default:
+ goto xgni_look_for;
+ break;
+ }
+
+ xgni_look_for:
+
+ if (pos == len) return XOP_COUNT;
+
+ opcode = data[pos];
+
+ for (result = 0; result < XOP_COUNT; result++)
+ {
+ if ((_instructions[result].prefix & *prefix) != *prefix) continue;
+
+ if (_instructions[result].opcode != opcode) continue;
+
+ if (_instructions[result].op_extension != IDX_TO_EXT(-1))
+ {
+ if ((pos + 1) == len) continue;
+ if (_instructions[result].op_extension != OPCODE_EXT(data[pos + 1])) continue;
+ }
+
+ *prefix |= extra;
+ *care = _instructions[result].care_of_data;
+ break;
+
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* 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 : - *
+* *
+******************************************************************************/
+
+static const char *x86_get_instruction_text(const GX86Instruction *instr, const exe_format *format, AsmSyntax syntax)
+{
+ const char *result; /* Chaîne à retourner */
+
+ result = strdup(_instructions[instr->type].keyword);
+
+ if (instr->prefixes & XPX_REPEAT_STRING_OPERATION)
+ result = strprep(result, "repnz ");
+
+ return result;
+
+}
diff --git a/src/arch/x86/op_jump.c b/src/arch/x86/op_jump.c
index 709ff24..be993f1 100644
--- a/src/arch/x86/op_jump.c
+++ b/src/arch/x86/op_jump.c
@@ -1,6 +1,6 @@
/* OpenIDA - Outil d'analyse de fichiers binaires
- * op_jump.c - décodage des sauts conditionnels
+ * op_jump.c - décodage des sauts inconditionnels
*
* Copyright (C) 2008 Cyrille Bagard
*
diff --git a/src/arch/x86/op_scas.c b/src/arch/x86/op_scas.c
new file mode 100644
index 0000000..2ec8230
--- /dev/null
+++ b/src/arch/x86/op_scas.c
@@ -0,0 +1,63 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * op_scas.c - décodage des recherches dans des chaînes ASCII
+ *
+ * Copyright (C) 2009 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 <malloc.h>
+
+
+#include "../instruction-int.h"
+#include "opcodes.h"
+#include "operand.h"
+
+
+
+/******************************************************************************
+* *
+* Paramètres : data = flux de données à analyser. *
+* pos = position courante dans ce flux. [OUT] *
+* len = taille totale des données à analyser. *
+* addr = adresse virtuelle de l'instruction. *
+* proc = architecture ciblée par le désassemblage. *
+* *
+* Description : Décode une instruction de type 'scas al, ...' (8 bits). *
+* *
+* Retour : Instruction mise en place ou NULL. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GArchInstruction *x86_read_instr_scas_al_m8(const bin_t *data, off_t *pos, off_t len, vmpa_t addr, X86Prefix prefix, const GX86Processor *proc)
+{
+ GArchInstruction *result; /* Instruction à retourner */
+
+ result = g_x86_instruction_new(XOP_SCAS_AL_M8);
+
+ if (!x86_read_two_operands(result, data, pos, len, X86_OTP_AL, X86_OTP_AL/*FIXME*/))
+ {
+ /* TODO free(result);*/
+ return NULL;
+ }
+
+ return result;
+
+}
diff --git a/src/arch/x86/operand.c b/src/arch/x86/operand.c
index e916541..5e01fd7 100644
--- a/src/arch/x86/operand.c
+++ b/src/arch/x86/operand.c
@@ -40,7 +40,7 @@
/* ---------------------- COQUILLE VIDE POUR LES OPERANDES X86 ---------------------- */
-/* Définition d'un opérande de la x86 (instance) */
+/* Définition d'un opérande de x86 (instance) */
struct _GX86Operand
{
GArchOperand parent; /* Instance parente */
@@ -48,7 +48,7 @@ struct _GX86Operand
};
-/* Définition d'un opérande de la x86 (classe) */
+/* Définition d'un opérande de x86 (classe) */
struct _GX86OperandClass
{
GArchOperandClass parent; /* Classe parente */
@@ -59,7 +59,7 @@ struct _GX86OperandClass
/* Initialise la classe des opérandes x86 de base. */
static void g_x86_operand_class_init(GX86OperandClass *);
-/* Initialise une instance d'opérande de base pour la x86. */
+/* Initialise une instance d'opérande de base pour x86. */
static void g_x86_operand_init(GX86Operand *);
@@ -224,7 +224,7 @@ static void g_x86_operand_class_init(GX86OperandClass *klass)
* *
* Paramètres : operand = instance à initialiser. *
* *
-* Description : Initialise une instance d'opérande de registre x86. *
+* Description : Initialise une instance d'opérande de base pour x86. *
* *
* Retour : - *
* *
@@ -297,7 +297,7 @@ static void g_x86_register_operand_init(GX86RegisterOperand *operand)
* size = taille de l'opérande, et donc du registre. *
* base = indice du premier registre. *
* *
-* Description : Crée un opérande visant un registre X86. *
+* Description : Crée un opérande visant un registre x86. *
* *
* Retour : Opérande mis en place. *
* *
@@ -336,7 +336,7 @@ GArchOperand *g_x86_register_operand_new_from_opcode(const bin_t *data, off_t *p
* size = taille de l'opérande, et donc du registre. *
* first = indique la partie du ModR/M à traiter. *
* *
-* Description : Crée un opérande visant un registre X86. *
+* Description : Crée un opérande visant un registre x86. *
* *
* Retour : Opérande mis en place. *
* *
@@ -376,7 +376,7 @@ GArchOperand *g_x86_register_operand_new_from_mod_rm(const bin_t *data, off_t *p
* Paramètres : index = indice du registre visé. *
* size = taille de l'opérande, et donc du registre. *
* *
-* Description : Crée un opérande visant un registre X86 donnée. *
+* Description : Crée un opérande visant un registre x86 donné. *
* *
* Retour : Opérande mis en place. *
* *
diff --git a/src/arch/x86/operand.h b/src/arch/x86/operand.h
index ebab200..1139fe2 100644
--- a/src/arch/x86/operand.h
+++ b/src/arch/x86/operand.h
@@ -41,10 +41,10 @@
#define G_X86_OPERAND_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE((inst), g_x86_operand_get_type(), GX86OperandIface))
-/* Définition d'un opérande de la x86 (instance) */
+/* Définition d'un opérande de x86 (instance) */
typedef struct _GX86Operand GX86Operand;
-/* Définition d'un opérande de la x86 (classe) */
+/* Définition d'un opérande de x86 (classe) */
typedef struct _GX86OperandClass GX86OperandClass;
@@ -72,13 +72,13 @@ typedef struct _GX86RegisterOperandClass GX86RegisterOperandClass;
/* Indique le type défini par la GLib pour un opérande de registre x86. */
GType g_x86_register_operand_get_type(void);
-/* Crée un opérande visant un registre X86. */
+/* Crée un opérande visant un registre x86. */
GArchOperand *g_x86_register_operand_new_from_opcode(const bin_t *, off_t *, off_t, AsmOperandSize, bin_t);
-/* Crée un opérande visant un registre X86. */
+/* Crée un opérande visant un registre x86. */
GArchOperand *g_x86_register_operand_new_from_mod_rm(const bin_t *, off_t *, off_t, AsmOperandSize, bool);
-/* Crée un opérande visant un registre X86 donnée. */
+/* Crée un opérande visant un registre x86 donné. */
GArchOperand *g_x86_register_operand_new_from_index(bin_t, AsmOperandSize);
diff --git a/src/arch/x86/registers.c b/src/arch/x86/registers.c
new file mode 100644
index 0000000..802e2f6
--- /dev/null
+++ b/src/arch/x86/registers.c
@@ -0,0 +1,530 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * registers.c - aides auxiliaires relatives aux registres x86
+ *
+ * Copyright (C) 2009 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 "registers.h"
+
+
+#include <malloc.h>
+#include <stdio.h>
+
+
+
+/* Liste des registres 8 bits */
+typedef enum _X868bRegister
+{
+ X86_REG8_AL = 0, /* Registre AL */
+ X86_REG8_CL = 1, /* Registre AL */
+ X86_REG8_DL = 2, /* Registre AL */
+ X86_REG8_BL = 3, /* Registre AL */
+ X86_REG8_AH = 4, /* Registre AH */
+ X86_REG8_CH = 5, /* Registre AH */
+ X86_REG8_DH = 6, /* Registre AH */
+ X86_REG8_BH = 7, /* Registre AH */
+
+ X86_REG8_NONE /* Aucun registre */
+
+} X868bRegister;
+
+/* Liste des registres 16 bits */
+typedef enum _X8616bRegister
+{
+ X86_REG16_AX = 0, /* Registre AX */
+ X86_REG16_CX = 1, /* Registre AX */
+ X86_REG16_DX = 2, /* Registre AX */
+ X86_REG16_BX = 3, /* Registre AX */
+ X86_REG16_SP = 4, /* Registre SP */
+ X86_REG16_BP = 5, /* Registre BP */
+ X86_REG16_SI = 6, /* Registre SI */
+ X86_REG16_DI = 7, /* Registre DI */
+
+ X86_REG16_NONE /* Aucun registre */
+
+} X8616bRegister;
+
+/* Liste des registres 32 bits */
+typedef enum _X8632bRegister
+{
+ X86_REG32_EAX = 0, /* Registre EAX */
+ X86_REG32_ECX = 1, /* Registre EAX */
+ X86_REG32_EDX = 2, /* Registre EAX */
+ X86_REG32_EBX = 3, /* Registre EAX */
+ X86_REG32_ESP = 4, /* Registre ESP */
+ X86_REG32_EBP = 5, /* Registre EBP */
+ X86_REG32_ESI = 6, /* Registre ESI */
+ X86_REG32_EDI = 7, /* Registre EDI */
+
+ X86_REG32_NONE /* Aucun registre */
+
+} X8632bRegister;
+
+
+/* Registre x86 */
+struct _x86_register
+{
+ union
+ {
+ X868bRegister reg8; /* Registre 8 bits */
+ X8616bRegister reg16; /* Registre 16 bits */
+ X8632bRegister reg32; /* Registre 32 bits */
+
+ } reg;
+
+ AsmOperandSize size; /* Taille de ce registre */
+
+};
+
+
+
+/******************************************************************************
+* *
+* Paramètres : size = indique la taille du registre. *
+* value = valeur correspondant au registre. *
+* *
+* Description : Récupère l'indentifiant interne d'un registre. *
+* *
+* Retour : Registre définit ou NULL. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+x86_register *get_x86_register(AsmOperandSize size, bin_t value)
+{
+ x86_register *result; /* Représentation à renvoyer */
+
+ result = (x86_register *)calloc(1, sizeof(x86_register));
+
+ result->size = size;
+
+ switch (size)
+ {
+ case AOS_8_BITS:
+ switch (value)
+ {
+ case 0 ... 7:
+ result->reg.reg8 = (X868bRegister)value;
+ break;
+ default:
+ goto gxr_error;
+ break;
+ }
+ break;
+
+ case AOS_16_BITS:
+ switch (value)
+ {
+ case 0 ... 7:
+ result->reg.reg16 = (X8616bRegister)value;
+ break;
+ default:
+ goto gxr_error;
+ break;
+ }
+ break;
+
+ case AOS_32_BITS:
+ switch (value)
+ {
+ case 0 ... 7:
+ result->reg.reg32 = (X8632bRegister)value;
+ break;
+ default:
+ goto gxr_error;
+ break;
+ }
+ break;
+
+ default:
+ goto gxr_error;
+ break;
+
+ }
+
+ return result;
+
+ gxr_error:
+
+ free(result);
+
+ return NULL;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : reg = registre à supprimer. *
+* *
+* Description : Efface de la mémoire l'indentifiant interne d'un registre. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void free_x86_register(x86_register *reg)
+{
+ free(reg);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : reg = registre à consulter. *
+* *
+* Description : Indique si le registre correspond à ebp ou similaire. *
+* *
+* Retour : true si la correspondance est avérée, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool is_x86_register_base_pointer(const x86_register *reg)
+{
+ bool result; /* Bilan à remonter */
+
+ switch (reg->size)
+ {
+ case AOS_8_BITS_UNSIGNED:
+ case AOS_8_BITS_SIGNED:
+ result = (reg->reg.reg8 == X86_REG8_CH);
+ break;
+ case AOS_16_BITS_UNSIGNED:
+ case AOS_16_BITS_SIGNED:
+ result = (reg->reg.reg16 == X86_REG16_BP);
+ break;
+ case AOS_32_BITS_UNSIGNED:
+ case AOS_32_BITS_SIGNED:
+ result = (reg->reg.reg32 == X86_REG32_EBP);
+ break;
+ /*
+ case AOS_64_BITS_UNSIGNED:
+ case AOS_64_BITS_SIGNED:
+ result = (reg->reg.reg8 == X86_REG8_CH);
+ break;
+ */
+ default:
+ result = false;
+
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : reg = registre à consulter. *
+* *
+* Description : Indique si le registre correspond à esp ou similaire. *
+* *
+* Retour : true si la correspondance est avérée, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool is_x86_register_stack_pointer(const x86_register *reg)
+{
+ bool result; /* Bilan à remonter */
+
+ switch (reg->size)
+ {
+ case AOS_8_BITS_UNSIGNED:
+ case AOS_8_BITS_SIGNED:
+ result = (reg->reg.reg8 == X86_REG8_AH);
+ break;
+ case AOS_16_BITS_UNSIGNED:
+ case AOS_16_BITS_SIGNED:
+ result = (reg->reg.reg16 == X86_REG16_SP);
+ break;
+ case AOS_32_BITS_UNSIGNED:
+ case AOS_32_BITS_SIGNED:
+ result = (reg->reg.reg32 == X86_REG32_ESP);
+ break;
+ /*
+ case AOS_64_BITS_UNSIGNED:
+ case AOS_64_BITS_SIGNED:
+ result = (reg->reg.reg8 == X86_REG8_CH);
+ break;
+ */
+ default:
+ result = false;
+
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : reg = registre à imprimer. *
+* syntax = type de représentation demandée. *
+* *
+* Description : Traduit un registre x86 en texte. *
+* *
+* Retour : Traduction en chaîne à libérer de la mémoire. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+char *x86_register_as_text(const x86_register *reg, AsmSyntax syntax)
+{
+ char *result; /* Chaîne à renvoyer */
+
+ result = (char *)calloc(5, sizeof(char));
+
+ switch (syntax)
+ {
+ case ASX_INTEL:
+ switch (reg->size)
+ {
+ case AOS_8_BITS:
+ switch (reg->reg.reg8)
+ {
+ case X86_REG8_AL:
+ snprintf(result, 5, "al");
+ break;
+ case X86_REG8_CL:
+ snprintf(result, 5, "cl");
+ break;
+ case X86_REG8_DL:
+ snprintf(result, 5, "dl");
+ break;
+ case X86_REG8_BL:
+ snprintf(result, 5, "bl");
+ break;
+ case X86_REG8_AH:
+ snprintf(result, 5, "ah");
+ break;
+ case X86_REG8_CH:
+ snprintf(result, 5, "ch");
+ break;
+ case X86_REG8_DH:
+ snprintf(result, 5, "dh");
+ break;
+ case X86_REG8_BH:
+ snprintf(result, 5, "bh");
+ break;
+ case X86_REG8_NONE:
+ /* Ne devrait jamais arriver */
+ break;
+ }
+ break;
+
+ case AOS_16_BITS:
+ switch (reg->reg.reg16)
+ {
+ case X86_REG16_AX:
+ snprintf(result, 5, "ax");
+ break;
+ case X86_REG16_CX:
+ snprintf(result, 5, "cx");
+ break;
+ case X86_REG16_DX:
+ snprintf(result, 5, "dx");
+ break;
+ case X86_REG16_BX:
+ snprintf(result, 5, "bx");
+ break;
+ case X86_REG16_SP:
+ snprintf(result, 5, "sp");
+ break;
+ case X86_REG16_BP:
+ snprintf(result, 5, "bp");
+ break;
+ case X86_REG16_SI:
+ snprintf(result, 5, "si");
+ break;
+ case X86_REG16_DI:
+ snprintf(result, 5, "di");
+ break;
+ case X86_REG16_NONE:
+ /* Ne devrait jamais arriver */
+ break;
+ }
+ break;
+
+ case AOS_32_BITS:
+ switch (reg->reg.reg32)
+ {
+ case X86_REG32_EAX:
+ snprintf(result, 5, "eax");
+ break;
+ case X86_REG32_ECX:
+ snprintf(result, 5, "ecx");
+ break;
+ case X86_REG32_EDX:
+ snprintf(result, 5, "edx");
+ break;
+ case X86_REG32_EBX:
+ snprintf(result, 5, "ebx");
+ break;
+ case X86_REG32_ESP:
+ snprintf(result, 5, "esp");
+ break;
+ case X86_REG32_EBP:
+ snprintf(result, 5, "ebp");
+ break;
+ case X86_REG32_ESI:
+ snprintf(result, 5, "esi");
+ break;
+ case X86_REG32_EDI:
+ snprintf(result, 5, "edi");
+ break;
+ case X86_REG32_NONE:
+ printf("null reg\n");
+ /* Ne devrait jamais arriver */
+ break;
+ }
+ break;
+
+ default:
+ break;
+
+ }
+ break;
+
+ case ASX_ATT:
+ switch (reg->size)
+ {
+ case AOS_8_BITS:
+ switch (reg->reg.reg8)
+ {
+ case X86_REG8_AL:
+ snprintf(result, 5, "%%al");
+ break;
+ case X86_REG8_CL:
+ snprintf(result, 5, "%%cl");
+ break;
+ case X86_REG8_DL:
+ snprintf(result, 5, "%%dl");
+ break;
+ case X86_REG8_BL:
+ snprintf(result, 5, "%%bl");
+ break;
+ case X86_REG8_AH:
+ snprintf(result, 5, "%%ah");
+ break;
+ case X86_REG8_CH:
+ snprintf(result, 5, "%%ch");
+ break;
+ case X86_REG8_DH:
+ snprintf(result, 5, "%%dh");
+ break;
+ case X86_REG8_BH:
+ snprintf(result, 5, "%%bh");
+ break;
+ case X86_REG8_NONE:
+ /* Ne devrait jamais arriver */
+ break;
+ }
+ break;
+
+ case AOS_16_BITS:
+ switch (reg->reg.reg16)
+ {
+ case X86_REG16_AX:
+ snprintf(result, 5, "%%ax");
+ break;
+ case X86_REG16_CX:
+ snprintf(result, 5, "%%cx");
+ break;
+ case X86_REG16_DX:
+ snprintf(result, 5, "%%dx");
+ break;
+ case X86_REG16_BX:
+ snprintf(result, 5, "%%bx");
+ break;
+ case X86_REG16_SP:
+ snprintf(result, 5, "%%sp");
+ break;
+ case X86_REG16_BP:
+ snprintf(result, 5, "%%bp");
+ break;
+ case X86_REG16_SI:
+ snprintf(result, 5, "%%si");
+ break;
+ case X86_REG16_DI:
+ snprintf(result, 5, "%%di");
+ break;
+ case X86_REG16_NONE:
+ /* Ne devrait jamais arriver */
+ break;
+ }
+ break;
+
+ case AOS_32_BITS:
+ switch (reg->reg.reg32)
+ {
+ case X86_REG32_EAX:
+ snprintf(result, 5, "%%eax");
+ break;
+ case X86_REG32_ECX:
+ snprintf(result, 5, "%%ecx");
+ break;
+ case X86_REG32_EDX:
+ snprintf(result, 5, "%%edx");
+ break;
+ case X86_REG32_EBX:
+ snprintf(result, 5, "%%ebx");
+ break;
+ case X86_REG32_ESP:
+ snprintf(result, 5, "%%esp");
+ break;
+ case X86_REG32_EBP:
+ snprintf(result, 5, "%%ebp");
+ break;
+ case X86_REG32_ESI:
+ snprintf(result, 5, "%%esi");
+ break;
+ case X86_REG32_EDI:
+ snprintf(result, 5, "%%edi");
+ break;
+ case X86_REG32_NONE:
+ /* Ne devrait jamais arriver */
+ break;
+ }
+ break;
+
+ default:
+ break;
+
+ }
+ break;
+
+ default:
+ break;
+
+ }
+
+ return result;
+
+}
diff --git a/src/arch/x86/registers.h b/src/arch/x86/registers.h
new file mode 100644
index 0000000..491d5bc
--- /dev/null
+++ b/src/arch/x86/registers.h
@@ -0,0 +1,54 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * registers.h - prototypes pour les aides auxiliaires relatives aux registres x86
+ *
+ * Copyright (C) 2009 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 _ARCH_X86_REGISTERS_H
+#define _ARCH_X86_REGISTERS_H
+
+
+#include "../archbase.h"
+#include "../operand.h"
+
+
+
+/* Registre x86 */
+typedef struct _x86_register x86_register;
+
+
+/* Récupère l'indentifiant interne d'un registre. */
+x86_register *get_x86_register(AsmOperandSize, bin_t);
+
+/* Efface de la mémoire l'indentifiant interne d'un registre. */
+void free_x86_register(x86_register *);
+
+/* Indique si le registre correspond à ebp ou similaire. */
+bool is_x86_register_base_pointer(const x86_register *);
+
+/* Indique si le registre correspond à esp ou similaire. */
+bool is_x86_register_stack_pointer(const x86_register *);
+
+/* Traduit un registre x86 en texte. */
+char *x86_register_as_text(const x86_register *, AsmSyntax);
+
+
+
+#endif /* _ARCH_X86_REGISTERS_H */
diff --git a/src/format/elf/e_elf.c b/src/format/elf/e_elf.c
index dac0cd7..b5e3406 100644
--- a/src/format/elf/e_elf.c
+++ b/src/format/elf/e_elf.c
@@ -242,7 +242,25 @@ elf_format *load_elf(const uint8_t *content, off_t length)
FormatTargetMachine get_elf_target_machine(const elf_format *format)
{
- return FTM_386;
+ FormatTargetMachine result; /* Identifiant à retourner */
+
+ switch (format->header.e_machine)
+ {
+ case EM_MIPS:
+ result = FTM_MIPS;
+ break;
+
+ case EM_386:
+ result = FTM_386;
+ break;
+
+ default:
+ /* FIXME */
+ break;
+
+ }
+
+ return result;
}
diff --git a/src/format/exe_format.c b/src/format/exe_format.c
index aeeaea3..5ddb934 100644
--- a/src/format/exe_format.c
+++ b/src/format/exe_format.c
@@ -360,7 +360,25 @@ const uint8_t *get_exe_content(const exe_format *format, off_t *length)
FormatTargetMachine get_exe_target_machine(const exe_format *format)
{
- return format->get_target_machine(format);
+ FormatTargetMachine result; /* Type à retourner */
+
+ result = format->get_target_machine(format);
+
+ switch (result)
+ {
+ case FTM_JVM:
+ log_simple_message(LMT_INFO, _("Detected architecture: Java Virtual Machine"));
+ break;
+ case FTM_MIPS:
+ log_simple_message(LMT_INFO, _("Detected architecture: Microprocessor without Interlocked Pipeline Stages"));
+ break;
+ case FTM_386:
+ log_simple_message(LMT_INFO, _("Detected architecture: X386"));
+ break;
+
+ }
+
+ return result;
}
diff --git a/src/format/exe_format.h b/src/format/exe_format.h
index 2c10d65..de9f025 100644
--- a/src/format/exe_format.h
+++ b/src/format/exe_format.h
@@ -92,8 +92,9 @@ exe_format *load_new_exe_format(const uint8_t *, off_t);
/* Architectures de destination des formats */
typedef enum _FormatTargetMachine
{
- FTM_386, /* Intel 80386 */
FTM_JVM, /* Java Virtual Machine */
+ FTM_MIPS, /* Mips 32 ou 64 bits */
+ FTM_386, /* Intel 80386 */
FTM_COUNT