diff options
Diffstat (limited to 'src/arch/operand.c')
-rw-r--r-- | src/arch/operand.c | 132 |
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. * |