summaryrefslogtreecommitdiff
path: root/src/arch/operand.c
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2008-07-31 21:46:47 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2008-07-31 21:46:47 (GMT)
commit3786e818fdf8731dd6f310f0aaac75d431646160 (patch)
treea1dc1d1ed27c56d7ae2e361102fef7310a9b1a21 /src/arch/operand.c
parent57758c2cd11938e3e4c6e45b983cee4c2269ff44 (diff)
Handled the virtual offset and fixed the operand-size overriding.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@11 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'src/arch/operand.c')
-rw-r--r--src/arch/operand.c79
1 files changed, 79 insertions, 0 deletions
diff --git a/src/arch/operand.c b/src/arch/operand.c
index 33807bc..e24a3e0 100644
--- a/src/arch/operand.c
+++ b/src/arch/operand.c
@@ -156,6 +156,85 @@ 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. *
+* data = flux de données à analyser. *
+* pos = position courante dans ce flux. [OUT] *
+* len = taille totale des données à analyser. *
+* ref = adresse de référence. *
+* *
+* Description : Crée une opérande contenant une valeur relative sur x bits. *
+* *
+* Retour : true si l'opération s'est effectuée avec succès, false sinon.*
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool fill_relimm_operand(asm_operand *operand, AsmOperandSize size, const uint8_t *data, off_t *pos, off_t len, uint64_t ref)
+{
+ bool result; /* Bilan à retourner */
+ off_t old_pos; /* Sauvegarde de l'évolution */
+ int8_t val8; /* Valeur sur 8 bits */
+ int16_t val16; /* Valeur sur 16 bits */
+ uint32_t val32; /* Valeur sur 32 bits */
+ int64_t val64; /* Valeur sur 64 bits */
+
+ old_pos = *pos;
+ result = fill_imm_operand(operand, size, data, pos, len);
+
+ if (result)
+ switch (size)
+ {
+ case AOS_8_BITS:
+ if (operand->value.val8 & 0x80)
+ {
+ val8 = operand->value.val8 - 1;
+ val8 = ~val8;
+ operand->value.val8 = ref + (*pos - old_pos);
+ operand->value.val8 -= val8;
+ }
+ else operand->value.val8 += ref + (*pos - old_pos);
+ break;
+ case AOS_16_BITS:
+ if (operand->value.val16 & 0x8000)
+ {
+ val16 = operand->value.val16 - 1;
+ val16 = ~val16;
+ operand->value.val16 = ref + (*pos - old_pos);
+ operand->value.val16 -= val16;
+ }
+ else operand->value.val16 += ref + (*pos - old_pos);
+ break;
+ case AOS_32_BITS:
+ if (operand->value.val32 & 0x80000000)
+ {
+ val32 = operand->value.val32 - 1;
+ val32 = ~val32;
+ operand->value.val32 = ref + (*pos - old_pos);
+ operand->value.val32 -= val32;
+ }
+ else operand->value.val32 += ref + (*pos - old_pos);
+ break;
+ case AOS_64_BITS:
+ if (operand->value.val64 & 0x8000000000000000ull)
+ {
+ val64 = operand->value.val64 - 1;
+ val64 = ~val64;
+ operand->value.val64 = ref + (*pos - old_pos);
+ operand->value.val64 -= val64;
+ }
+ else operand->value.val64 += ref + (*pos - old_pos);
+ break;
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : operand = instruction à traiter. *
* buffer = tampon de sortie mis à disposition. [OUT] *
* len = taille de ce tampon. *