diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2008-07-31 21:46:47 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2008-07-31 21:46:47 (GMT) |
commit | 3786e818fdf8731dd6f310f0aaac75d431646160 (patch) | |
tree | a1dc1d1ed27c56d7ae2e361102fef7310a9b1a21 /src/arch/operand.c | |
parent | 57758c2cd11938e3e4c6e45b983cee4c2269ff44 (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.c | 79 |
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. * |