summaryrefslogtreecommitdiff
path: root/src/arch/operand.c
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2008-09-14 20:54:43 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2008-09-14 20:54:43 (GMT)
commit06cf576b280cbabb73a956161693a63ee846f57b (patch)
tree3ac4b32e869cc8aaa1d4b7429d7d4a12f9a8ae7f /src/arch/operand.c
parentab1489b6a6ef1f09957f6f805f143fceb42f6a08 (diff)
Made the program able to disassemble a simple binary completely.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@30 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'src/arch/operand.c')
-rw-r--r--src/arch/operand.c132
1 files changed, 132 insertions, 0 deletions
diff --git a/src/arch/operand.c b/src/arch/operand.c
index e24a3e0..53e652c 100644
--- a/src/arch/operand.c
+++ b/src/arch/operand.c
@@ -24,6 +24,7 @@
#include "operand.h"
+#include <stdarg.h>
#include <stdio.h>
@@ -90,6 +91,83 @@ void print_db_operand(const asm_operand *operand, char *buffer, size_t len, AsmS
/******************************************************************************
* *
+* Paramètres : size = taille de l'opérande souhaitée. *
+* data = flux de données à analyser. *
+* pos = position courante dans ce flux. [OUT] *
+* len = taille totale des données à analyser. *
+* ... = adresse où placer la valeur lue. [OUT] *
+* *
+* Description : Lit une valeur (signée ou non) sur x bits. *
+* *
+* Retour : true si l'opération s'est effectuée avec succès, false sinon.*
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool read_imm_value(AsmOperandSize size, const uint8_t *data, off_t *pos, off_t len, ...)
+{
+ va_list ap; /* Récupération d'argument */
+ uint8_t *val8; /* Valeur sur 8 bits */
+ uint16_t *val16; /* Valeur sur 16 bits */
+ uint32_t *val32; /* Valeur sur 32 bits */
+ uint64_t *val64; /* Valeur sur 64 bits */
+
+ /* Vérifications sanitaires */
+ switch (size)
+ {
+ case AOS_8_BITS:
+ if ((len - *pos) < 1) return false;
+ break;
+ case AOS_16_BITS:
+ if ((len - *pos) < 2) return false;
+ break;
+ case AOS_32_BITS:
+ if ((len - *pos) < 4) return false;
+ break;
+ case AOS_64_BITS:
+ if ((len - *pos) < 8) return false;
+ break;
+ }
+
+ va_start(ap, len);
+
+ switch (size)
+ {
+ case AOS_8_BITS:
+ val8 = va_arg(ap, uint8_t *);
+ *val8 = data[*pos];
+ *pos += 1;
+ break;
+ case AOS_16_BITS:
+ val16 = va_arg(ap, uint16_t *);
+ *val16 = data[*pos] | (uint16_t)data[*pos + 1] << 8;
+ *pos += 2;
+ break;
+ case AOS_32_BITS:
+ val32 = va_arg(ap, uint32_t *);
+ *val32 = data[*pos] | (uint32_t)data[*pos + 1] << 8
+ | (uint32_t)data[*pos + 2] << 16 | (uint32_t)data[*pos + 3] << 24;
+ *pos += 4;
+ break;
+ case AOS_64_BITS:
+ val64 = va_arg(ap, uint64_t *);
+ *val64 = data[*pos] | (uint64_t)data[*pos + 1] << 8 | (uint64_t)data[*pos + 2] << 16
+ | (uint64_t)data[*pos + 3] << 24 | (uint64_t)data[*pos + 4] << 32 | (uint64_t)data[*pos + 5] << 40
+ | (uint64_t)data[*pos + 6] << 48 | (uint64_t)data[*pos + 7] << 56;
+ *pos += 8;
+ break;
+ }
+
+ va_end(ap);
+
+ return true;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : operand = structure dont le contenu est à définir. *
* size = taille de l'opérande souhaitée. *
* data = flux de données à analyser. *
@@ -158,6 +236,60 @@ bool fill_imm_operand(asm_operand *operand, AsmOperandSize size, const uint8_t *
* *
* Paramètres : operand = structure dont le contenu est à définir. *
* size = taille de l'opérande souhaitée. *
+* ... = valeur à utiliser. *
+* *
+* Description : Crée une opérande contenant une valeur sur x bits. *
+* *
+* Retour : true si l'opération s'est effectuée avec succès, false sinon.*
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool fill_imm_operand_with_value(asm_operand *operand, AsmOperandSize size, ...)
+{
+ va_list ap; /* Récupération d'argument */
+ const uint8_t *val8; /* Valeur sur 8 bits */
+ const uint16_t *val16; /* Valeur sur 16 bits */
+ const uint32_t *val32; /* Valeur sur 32 bits */
+ const uint64_t *val64; /* Valeur sur 64 bits */
+
+ operand->type = AOT_IMM;
+ operand->size = size;
+
+ va_start(ap, size);
+
+ switch (size)
+ {
+ case AOS_8_BITS:
+ val8 = va_arg(ap, const uint8_t *);
+ operand->value.val8 = *val8;
+ break;
+ case AOS_16_BITS:
+ val16 = va_arg(ap, const uint16_t *);
+ operand->value.val16 = *val16;
+ break;
+ case AOS_32_BITS:
+ val32 = va_arg(ap, const uint32_t *);
+ operand->value.val32 = *val32;
+ break;
+ case AOS_64_BITS:
+ val64 = va_arg(ap, const uint64_t *);
+ operand->value.val64 = *val64;
+ break;
+ }
+
+ va_end(ap);
+
+ return true;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : operand = structure dont le contenu est à définir. *
+* size = taille de l'opérande souhaitée. *
* data = flux de données à analyser. *
* pos = position courante dans ce flux. [OUT] *
* len = taille totale des données à analyser. *