diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2009-05-31 20:58:20 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2009-05-31 20:58:20 (GMT) |
commit | 8724afdc73e0ddad86f46de1a3fbe0254575a76e (patch) | |
tree | de666b66e154c6c6453807d3fa4272efb6877a91 /src/arch/mips | |
parent | 0b7d7f26c745ff0f52e9e483a0980351368ca824 (diff) |
Supported a new architecture (MIPS).
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@67 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'src/arch/mips')
-rw-r--r-- | src/arch/mips/Makefile.am | 30 | ||||
-rw-r--r-- | src/arch/mips/instruction.c | 285 | ||||
-rw-r--r-- | src/arch/mips/instruction.h | 105 | ||||
-rw-r--r-- | src/arch/mips/op_add.c | 95 | ||||
-rw-r--r-- | src/arch/mips/op_and.c | 62 | ||||
-rw-r--r-- | src/arch/mips/op_branch.c | 161 | ||||
-rw-r--r-- | src/arch/mips/op_jump.c | 114 | ||||
-rw-r--r-- | src/arch/mips/op_load.c | 128 | ||||
-rw-r--r-- | src/arch/mips/op_nop.c | 58 | ||||
-rw-r--r-- | src/arch/mips/op_sr.c | 62 | ||||
-rw-r--r-- | src/arch/mips/op_store.c | 95 | ||||
-rw-r--r-- | src/arch/mips/op_sub.c | 95 | ||||
-rw-r--r-- | src/arch/mips/opcodes.h | 107 | ||||
-rw-r--r-- | src/arch/mips/operand.c | 649 | ||||
-rw-r--r-- | src/arch/mips/operand.h | 156 | ||||
-rw-r--r-- | src/arch/mips/processor.c | 253 | ||||
-rw-r--r-- | src/arch/mips/processor.h | 53 | ||||
-rw-r--r-- | src/arch/mips/registers.c | 249 | ||||
-rw-r--r-- | src/arch/mips/registers.h | 51 |
19 files changed, 2808 insertions, 0 deletions
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 */ |