diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2020-01-15 19:19:40 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2020-01-15 19:19:40 (GMT) |
commit | d75fe33356f22c1c41925bffe179a55b9cea6cd1 (patch) | |
tree | 37b9a32d3a2b688326791392b338e025bb4c84f3 /src/arch/immediate.c | |
parent | 55935908085677432f746f8378e600f4fd8234b0 (diff) |
Reorganized the architecture operands.
Diffstat (limited to 'src/arch/immediate.c')
-rw-r--r-- | src/arch/immediate.c | 1533 |
1 files changed, 0 insertions, 1533 deletions
diff --git a/src/arch/immediate.c b/src/arch/immediate.c deleted file mode 100644 index 2d021be..0000000 --- a/src/arch/immediate.c +++ /dev/null @@ -1,1533 +0,0 @@ - -/* Chrysalide - Outil d'analyse de fichiers binaires - * immediate.c - opérandes représentant des valeurs numériques - * - * Copyright (C) 2009-2017 Cyrille Bagard - * - * This file is part of Chrysalide. - * - * Chrysalide is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * Chrysalide is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Chrysalide. If not, see <http://www.gnu.org/licenses/>. - */ - - -#include "immediate.h" - - -#include <assert.h> -#include <ctype.h> -#include <inttypes.h> -#include <limits.h> -#include <malloc.h> -#include <stdarg.h> -#include <stdio.h> -#include <string.h> - - -#include <i18n.h> - - -#include "operand-int.h" -#include "targetableop-int.h" -#include "../common/asm.h" -#include "../common/extstr.h" -#include "../format/format.h" - - - -/* Définition d'un opérande de valeur numérique (instance) */ -struct _GImmOperand -{ - GArchOperand parent; /* Instance parente */ - - uint64_t raw; /* Valeur transtypée */ - MemoryDataSize size; /* Taille de l'opérande */ - - ImmOperandDisplay def_display; /* Type par défaut d'affichage */ - ImmOperandDisplay display; /* Format général d'affichage */ - unsigned char misc; /* Informations diverses */ - -}; - - -#define IMM_GET_DEF_ZERO_PADDING(op) ((op)->misc & (1 << 0)) -#define IMM_SET_DEF_ZERO_PADDING(op, v) (op)->misc = ((op)->misc & ~(1 << 0)) | ((v) ? (1 << 0) : 0) - -#define IMM_HAS_ZERO_PADDING(op) ((op)->misc & (1 << 1)) -#define IMM_SET_ZERO_PADDING(op) (op)->misc |= (1 << 1) - -#define IMM_GET_ZERO_PADDING_VALUE(op) ((op)->misc & (1 << 2)) -#define IMM_SET_ZERO_PADDING_VALUE(op, v) (op)->misc = ((op)->misc & ~(1 << 2)) | ((v) ? (1 << 2) : 0) - -#define IMM_HAS_DISPLAY(op) ((op)->misc & (1 << 3)) -#define IMM_SET_DISPLAY(op) (op)->misc |= (1 << 3) - - -/* Définition d'un opérande de valeur numérique (classe) */ -struct _GImmOperandClass -{ - GArchOperandClass parent; /* Classe parente */ - -}; - - -/* Initialise la classe des lignes de descriptions initiales. */ -static void g_imm_operand_class_init(GImmOperandClass *); - -/* Initialise la classe des lignes de descriptions initiales. */ -static void g_imm_operand_init(GImmOperand *); - -/* Procède à l'initialisation de l'interface de ciblage. */ -static void g_imm_operand_targetable_interface_init(GTargetableOperandInterface *); - -/* Supprime toutes les références externes. */ -static void g_imm_operand_dispose(GImmOperand *); - -/* Procède à la libération totale de la mémoire. */ -static void g_imm_operand_finalize(GImmOperand *); - -/* Compare un opérande avec un autre. */ -static int g_imm_operand_compare(const GImmOperand *, const GImmOperand *); - -/* Indique si une valeur est complétée par des zéros. */ -static bool g_imm_operand_does_padding_for_display(const GImmOperand *, ImmOperandDisplay); - -/* Construit la chaîne de caractères correspondant à l'opérande. */ -static size_t _g_imm_operand_to_string(const GImmOperand *, ImmOperandDisplay, char [IMM_MAX_SIZE]); - -/* Traduit un opérande en version humainement lisible. */ -static void g_imm_operand_print(const GImmOperand *, GBufferLine *); - -/* Construit un petit résumé concis de l'opérande. */ -static char *g_imm_operand_build_tooltip(const GImmOperand *, const GLoadedBinary *); - - - -/* --------------------- TRANSPOSITIONS VIA CACHE DES OPERANDES --------------------- */ - - -/* Charge un opérande depuis une mémoire tampon. */ -static bool g_imm_operand_unserialize(GImmOperand *, GAsmStorage *, GBinFormat *, packed_buffer *); - -/* Sauvegarde un opérande dans une mémoire tampon. */ -static bool g_imm_operand_serialize(const GImmOperand *, GAsmStorage *, packed_buffer *); - - - -/* ----------------------- INTERFACE DE CIBLAGE POUR OPERANDE ----------------------- */ - - -/* Obtient l'adresse de la cible visée par un opérande. */ -static bool g_imm_operand_get_addr(const GImmOperand *, const vmpa2t *, GBinFormat *, GArchProcessor *, vmpa2t *); - - - -/* Indique le type défini pour un opérande de valeur numérique. */ -G_DEFINE_TYPE_WITH_CODE(GImmOperand, g_imm_operand, G_TYPE_ARCH_OPERAND, - G_IMPLEMENT_INTERFACE(G_TYPE_TARGETABLE_OPERAND, g_imm_operand_targetable_interface_init)); - - - -/****************************************************************************** -* * -* Paramètres : klass = classe à initialiser. * -* * -* Description : Initialise la classe des lignes de descriptions initiales. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_imm_operand_class_init(GImmOperandClass *klass) -{ - GObjectClass *object; /* Autre version de la classe */ - GArchOperandClass *operand; /* Version de classe parente */ - - object = G_OBJECT_CLASS(klass); - operand = G_ARCH_OPERAND_CLASS(klass); - - object->dispose = (GObjectFinalizeFunc/* ! */)g_imm_operand_dispose; - object->finalize = (GObjectFinalizeFunc)g_imm_operand_finalize; - - operand->compare = (operand_compare_fc)g_imm_operand_compare; - operand->print = (operand_print_fc)g_imm_operand_print; - operand->build_tooltip = (operand_build_tooltip_fc)g_imm_operand_build_tooltip; - - operand->unserialize = (unserialize_operand_fc)g_imm_operand_unserialize; - operand->serialize = (serialize_operand_fc)g_imm_operand_serialize; - -} - - -/****************************************************************************** -* * -* Paramètres : operand = instance à initialiser. * -* * -* Description : Initialise la classe des lignes de descriptions initiales. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_imm_operand_init(GImmOperand *operand) -{ - operand->def_display = IOD_HEX; - operand->misc = 0; - - IMM_SET_DEF_ZERO_PADDING(operand, false); - -} - - -/****************************************************************************** -* * -* Paramètres : iface = interface GLib à initialiser. * -* * -* Description : Procède à l'initialisation de l'interface de ciblage. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_imm_operand_targetable_interface_init(GTargetableOperandInterface *iface) -{ - iface->get_addr = (get_targetable_addr_fc)g_imm_operand_get_addr; - -} - - -/****************************************************************************** -* * -* Paramètres : operand = instance d'objet GLib à traiter. * -* * -* Description : Supprime toutes les références externes. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_imm_operand_dispose(GImmOperand *operand) -{ - G_OBJECT_CLASS(g_imm_operand_parent_class)->dispose(G_OBJECT(operand)); - -} - - -/****************************************************************************** -* * -* Paramètres : operand = instance d'objet GLib à traiter. * -* * -* Description : Procède à la libération totale de la mémoire. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_imm_operand_finalize(GImmOperand *operand) -{ - G_OBJECT_CLASS(g_imm_operand_parent_class)->finalize(G_OBJECT(operand)); - -} - - -/****************************************************************************** -* * -* Paramètres : size = taille de l'opérande souhaitée. * -* content = flux de données à analyser. * -* addr = position courante dans ce flux. [OUT] * -* low = position éventuelle des 4 bits visés. [OUT] * -* endian = ordre des bits dans la source. * -* * -* Description : Crée un opérande réprésentant une valeur numérique. * -* * -* Retour : Instruction mise en place. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GArchOperand *_g_imm_operand_new_from_data(MemoryDataSize size, const GBinContent *content, vmpa2t *addr, bool *low, SourceEndian endian) -{ - GImmOperand *result; /* Opérande à retourner */ - uint8_t uval8; /* Valeur sur 8 bits */ - uint16_t uval16; /* Valeur sur 16 bits */ - uint32_t uval32; /* Valeur sur 32 bits */ - uint64_t uval64; /* Valeur sur 64 bits */ - int8_t sval8; /* Valeur sur 8 bits */ - int16_t sval16; /* Valeur sur 16 bits */ - int32_t sval32; /* Valeur sur 32 bits */ - int64_t sval64; /* Valeur sur 64 bits */ - - result = g_object_new(G_TYPE_IMM_OPERAND, NULL); - - result->size = size; - - switch (size) - { - case MDS_4_BITS_UNSIGNED: - if (!g_binary_content_read_u4(content, addr, low, &uval8)) - goto gionfd_error; - result->raw = uval8; - break; - - case MDS_8_BITS_UNSIGNED: - if (!g_binary_content_read_u8(content, addr, &uval8)) - goto gionfd_error; - result->raw = uval8; - break; - - case MDS_16_BITS_UNSIGNED: - if (!g_binary_content_read_u16(content, addr, endian, &uval16)) - goto gionfd_error; - result->raw = uval16; - break; - - case MDS_32_BITS_UNSIGNED: - if (!g_binary_content_read_u32(content, addr, endian, &uval32)) - goto gionfd_error; - result->raw = uval32; - break; - - case MDS_64_BITS_UNSIGNED: - if (!g_binary_content_read_u64(content, addr, endian, &uval64)) - goto gionfd_error; - result->raw = uval64; - break; - - case MDS_4_BITS_SIGNED: - if (!g_binary_content_read_s4(content, addr, low, &sval8)) - goto gionfd_error; - result->raw = sval8; - break; - - case MDS_8_BITS_SIGNED: - if (!g_binary_content_read_s8(content, addr, &sval8)) - goto gionfd_error; - result->raw = sval8; - break; - - case MDS_16_BITS_SIGNED: - if (!g_binary_content_read_s16(content, addr, endian, &sval16)) - goto gionfd_error; - result->raw = sval16; - break; - - case MDS_32_BITS_SIGNED: - if (!g_binary_content_read_s32(content, addr, endian, &sval32)) - goto gionfd_error; - result->raw = sval32; - break; - - case MDS_64_BITS_SIGNED: - if (!g_binary_content_read_s64(content, addr, endian, &sval64)) - goto gionfd_error; - result->raw = sval64; - break; - - case MDS_UNDEFINED: - goto gionfd_error; - break; - - } - - return G_ARCH_OPERAND(result); - - gionfd_error: - - g_object_unref(G_OBJECT(result)); - - return NULL; - -} - - -/****************************************************************************** -* * -* Paramètres : size = taille de l'opérande souhaitée. * -* value = valeur sur x bits à venir récupérer. * -* * -* Description : Crée un opérande réprésentant une valeur numérique. * -* * -* Retour : Instruction mise en place. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GArchOperand *g_imm_operand_new_from_value(MemoryDataSize size, uint64_t value) -{ - GImmOperand *result; /* Opérande à retourner */ - - if (size == MDS_UNDEFINED) - result = NULL; - - else - { - result = g_object_new(G_TYPE_IMM_OPERAND, NULL); - - result->size = size; - result->raw = value; - - } - - return (result != NULL ? G_ARCH_OPERAND(result) : NULL); - -} - - -/****************************************************************************** -* * -* Paramètres : a = premier opérande à consulter. * -* b = second opérande à consulter. * -* * -* Description : Compare un opérande avec un autre. * -* * -* Retour : Bilan de la comparaison. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static int g_imm_operand_compare(const GImmOperand *a, const GImmOperand *b) -{ - int result; /* Bilan à retourner */ - - if (a->size < b->size) - { - result = -1; - goto gioc_done; - } - else if (a->size > b->size) - { - result = 1; - goto gioc_done; - } - - if (a->raw < b->raw) - { - result = -1; - goto gioc_done; - } - else if (a->raw > b->raw) - { - result = 1; - goto gioc_done; - } - - if (a->def_display < b->def_display) - { - result = -1; - goto gioc_done; - } - else if (a->def_display > b->def_display) - { - result = 1; - goto gioc_done; - } - - if (IMM_HAS_DISPLAY(a) != IMM_HAS_DISPLAY(b)) - { - result = (IMM_HAS_DISPLAY(a) ? 1 : -1); - goto gioc_done; - } - - if (IMM_HAS_DISPLAY(a)) - { - if (a->display < b->display) - { - result = -1; - goto gioc_done; - } - else if (a->display > b->display) - { - result = 1; - goto gioc_done; - } - } - - if (IMM_GET_DEF_ZERO_PADDING(a) != IMM_GET_DEF_ZERO_PADDING(b)) - { - result = (IMM_GET_DEF_ZERO_PADDING(a) ? 1 : -1); - goto gioc_done; - } - - if (IMM_HAS_ZERO_PADDING(a) != IMM_HAS_ZERO_PADDING(b)) - { - result = (IMM_HAS_ZERO_PADDING(a) ? 1 : -1); - goto gioc_done; - } - - if (IMM_HAS_ZERO_PADDING(a)) - { - if (IMM_GET_ZERO_PADDING_VALUE(a) != IMM_GET_ZERO_PADDING_VALUE(b)) - { - result = (IMM_GET_ZERO_PADDING_VALUE(a) ? 1 : -1); - goto gioc_done; - } - } - - result = 0; - - gioc_done: - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : operand = structure dont le contenu est à consulter. * -* * -* Description : Renseigne la taille de la valeur indiquée à la construction. * -* * -* Retour : Taille de la valeur représentée en mémoire. * -* * -* Remarques : - * -* * -******************************************************************************/ - -MemoryDataSize g_imm_operand_get_size(const GImmOperand *operand) -{ - return operand->size; - -} - - -/****************************************************************************** -* * -* Paramètres : operand = structure dont le contenu est à consulter. * -* size = taille de l'opérande souhaitée. * -* ... = valeur sur x bits à venir récupérer. * -* * -* Description : Fournit la valeur portée par une opérande numérique. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool g_imm_operand_get_value(const GImmOperand *operand, MemoryDataSize size, ...) -{ - bool result; /* Bilan à retourner */ - va_list ap; /* Liste des compléments */ - uint8_t *uval8; /* Valeur sur 8 bits */ - uint16_t *uval16; /* Valeur sur 16 bits */ - uint32_t *uval32; /* Valeur sur 32 bits */ - uint64_t *uval64; /* Valeur sur 64 bits */ - int8_t *sval8; /* Valeur sur 8 bits */ - int16_t *sval16; /* Valeur sur 16 bits */ - int32_t *sval32; /* Valeur sur 32 bits */ - int64_t *sval64; /* Valeur sur 64 bits */ - - if (operand->size != size) return false; - - result = true; - - va_start(ap, size); - - switch (size) - { - /* Pour GCC... */ - case MDS_UNDEFINED: - result = false; - break; - case MDS_4_BITS_UNSIGNED: - case MDS_8_BITS_UNSIGNED: - uval8 = va_arg(ap, uint8_t *); - *uval8 = operand->raw; - break; - case MDS_16_BITS_UNSIGNED: - uval16 = va_arg(ap, uint16_t *); - *uval16 = operand->raw; - break; - case MDS_32_BITS_UNSIGNED: - uval32 = va_arg(ap, uint32_t *); - *uval32 = operand->raw; - break; - case MDS_64_BITS_UNSIGNED: - uval64 = va_arg(ap, uint64_t *); - *uval64 = operand->raw; - break; - case MDS_4_BITS_SIGNED: - case MDS_8_BITS_SIGNED: - sval8 = va_arg(ap, int8_t *); - *sval8 = operand->raw; - break; - case MDS_16_BITS_SIGNED: - sval16 = va_arg(ap, int16_t *); - *sval16 = operand->raw; - break; - case MDS_32_BITS_SIGNED: - sval32 = va_arg(ap, int32_t *); - *sval32 = operand->raw; - break; - case MDS_64_BITS_SIGNED: - sval64 = va_arg(ap, int64_t *); - *sval64 = operand->raw; - break; - } - - va_end(ap); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : operand = opérande à consulter. * -* * -* Description : Fournit la valeur brute représentée par l'opérande. * -* * -* Retour : Valeur destinée à un usage interne. * -* * -* Remarques : - * -* * -******************************************************************************/ - -uint64_t g_imm_operand_get_raw_value(const GImmOperand *operand) -{ - return operand->raw; - -} - - -/****************************************************************************** -* * -* Paramètres : operand = structure dont le contenu est à actualiser. [OUT] * -* size = taille de l'opérande souhaitée. * -* value = valeur sur x bits à venir récupérer. * -* * -* Description : Définit la nouvelle valeur de l'opérande à une valeur. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void g_imm_operand_set_value(GImmOperand *operand, MemoryDataSize size, uint64_t value) -{ - assert(size != MDS_UNDEFINED); - - operand->size = size; - operand->raw = value; - -} - - -/****************************************************************************** -* * -* Paramètres : operand = structure dont le contenu est à actualiser. [OUT] * -* state = true si des zéro sont à ajouter, false sinon. * -* * -* Description : Précise si des zéro doivent compléter l'affichage ou non. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void g_imm_operand_pad_by_default(GImmOperand *operand, bool state) -{ - IMM_SET_DEF_ZERO_PADDING(operand, state); - -} - - -/****************************************************************************** -* * -* Paramètres : operand = structure dont le contenu est à consulter. * -* * -* Description : Indique si une valeur est complétée par des zéros par défaut.* -* * -* Retour : true si des zéro sont ajoutés à l'affichage, false sinon. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool g_imm_operand_does_padding_by_default(const GImmOperand *operand) -{ - bool result; /* Statut à retourner */ - - result = IMM_GET_DEF_ZERO_PADDING(operand); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : operand = structure dont le contenu est à actualiser. [OUT] * -* state = true si des zéro sont à ajouter, false sinon. * -* * -* Description : Précise si des zéro doivent compléter l'affichage ou non. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void g_imm_operand_pad(GImmOperand *operand, bool state) -{ - IMM_SET_ZERO_PADDING(operand); - IMM_SET_ZERO_PADDING_VALUE(operand, state); - -} - - -/****************************************************************************** -* * -* Paramètres : operand = structure dont le contenu est à consulter. * -* * -* Description : Indique si une valeur est complétée par des zéros. * -* * -* Retour : true si des zéro sont ajoutés à l'affichage, false sinon. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool g_imm_operand_does_padding(const GImmOperand *operand) -{ - bool result; /* Statut à retourner */ - - if (IMM_HAS_ZERO_PADDING(operand)) - result = IMM_GET_ZERO_PADDING_VALUE(operand); - else - result = IMM_GET_DEF_ZERO_PADDING(operand); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : operand = structure dont le contenu est à consulter. * -* display = type d'affichage à considérer. * -* * -* Description : Indique si une valeur est complétée par des zéros. * -* * -* Retour : true si des zéro sont ajoutés à l'affichage, false sinon. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static bool g_imm_operand_does_padding_for_display(const GImmOperand *operand, ImmOperandDisplay display) -{ - bool result; /* Statut à retourner */ - - result = g_imm_operand_does_padding(operand); - - if (result) - { - display = g_imm_operand_get_display(operand); - - if (display != IOD_BIN && display != IOD_HEX) - result = false; - - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : operand = structure dont le contenu est à actualiser. [OUT] * -* display = format global d'un affichage de valeur. * -* * -* Description : Définit le format textuel par défaut de la valeur. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void g_imm_operand_set_default_display(GImmOperand *operand, ImmOperandDisplay display) -{ - operand->def_display = display; - -} - - -/****************************************************************************** -* * -* Paramètres : operand = structure dont le contenu est à consulter. * -* * -* Description : Indique le format textuel par défaut de la valeur. * -* * -* Retour : Format global d'un affichage de valeur. * -* * -* Remarques : - * -* * -******************************************************************************/ - -ImmOperandDisplay g_imm_operand_get_default_display(const GImmOperand *operand) -{ - return operand->def_display; - -} - - -/****************************************************************************** -* * -* Paramètres : operand = structure dont le contenu est à actualiser. [OUT] * -* display = format global d'un affichage de valeur. * -* * -* Description : Définit la grande ligne du format textuel de la valeur. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void g_imm_operand_set_display(GImmOperand *operand, ImmOperandDisplay display) -{ - IMM_SET_DISPLAY(operand); - operand->display = display; - -} - - -/****************************************************************************** -* * -* Paramètres : operand = structure dont le contenu est à consulter. * -* * -* Description : Indique la grande ligne du format textuel de la valeur. * -* * -* Retour : Format global d'un affichage de valeur. * -* * -* Remarques : - * -* * -******************************************************************************/ - -ImmOperandDisplay g_imm_operand_get_display(const GImmOperand *operand) -{ - ImmOperandDisplay result; /* Affichage à retourner */ - - if (IMM_HAS_DISPLAY(operand)) - result = operand->display; - else - result = operand->def_display; - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : operand = structure dont le contenu est à consulter. * -* * -* Description : Indique le signe d'une valeur immédiate. * -* * -* Retour : true si la valeur est strictement négative, false sinon. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool g_imm_operand_is_negative(const GImmOperand *operand) -{ - bool result; /* Bilan à renvoyer */ - - switch (operand->size) - { - case MDS_4_BITS_SIGNED: - case MDS_8_BITS_SIGNED: - case MDS_16_BITS_SIGNED: - case MDS_32_BITS_SIGNED: - case MDS_64_BITS_SIGNED: - /** - * Pour les valeurs plus petites que 64 bits, le compilateur - * réalise une extension de signe lors du transtypage. - */ - result = (operand->raw & 0x8000000000000000ll); - break; - default: - result = false; - break; - } - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : operand = structure dont le contenu est à consulter. * -* * -* Description : Indique si une valeur immédiate est nulle ou non. * -* * -* Retour : true si la valeur est nulle, false sinon. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool g_imm_operand_is_null(const GImmOperand *operand) -{ - return (operand->raw == 0ll); - -} - - -/****************************************************************************** -* * -* Paramètres : operand = opérande à transcrire. * -* display = type d'affichage demandé. * -* value = valeur portée par l'opérande transcrite. [OUT] * -* * -* Description : Construit la chaîne de caractères correspondant à l'opérande.* -* * -* Retour : Nombre de caractères utilisés. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static size_t _g_imm_operand_to_string(const GImmOperand *operand, ImmOperandDisplay display, char value[IMM_MAX_SIZE]) -{ - size_t result; /* Longueur à retourner */ - unsigned int range; /* Catégorie de la taille */ - const char *prefix; /* Entrée en matière */ - const char *suffix; /* Sortie de matière */ - const char *alternate; /* Préfixe de forme alternative*/ - const char *intro; /* Introduction du formatage */ - bool do_padding; /* Indication de bourrage */ - const char *zpad; /* Remplissage par des zéros */ - const char *lmod; /* Modification de longueur */ - const char *conv; /* Opérateur de conversion */ - char binval[65]; /* Conversion intégrée */ - unsigned int max; /* Indice du plus fort bit */ - unsigned int i; /* Boucle de parcours */ - char format[16 + 65]; /* Format d'impression final */ - - static const char *zpad_defs[] = { "", "02", "04", "08", "016" }; - static const char *lmod_defs[] = { "hh", "hh", "h", "", __PRI64_PREFIX }; - static const char *conv_si_defs[] = { "", "o", "d", "x", "c" }; - static const char *conv_us_defs[] = { "", "o", "u", "x", "c" }; - - assert(display <= IOD_LAST_VALID); - - range = MDS_RANGE(operand->size); - - /* Encadrement pour les caractères */ - if (display == IOD_CHAR) - { - prefix = "'"; - suffix = "'"; - } - else - { - prefix = ""; - suffix = ""; - } - - /* Préfix de forme '0x', 'b' ou '0' */ - switch (display) - { - case IOD_BIN: - alternate = "b"; - break; - case IOD_OCT: - alternate = "0"; - break; - case IOD_HEX: - alternate = "0x"; - break; - default: - alternate = ""; - break; - } - - /* Va-t-on réellement avoir besoin d'un formatage ? */ - if (display != IOD_BIN) - intro = "%"; - else - intro = ""; - - /* Drapeau de remplissage ? */ - - do_padding = g_imm_operand_does_padding_for_display(operand, display); - - switch (display) - { - case IOD_BIN: - case IOD_CHAR: - case IOD_OCT: - case IOD_DEC: - zpad = ""; - break; - default: - zpad = (do_padding ? zpad_defs[range] : ""); - break; - } - - /* Modification de la longueur fournie */ - - if (display != IOD_BIN) - lmod = lmod_defs[range]; - else - lmod = ""; - - /* Spécification de la conversion */ - - if (display != IOD_BIN) - { - if (MDS_IS_SIGNED(operand->size)) - conv = conv_si_defs[display]; - else - conv = conv_us_defs[display]; - - } - else - { - if (do_padding) - max = range * 8; - - else - { - if (!msb_64(operand->raw, &max)) - { - conv = "0"; - max = 0; - } - } - - if (max > 0) - { - conv = binval; - - for (i = max; i > 0; i--) - binval[max - i] = (operand->raw & (1llu << (i - 1)) ? '1' : '0'); - - binval[max] = '\0'; - - } - - } - - /* Impression finale */ - - snprintf(format, sizeof(format), "%s%s%s%s%s%s%s", prefix, alternate, intro, zpad, lmod, conv, suffix); - - switch (operand->size) - { - case MDS_UNDEFINED: - result = snprintf(value, IMM_MAX_SIZE, "<? undef value ?>"); - break; - - case MDS_4_BITS_UNSIGNED: - result = snprintf(value, IMM_MAX_SIZE, format, (uint8_t)operand->raw); - break; - - case MDS_8_BITS_UNSIGNED: - result = snprintf(value, IMM_MAX_SIZE, format, (uint8_t)operand->raw); - break; - - case MDS_16_BITS_UNSIGNED: - result = snprintf(value, IMM_MAX_SIZE, format, (uint16_t)operand->raw); - break; - - case MDS_32_BITS_UNSIGNED: - result = snprintf(value, IMM_MAX_SIZE, format, (uint32_t)operand->raw); - break; - - case MDS_64_BITS_UNSIGNED: - result = snprintf(value, IMM_MAX_SIZE, format, (uint64_t)operand->raw); - break; - - case MDS_4_BITS_SIGNED: - result = snprintf(value, IMM_MAX_SIZE, format, (int8_t)operand->raw); - break; - - case MDS_8_BITS_SIGNED: - result = snprintf(value, IMM_MAX_SIZE, format, (int8_t)operand->raw); - break; - - case MDS_16_BITS_SIGNED: - result = snprintf(value, IMM_MAX_SIZE, format, (int16_t)operand->raw); - break; - - case MDS_32_BITS_SIGNED: - result = snprintf(value, IMM_MAX_SIZE, format, (int32_t)operand->raw); - break; - - case MDS_64_BITS_SIGNED: - result = snprintf(value, IMM_MAX_SIZE, format, (int64_t)operand->raw); - break; - - default: - assert(false); - result = 0; - break; - - } - - assert(result > 0); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : operand = opérande à transcrire. * -* syntax = type de représentation demandée. * -* value = valeur portée par l'opérande transcrite. [OUT] * -* * -* Description : Construit la chaîne de caractères correspondant à l'opérande.* -* * -* Retour : Nombre de caractères utilisés. * -* * -* Remarques : - * -* * -******************************************************************************/ - -size_t g_imm_operand_to_string(const GImmOperand *operand, char value[IMM_MAX_SIZE]) -{ - size_t result; /* Longueur à retourner */ - ImmOperandDisplay display; /* Type d'affichage courant */ - - display = g_imm_operand_get_display(operand); - - result = _g_imm_operand_to_string(operand, display, value); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : operand = opérande à traiter. * -* line = ligne tampon où imprimer l'opérande donné. * -* * -* Description : Traduit un opérande en version humainement lisible. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_imm_operand_print(const GImmOperand *operand, GBufferLine *line) -{ - char value[IMM_MAX_SIZE]; /* Chaîne à imprimer */ - size_t len; /* Taille de l'élément inséré */ - - len = g_imm_operand_to_string(operand, value); - - g_buffer_line_append_text(line, BLC_MAIN, value, len, RTT_IMMEDIATE, G_OBJECT(operand)); - -} - - -/****************************************************************************** -* * -* Paramètres : operand = opérande à consulter. * -* binary = informations relatives au binaire chargé. * -* * -* Description : Construit un petit résumé concis de l'opérande. * -* * -* Retour : Chaîne de caractères à libérer après usage ou NULL. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static char *g_imm_operand_build_tooltip(const GImmOperand *operand, const GLoadedBinary *binary) -{ - char *result; /* Description à retourner */ - char value[IMM_MAX_SIZE]; /* Conversion artificielle */ - char *conv; /* Affichage de la Conversion */ - - if (operand->raw <= UCHAR_MAX && isprint(operand->raw)) - switch (operand->raw) - { - case '&': - asprintf(&result, _("Character: '&'")); - break; - case '<': - asprintf(&result, _("Character: '<'")); - break; - case '>': - asprintf(&result, _("Character: '>'")); - break; - default: - asprintf(&result, _("Character: '%c'"), (char)operand->raw); - break; - } - - else - asprintf(&result, _("Character: <not printable>")); - - /* Binaire */ - - _g_imm_operand_to_string(operand, IOD_BIN, value); - - asprintf(&conv, _("Binary: %s"), value); - - result = stradd(result, "\n"); - result = stradd(result, conv); - - free(conv); - - /* Octal */ - - _g_imm_operand_to_string(operand, IOD_OCT, value); - - asprintf(&conv, _("Octal: %s"), value); - - result = stradd(result, "\n"); - result = stradd(result, conv); - - free(conv); - - /* Décimal */ - - _g_imm_operand_to_string(operand, IOD_DEC, value); - - asprintf(&conv, _("Decimal: %s"), value); - - result = stradd(result, "\n"); - result = stradd(result, conv); - - free(conv); - - /* Hexadécimal */ - - _g_imm_operand_to_string(operand, IOD_HEX, value); - - asprintf(&conv, _("Hexadecimal: %s"), value); - - result = stradd(result, "\n"); - result = stradd(result, conv); - - free(conv); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : operand = opérande à traiter. * -* pos = valeur résultante. [OUT] * -* * -* Description : Convertit une valeur immédiate en position de type phys_t. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool g_imm_operand_to_phys_t(const GImmOperand *operand, phys_t *pos) -{ - bool result; /* Bilan à renvoyer */ - - result = !MDS_IS_SIGNED(operand->size); - - if (result) - *pos = operand->raw; - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : operand = opérande à traiter. * -* addr = valeur résultante. [OUT] * -* * -* Description : Convertit une valeur immédiate en adresse de type virt_t. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool g_imm_operand_to_virt_t(const GImmOperand *operand, virt_t *addr) -{ - bool result; /* Bilan à renvoyer */ - - result = !MDS_IS_SIGNED(operand->size); - - if (result) - *addr = operand->raw; - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : operand = opérande à traiter. * -* val = valeur résultante. [OUT] * -* * -* Description : Convertit une valeur immédiate en valeur de type leb128_t. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -void g_imm_operand_as_leb128(const GImmOperand *operand, leb128_t *val) -{ - *val = operand->raw; - -} - - -/****************************************************************************** -* * -* Paramètres : operand = opérande à traiter. * -* val = valeur résultante. [OUT] * -* * -* Description : Convertit une valeur immédiate en valeur de type uleb128_t. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -void g_imm_operand_as_uleb128(const GImmOperand *operand, uleb128_t *val) -{ - *val = operand->raw; - -} - - -/****************************************************************************** -* * -* Paramètres : operand = opérande à traiter. * -* addr = valeur résultante. [OUT] * -* * -* Description : Convertit une valeur immédiate en adresse de type vmpa_t. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool g_imm_operand_to_vmpa_t(const GImmOperand *operand, vmpa_t *addr) -{ - return false; - -} - - -/****************************************************************************** -* * -* Paramètres : operand = opérande à traiter. * -* value = valeur résultante. [OUT] * -* negative = indique si la valeur était négative à l'origine. * -* * -* Description : Convertit une valeur immédiate en valeur de type size_t. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool g_imm_operand_to_size_t(const GImmOperand *operand, size_t *value, bool *negative) -{ - return false; - -} - - -/****************************************************************************** -* * -* Paramètres : operand = opérande à traiter. * -* value = valeur résultante. [OUT] * -* negative = indique si la valeur était négative à l'origine. * -* * -* Description : Convertit une valeur immédiate en valeur de type off_t. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -bool g_imm_operand_to_off_t(const GImmOperand *operand, off_t *value, bool *negative) -{ - return false; - -} - - - -/* ---------------------------------------------------------------------------------- */ -/* TRANSPOSITIONS VIA CACHE DES OPERANDES */ -/* ---------------------------------------------------------------------------------- */ - - -/****************************************************************************** -* * -* Paramètres : operand = opérande d'assemblage à constituer. * -* storage = mécanisme de sauvegarde à manipuler. * -* format = format binaire chargé associé à l'architecture. * -* pbuf = zone tampon à remplir. * -* * -* Description : Charge un opérande depuis une mémoire tampon. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static bool g_imm_operand_unserialize(GImmOperand *operand, GAsmStorage *storage, GBinFormat *format, packed_buffer *pbuf) -{ - bool result; /* Bilan à retourner */ - GArchOperandClass *parent; /* Classe parente à consulter */ - - parent = G_ARCH_OPERAND_CLASS(g_imm_operand_parent_class); - - result = parent->unserialize(G_ARCH_OPERAND(operand), storage, format, pbuf); - - if (result) - result = extract_packed_buffer(pbuf, &operand->raw, sizeof(uint64_t), true); - - if (result) - result = extract_packed_buffer(pbuf, &operand->size, sizeof(MemoryDataSize), true); - - if (result) - result = extract_packed_buffer(pbuf, &operand->def_display, sizeof(ImmOperandDisplay), true); - - if (result) - result = extract_packed_buffer(pbuf, &operand->display, sizeof(ImmOperandDisplay), true); - - if (result) - result = extract_packed_buffer(pbuf, &operand->misc, sizeof(uint8_t), false); - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : operand = opérande d'assemblage à consulter. * -* storage = mécanisme de sauvegarde à manipuler. * -* pbuf = zone tampon à remplir. * -* * -* Description : Sauvegarde un opérande dans une mémoire tampon. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static bool g_imm_operand_serialize(const GImmOperand *operand, GAsmStorage *storage, packed_buffer *pbuf) -{ - bool result; /* Bilan à retourner */ - GArchOperandClass *parent; /* Classe parente à consulter */ - - parent = G_ARCH_OPERAND_CLASS(g_imm_operand_parent_class); - - result = parent->serialize(G_ARCH_OPERAND(operand), storage, pbuf); - - if (result) - result = extend_packed_buffer(pbuf, &operand->raw, sizeof(uint64_t), true); - - if (result) - result = extend_packed_buffer(pbuf, &operand->size, sizeof(MemoryDataSize), true); - - if (result) - result = extend_packed_buffer(pbuf, &operand->def_display, sizeof(ImmOperandDisplay), true); - - if (result) - result = extend_packed_buffer(pbuf, &operand->display, sizeof(ImmOperandDisplay), true); - - if (result) - result = extend_packed_buffer(pbuf, &operand->misc, sizeof(uint8_t), false); - - return result; - -} - - - -/* ---------------------------------------------------------------------------------- */ -/* INTERFACE DE CIBLAGE POUR OPERANDE */ -/* ---------------------------------------------------------------------------------- */ - - -/****************************************************************************** -* * -* Paramètres : operand = operande à consulter. * -* src = localisation de l'instruction mère. * -* format = format reconnu pour le binaire chargé. * -* proc = architecture associée à ce même binaire. * -* addr = localisation de la cible. [OUT] * -* * -* Description : Obtient l'adresse de la cible visée par un opérande. * -* * -* Retour : true si la cible est valide, false sinon. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static bool g_imm_operand_get_addr(const GImmOperand *operand, const vmpa2t *src, GBinFormat *format, GArchProcessor *proc, vmpa2t *addr) -{ - bool result; /* Bilan à retourner */ - virt_t virt; /* Adresse virtuelle */ - - result = g_imm_operand_to_virt_t(operand, &virt); - - if (result) - result = g_exe_format_translate_address_into_vmpa(G_EXE_FORMAT(format), virt, addr); - - return result; - -} |