diff options
Diffstat (limited to 'src/arch/operand.c')
-rw-r--r-- | src/arch/operand.c | 798 |
1 files changed, 0 insertions, 798 deletions
diff --git a/src/arch/operand.c b/src/arch/operand.c index 9d6fa28..0f488b3 100644 --- a/src/arch/operand.c +++ b/src/arch/operand.c @@ -24,808 +24,10 @@ #include "operand.h" -#include <stdarg.h> -#include <stdio.h> - - #include "operand-int.h" -/****************************************************************************** -* * -* Paramètres : operand = structure dont le contenu est à définir. * -* value = valeur immédiate à renseigner. * -* * -* Description : Crée une opérande pour l'instruction 'db'. * -* * -* Retour : true si l'opérande a été définie avec succès, false sinon. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool fill_db_operand(asm_operand *operand, uint8_t value) -{ - operand->type = AOT_NONE; - operand->size = AOS_8_BITS_UNSIGNED; - - operand->unsigned_imm.val8 = value; - - return true; - -} - - -/****************************************************************************** -* * -* Paramètres : operand = instruction à traiter. * -* buffer = tampon de sortie mis à disposition. [OUT] * -* len = taille de ce tampon. * -* syntax = type de représentation demandée. * -* * -* Description : Traduit une opérande de type 'db' en texte. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void print_db_operand(const asm_operand *operand, char *buffer, size_t len, AsmSyntax syntax) -{ - switch (syntax) - { - case ASX_INTEL: - snprintf(buffer, len, "0x%02hhx", operand->unsigned_imm.val8); - break; - - case ASX_ATT: - snprintf(buffer, len, "$0x%02hhx", operand->unsigned_imm.val8); - break; - - } - -} - - -/****************************************************************************** -* * -* 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_UNSIGNED: - case AOS_8_BITS_SIGNED: - if ((len - *pos) < 1) return false; - break; - case AOS_16_BITS_UNSIGNED: - case AOS_16_BITS_SIGNED: - if ((len - *pos) < 2) return false; - break; - case AOS_32_BITS_UNSIGNED: - case AOS_32_BITS_SIGNED: - if ((len - *pos) < 4) return false; - break; - case AOS_64_BITS_UNSIGNED: - case AOS_64_BITS_SIGNED: - if ((len - *pos) < 8) return false; - break; - } - - va_start(ap, len); - - switch (size) - { - case AOS_8_BITS_UNSIGNED: - case AOS_8_BITS_SIGNED: - val8 = va_arg(ap, uint8_t *); - *val8 = data[*pos]; - *pos += 1; - break; - case AOS_16_BITS_UNSIGNED: - case AOS_16_BITS_SIGNED: - val16 = va_arg(ap, uint16_t *); - *val16 = data[*pos] | (uint16_t)data[*pos + 1] << 8; - *pos += 2; - break; - case AOS_32_BITS_UNSIGNED: - case AOS_32_BITS_SIGNED: - 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_UNSIGNED: - case AOS_64_BITS_SIGNED: - 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. * -* * -* Description : Indique le signe d'une valeur immédiate. * -* * -* Retour : true si la valeur est strictement négative, false sinon. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool is_imm_operand_negative(const asm_operand *operand) -{ - bool result; /* Bilan à renvoyer */ - - result = false; - - switch (operand->size) - { - case AOS_8_BITS_SIGNED: - result = (operand->signed_imm.val8 & 0x80); - break; - case AOS_16_BITS_SIGNED: - result = (operand->signed_imm.val16 & 0x8000); - break; - case AOS_32_BITS_SIGNED: - result = (operand->signed_imm.val32 & 0x80000000); - break; - case AOS_64_BITS_SIGNED: - result = (operand->signed_imm.val64 & 0x8000000000000000ll); - break; - default: - /* Traitement non nécessaire */ - break; - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : operand = structure dont le contenu est à définir. * -* size = taille de l'opérande souhaitée. * -* * -* Description : Précalcule une valeur humaine lisible d'une valeur signée. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void cache_signed_imm_value(asm_operand *operand, AsmOperandSize size) -{ - int8_t val8; /* Valeur sur 8 bits */ - int16_t val16; /* Valeur sur 16 bits */ - int32_t val32; /* Valeur sur 32 bits */ - int64_t val64; /* Valeur sur 64 bits */ - - switch (size) - { - case AOS_8_BITS_SIGNED: - if (operand->signed_imm.val8 & 0x80) - { - val8 = operand->signed_imm.val8 - 1; - val8 = ~val8; - operand->unsigned_imm.val8 = val8; - } - else operand->unsigned_imm.val8 = operand->signed_imm.val8; - break; - case AOS_16_BITS_SIGNED: - if (operand->signed_imm.val16 & 0x8000) - { - val16 = operand->signed_imm.val16 - 1; - val16 = ~val16; - operand->unsigned_imm.val16 = val16; - } - else operand->unsigned_imm.val16 = operand->signed_imm.val16; - break; - case AOS_32_BITS_SIGNED: - if (operand->signed_imm.val32 & 0x80000000) - { - val32 = operand->signed_imm.val32 - 1; - val32 = ~val32; - operand->unsigned_imm.val32 = val32; - } - else operand->unsigned_imm.val32 = operand->signed_imm.val32; - break; - case AOS_64_BITS_SIGNED: - if (operand->signed_imm.val64 & 0x8000000000000000ll) - { - val64 = operand->signed_imm.val64 - 1; - val64 = ~val64; - operand->unsigned_imm.val64 = val64; - } - else operand->unsigned_imm.val64 = operand->signed_imm.val64; - break; - default: - /* Traitement non nécessaire */ - break; - } - -} - - -/****************************************************************************** -* * -* 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. * -* * -* 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(asm_operand *operand, AsmOperandSize size, const uint8_t *data, off_t *pos, off_t len) -{ - bool result; /* Bilan à retourner */ - - operand->type = AOT_IMM; - operand->size = size; - - switch (size) - { - case AOS_8_BITS_UNSIGNED: - result = read_imm_value(size, data, pos, len, &operand->unsigned_imm.val8); - break; - case AOS_16_BITS_UNSIGNED: - result = read_imm_value(size, data, pos, len, &operand->unsigned_imm.val16); - break; - case AOS_32_BITS_UNSIGNED: - result = read_imm_value(size, data, pos, len, &operand->unsigned_imm.val32); - break; - case AOS_64_BITS_UNSIGNED: - result = read_imm_value(size, data, pos, len, &operand->unsigned_imm.val64); - break; - case AOS_8_BITS_SIGNED: - result = read_imm_value(size, data, pos, len, &operand->signed_imm.val8); - cache_signed_imm_value(operand, size); - break; - case AOS_16_BITS_SIGNED: - result = read_imm_value(size, data, pos, len, &operand->signed_imm.val16); - cache_signed_imm_value(operand, size); - break; - case AOS_32_BITS_SIGNED: - result = read_imm_value(size, data, pos, len, &operand->signed_imm.val32); - cache_signed_imm_value(operand, size); - break; - case AOS_64_BITS_SIGNED: - result = read_imm_value(size, data, pos, len, &operand->signed_imm.val64); - cache_signed_imm_value(operand, size); - break; - } - - return result; - -} - - -/****************************************************************************** -* * -* 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 *us_val8; /* Valeur sur 8 bits n.-s. */ - const uint16_t *us_val16; /* Valeur sur 16 bits n.-s. */ - const uint32_t *us_val32; /* Valeur sur 32 bits n.-s. */ - const uint64_t *us_val64; /* Valeur sur 64 bits n.-s. */ - const int8_t *s_val8; /* Valeur sur 8 bits signés */ - const int16_t *s_val16; /* Valeur sur 16 bits signés */ - const int32_t *s_val32; /* Valeur sur 32 bits signés */ - const int64_t *s_val64; /* Valeur sur 64 bits signés */ - - operand->type = AOT_IMM; - operand->size = size; - - va_start(ap, size); - - switch (size) - { - case AOS_8_BITS_UNSIGNED: - us_val8 = va_arg(ap, const uint8_t *); - operand->unsigned_imm.val8 = *us_val8; - break; - case AOS_16_BITS_UNSIGNED: - us_val16 = va_arg(ap, const uint16_t *); - operand->unsigned_imm.val16 = *us_val16; - break; - case AOS_32_BITS_UNSIGNED: - us_val32 = va_arg(ap, const uint32_t *); - operand->unsigned_imm.val32 = *us_val32; - break; - case AOS_64_BITS_UNSIGNED: - us_val64 = va_arg(ap, const uint64_t *); - operand->unsigned_imm.val64 = *us_val64; - break; - case AOS_8_BITS_SIGNED: - s_val8 = va_arg(ap, const uint8_t *); - operand->signed_imm.val8 = *s_val8; - cache_signed_imm_value(operand, size); - break; - case AOS_16_BITS_SIGNED: - s_val16 = va_arg(ap, const uint16_t *); - operand->signed_imm.val16 = *s_val16; - cache_signed_imm_value(operand, size); - break; - case AOS_32_BITS_SIGNED: - s_val32 = va_arg(ap, const uint32_t *); - operand->signed_imm.val32 = *s_val32; - cache_signed_imm_value(operand, size); - break; - case AOS_64_BITS_SIGNED: - s_val64 = va_arg(ap, const uint64_t *); - operand->signed_imm.val64 = *s_val64; - cache_signed_imm_value(operand, size); - 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. * -* 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->unsigned_imm.val8 & 0x80) - { - val8 = operand->unsigned_imm.val8 - 1; - val8 = ~val8; - operand->unsigned_imm.val8 = ref + (*pos - old_pos); - operand->unsigned_imm.val8 -= val8; - } - else operand->unsigned_imm.val8 += ref + (*pos - old_pos); - break; - case AOS_16_BITS: - if (operand->unsigned_imm.val16 & 0x8000) - { - val16 = operand->unsigned_imm.val16 - 1; - val16 = ~val16; - operand->unsigned_imm.val16 = ref + (*pos - old_pos); - operand->unsigned_imm.val16 -= val16; - } - else operand->unsigned_imm.val16 += ref + (*pos - old_pos); - break; - case AOS_32_BITS: - if (operand->unsigned_imm.val32 & 0x80000000) - { - val32 = operand->unsigned_imm.val32 - 1; - val32 = ~val32; - operand->unsigned_imm.val32 = ref + (*pos - old_pos); - operand->unsigned_imm.val32 -= val32; - } - else operand->unsigned_imm.val32 += ref + (*pos - old_pos); - break; - case AOS_64_BITS: - if (operand->unsigned_imm.val64 & 0x8000000000000000ull) - { - val64 = operand->unsigned_imm.val64 - 1; - val64 = ~val64; - operand->unsigned_imm.val64 = ref + (*pos - old_pos); - operand->unsigned_imm.val64 -= val64; - } - else operand->unsigned_imm.val64 += ref + (*pos - old_pos); - break; - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : operand = structure dont le contenu est à définir. * -* size = taille de l'opérande souhaitée. * -* ... = zone d'enregistrement prévue. * -* * -* Description : Récupère la valeur d'une opérande sur x bits. * -* * -* Retour : true si l'opération s'est effectuée avec succès, false sinon.* -* * -* Remarques : - * -* * -******************************************************************************/ - -bool get_imm_operand_value(asm_operand *operand, AsmOperandSize size, ...) -{ - bool result; /* Bilan à retourner */ - va_list ap; /* Récupération d'argument */ - uint8_t *us_val8; /* Valeur sur 8 bits n.-s. */ - uint16_t *us_val16; /* Valeur sur 16 bits n.-s. */ - uint32_t *us_val32; /* Valeur sur 32 bits n.-s. */ - uint64_t *us_val64; /* Valeur sur 64 bits n.-s. */ - int8_t *s_val8; /* Valeur sur 8 bits signés */ - int16_t *s_val16; /* Valeur sur 16 bits signés */ - int32_t *s_val32; /* Valeur sur 32 bits signés */ - int64_t *s_val64; /* Valeur sur 64 bits signés */ - - result = true; - - va_start(ap, size); - - switch (size) - { - case AOS_8_BITS_UNSIGNED: - us_val8 = va_arg(ap, uint8_t *); - switch (operand->size) - { - case AOS_8_BITS_UNSIGNED: - *us_val8 = operand->unsigned_imm.val8; - break; - case AOS_8_BITS_SIGNED: - *us_val8 = operand->signed_imm.val8; - break; - default: - result = false; - break; - } - break; - - case AOS_16_BITS_UNSIGNED: - us_val16 = va_arg(ap, uint16_t *); - switch (operand->size) - { - case AOS_8_BITS_UNSIGNED: - *us_val16 = operand->unsigned_imm.val8; - break; - case AOS_16_BITS_UNSIGNED: - *us_val16 = operand->unsigned_imm.val16; - break; - case AOS_8_BITS_SIGNED: - *us_val16 = operand->signed_imm.val8; - break; - case AOS_16_BITS_SIGNED: - *us_val16 = operand->signed_imm.val16; - break; - default: - result = false; - break; - } - break; - - case AOS_32_BITS_UNSIGNED: - us_val32 = va_arg(ap, uint32_t *); - switch (operand->size) - { - case AOS_8_BITS_UNSIGNED: - *us_val32 = operand->unsigned_imm.val8; - break; - case AOS_16_BITS_UNSIGNED: - *us_val32 = operand->unsigned_imm.val16; - break; - case AOS_32_BITS_UNSIGNED: - *us_val32 = operand->unsigned_imm.val32; - break; - case AOS_8_BITS_SIGNED: - *us_val32 = operand->signed_imm.val8; - break; - case AOS_16_BITS_SIGNED: - *us_val32 = operand->signed_imm.val16; - break; - case AOS_32_BITS_SIGNED: - *us_val32 = operand->signed_imm.val32; - break; - default: - result = false; - break; - } - break; - - case AOS_64_BITS_UNSIGNED: - us_val64 = va_arg(ap, uint64_t *); - switch (operand->size) - { - case AOS_8_BITS_UNSIGNED: - *us_val64 = operand->unsigned_imm.val8; - break; - case AOS_16_BITS_UNSIGNED: - *us_val64 = operand->unsigned_imm.val16; - break; - case AOS_32_BITS_UNSIGNED: - *us_val64 = operand->unsigned_imm.val32; - break; - case AOS_64_BITS_UNSIGNED: - *us_val64 = operand->unsigned_imm.val64; - break; - case AOS_8_BITS_SIGNED: - *us_val64 = operand->signed_imm.val8; - break; - case AOS_16_BITS_SIGNED: - *us_val64 = operand->signed_imm.val16; - break; - case AOS_32_BITS_SIGNED: - *us_val64 = operand->signed_imm.val32; - break; - case AOS_64_BITS_SIGNED: - *us_val64 = operand->signed_imm.val64; - break; - default: - result = false; - break; - } - break; - - case AOS_8_BITS_SIGNED: - s_val8 = va_arg(ap, int8_t *); - switch (operand->size) - { - case AOS_8_BITS_UNSIGNED: - *s_val8 = operand->unsigned_imm.val8; - break; - case AOS_8_BITS_SIGNED: - *s_val8 = operand->signed_imm.val8; - break; - default: - result = false; - break; - } - break; - - case AOS_16_BITS_SIGNED: - s_val16 = va_arg(ap, int16_t *); - switch (operand->size) - { - case AOS_8_BITS_UNSIGNED: - *s_val16 = operand->unsigned_imm.val8; - break; - case AOS_16_BITS_UNSIGNED: - *s_val16 = operand->unsigned_imm.val16; - break; - case AOS_8_BITS_SIGNED: - *s_val16 = operand->signed_imm.val8; - break; - case AOS_16_BITS_SIGNED: - *s_val16 = operand->signed_imm.val16; - break; - default: - result = false; - break; - } - break; - - case AOS_32_BITS_SIGNED: - s_val32 = va_arg(ap, int32_t *); - switch (operand->size) - { - case AOS_8_BITS_UNSIGNED: - *s_val32 = operand->unsigned_imm.val8; - break; - case AOS_16_BITS_UNSIGNED: - *s_val32 = operand->unsigned_imm.val16; - break; - case AOS_32_BITS_UNSIGNED: - *s_val32 = operand->unsigned_imm.val32; - break; - case AOS_8_BITS_SIGNED: - *s_val32 = operand->signed_imm.val8; - break; - case AOS_16_BITS_SIGNED: - *s_val32 = operand->signed_imm.val16; - break; - case AOS_32_BITS_SIGNED: - *s_val32 = operand->signed_imm.val32; - break; - default: - result = false; - break; - } - break; - - case AOS_64_BITS_SIGNED: - s_val64 = va_arg(ap, int64_t *); - switch (operand->size) - { - case AOS_8_BITS_UNSIGNED: - *s_val64 = operand->unsigned_imm.val8; - break; - case AOS_16_BITS_UNSIGNED: - *s_val64 = operand->unsigned_imm.val16; - break; - case AOS_32_BITS_UNSIGNED: - *s_val64 = operand->unsigned_imm.val32; - break; - case AOS_64_BITS_UNSIGNED: - *s_val64 = operand->unsigned_imm.val64; - break; - case AOS_8_BITS_SIGNED: - *s_val64 = operand->signed_imm.val8; - break; - case AOS_16_BITS_SIGNED: - *s_val64 = operand->signed_imm.val16; - break; - case AOS_32_BITS_SIGNED: - *s_val64 = operand->signed_imm.val32; - break; - case AOS_64_BITS_SIGNED: - *s_val64 = operand->signed_imm.val64; - break; - default: - result = false; - break; - } - break; - - default: - result = false; - break; - - } - - va_end(ap); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : operand = instruction à traiter. * -* buffer = tampon de sortie mis à disposition. [OUT] * -* len = taille de ce tampon. * -* syntax = type de représentation demandée. * -* * -* Description : Traduit une opérande de valeur immédiate en texte. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void print_imm_operand(const asm_operand *operand, char *buffer, size_t len, AsmSyntax syntax) -{ - switch (syntax) - { - case ASX_INTEL: - switch (operand->size) - { - case AOS_8_BITS_UNSIGNED: - case AOS_8_BITS_SIGNED: - snprintf(buffer, len, "0x%hhx", operand->unsigned_imm.val8); - break; - case AOS_16_BITS_UNSIGNED: - case AOS_16_BITS_SIGNED: - snprintf(buffer, len, "0x%hx", operand->unsigned_imm.val16); - break; - case AOS_32_BITS_UNSIGNED: - case AOS_32_BITS_SIGNED: - snprintf(buffer, len, "0x%x", operand->unsigned_imm.val32); - break; - case AOS_64_BITS_UNSIGNED: - case AOS_64_BITS_SIGNED: - snprintf(buffer, len, "0x%llx", operand->unsigned_imm.val64); - break; - } - break; - - case ASX_ATT: - switch (operand->size) - { - case AOS_8_BITS_UNSIGNED: - case AOS_8_BITS_SIGNED: - snprintf(buffer, len, "$0x%hhx", operand->unsigned_imm.val8); - break; - case AOS_16_BITS_UNSIGNED: - case AOS_16_BITS_SIGNED: - snprintf(buffer, len, "$0x%hx", operand->unsigned_imm.val16); - break; - case AOS_32_BITS_UNSIGNED: - case AOS_32_BITS_SIGNED: - snprintf(buffer, len, "$0x%x", operand->unsigned_imm.val32); - break; - case AOS_64_BITS_UNSIGNED: - case AOS_64_BITS_SIGNED: - snprintf(buffer, len, "$0x%llx", operand->unsigned_imm.val64); - break; - } - break; - - } - -} - - - - - - - - - - - - - - - /* Initialise la classe générique des opérandes. */ static void g_arch_operand_class_init(GArchOperandClass *); |