summaryrefslogtreecommitdiff
path: root/plugins/arm/v7/helpers.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/arm/v7/helpers.c')
-rw-r--r--plugins/arm/v7/helpers.c277
1 files changed, 277 insertions, 0 deletions
diff --git a/plugins/arm/v7/helpers.c b/plugins/arm/v7/helpers.c
new file mode 100644
index 0000000..03786c0
--- /dev/null
+++ b/plugins/arm/v7/helpers.c
@@ -0,0 +1,277 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * helpers.c - aide à la mise en place des opérandes ARMv7
+ *
+ * Copyright (C) 2014-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 Foobar. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "helpers.h"
+
+
+#include <arch/register.h>
+#include <arch/immediate.h>
+#include <common/asm.h>
+#include <common/bconst.h>
+
+
+#include "register.h"
+
+
+
+/******************************************************************************
+* *
+* Paramètres : x = valeur sur 32 bits maximum à traiter. *
+* shift = nombre de décallages visés. *
+* *
+* Description : Effectue une rotation vers la droit d'une valeur. *
+* *
+* Retour : Adresse de la structure mise en place. *
+* *
+* Remarques : Correspond à la pseudo fonction 'ROR_C'. *
+* *
+******************************************************************************/
+
+GArchOperand *ror_armv7_imm(uint32_t x, unsigned int shift)
+{
+ GArchOperand *result; /* Opérande à faire remonter */
+ uint32_t val32; /* Valeur sur 32 bits */
+
+ shift %= 32;
+
+ val32 = (x >> shift) | (x << (32 - shift));
+
+ result = g_imm_operand_new_from_value(MDS_32_BITS_UNSIGNED, val32);
+
+ return result;
+
+}
+
+
+
+
+
+
+
+
+
+
+
+
+#if 0
+
+// Shift_C()
+// =========
+(bits(N), bit) Shift_C(bits(N) value, SRType type, integer amount, bit carry_in)
+assert !(type == SRType_RRX && amount != 1);
+if amount == 0 then
+(result, carry_out) = (value, carry_in);
+else
+case type of
+
+when SRType_LSL
+(result, carry_out) = LSL_C(value, amount);
+
+when SRType_LSR
+(result, carry_out)
+
+when SRType_ASR
+(result, carry_out)
+
+when SRType_ROR
+(result, carry_out)
+
+when SRType_RRX
+(result, carry_out)
+= LSR_C(value, amount);
+= ASR_C(value, amount);
+= ROR_C(value, amount);
+= RRX_C(value, carry_in);
+
+#endif
+
+
+
+
+
+
+/******************************************************************************
+* *
+* Paramètres : value = valeur sur 32 bits maximum à traiter. *
+* topbit = valeur du bit de poids fort manipulé. *
+* size = taille de la valeur finale à constituer. *
+* *
+* Description : Crée un opérande de valeur immédiate avec extension de signe.*
+* *
+* Retour : Adresse de la structure mise en place. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GArchOperand *sign_extend_armv7_imm(uint32_t value, bool topbit, unsigned int size)
+{
+ GArchOperand *result; /* Opérande à faire remonter */
+ unsigned int msb; /* Position du premier bit à 1 */
+ MemoryDataSize mds; /* Conversion de la taille */
+ uint32_t val4; /* Valeur sur 4 bits */
+ uint32_t val8; /* Valeur sur 8 bits */
+ uint32_t val16; /* Valeur sur 16 bits */
+ uint32_t val32; /* Valeur sur 32 bits */
+ unsigned int i; /* Boucle de parcours */
+
+ result = NULL;
+
+ topbit &= msb_32(value, &msb);
+
+ switch (size)
+ {
+
+#define SIGN_EXTEND_CASE(sz) \
+ case sz: \
+ mds = MDS_ ## sz ## _BITS_SIGNED; \
+ val ## sz = value; \
+ if (topbit) \
+ for (i = msb; i < sz; i++) \
+ val ## sz |= (1 << i); \
+ result = g_imm_operand_new_from_value(mds, val ## sz); \
+ break;
+
+ SIGN_EXTEND_CASE(4);
+ SIGN_EXTEND_CASE(8);
+ SIGN_EXTEND_CASE(16);
+ SIGN_EXTEND_CASE(32);
+
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : value = valeur sur 32 bits maximum à traiter. *
+* *
+* Description : Etend une valeur immédiate en mode 'Thumb' ARMv7. *
+* *
+* Retour : Adresse de la structure mise en place. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GArchOperand *thumb_expand_armv7_imm(uint32_t value)
+{
+ GArchOperand *result; /* Opérande à faire remonter */
+ uint8_t byte; /* Octet à reproduire */
+ uint32_t val32; /* Valeur sur 32 bits */
+ uint32_t unrotated; /* Transformation à décaller */
+
+ result = NULL;
+
+ if (((value >> 10) & b11) == b00)
+ {
+ byte = value & 0xff;
+
+ switch ((value >> 8) & b11)
+ {
+ case b00:
+ result = zero_extend_armv7_imm(byte, 32);
+ break;
+
+ case b01:
+ if (byte == 0) return NULL;
+ val32 = byte << 16 | byte;
+ result = g_imm_operand_new_from_value(MDS_32_BITS_UNSIGNED, val32);
+ break;
+
+ case b10:
+ if (byte == 0) return NULL;
+ val32 = byte << 24 | byte << 8;
+ result = g_imm_operand_new_from_value(MDS_32_BITS_UNSIGNED, val32);
+ break;
+
+ case b11:
+ if (byte == 0) return NULL;
+ val32 = byte << 24 | byte << 16 | byte << 8 | byte;
+ result = g_imm_operand_new_from_value(MDS_32_BITS_UNSIGNED, val32);
+ break;
+
+ }
+
+ }
+ else
+ {
+ unrotated = 1 << 7 | (value & 0x3f);
+ result = ror_armv7_imm(unrotated, (value >> 7) & 0x1f);
+ }
+
+ return result;
+
+}
+
+
+
+
+
+
+/******************************************************************************
+* *
+* Paramètres : value = valeur sur 32 bits maximum à traiter. *
+* size = taille de la valeur finale à constituer. *
+* *
+* Description : Réalise un simple transtypage de valeur entière. *
+* *
+* Retour : Adresse de la structure mise en place. *
+* *
+* Remarques : Correspond à la pseudo fonction 'ZeroExtend'. *
+* *
+******************************************************************************/
+
+GArchOperand *zero_extend_armv7_imm(uint32_t value, unsigned int size)
+{
+ GArchOperand *result; /* Opérande à faire remonter */
+ MemoryDataSize mds; /* Conversion de la taille */
+ uint32_t val4; /* Valeur sur 4 bits */
+ uint32_t val8; /* Valeur sur 8 bits */
+ uint32_t val16; /* Valeur sur 16 bits */
+ uint32_t val32; /* Valeur sur 32 bits */
+
+ result = NULL;
+
+ switch (size)
+ {
+
+#define ZERO_EXTEND_CASE(sz) \
+ case sz: \
+ mds = MDS_ ## sz ## _BITS_UNSIGNED; \
+ val ## sz = value; \
+ result = g_imm_operand_new_from_value(mds, val ## sz); \
+ break;
+
+ ZERO_EXTEND_CASE(4);
+ ZERO_EXTEND_CASE(8);
+ ZERO_EXTEND_CASE(16);
+ ZERO_EXTEND_CASE(32);
+
+ }
+
+ return result;
+
+}