diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/arch/arm/v7/processor.c | 5 | ||||
-rw-r--r-- | src/arch/immediate.c | 87 | ||||
-rw-r--r-- | src/arch/raw.c | 57 | ||||
-rw-r--r-- | src/arch/raw.h | 3 | ||||
-rw-r--r-- | src/common/asm.c | 38 | ||||
-rw-r--r-- | src/common/asm.h | 3 |
6 files changed, 111 insertions, 82 deletions
diff --git a/src/arch/arm/v7/processor.c b/src/arch/arm/v7/processor.c index 7a1dd5a..195b87c 100644 --- a/src/arch/arm/v7/processor.c +++ b/src/arch/arm/v7/processor.c @@ -289,11 +289,6 @@ static GArchInstruction *g_armv7_processor_disassemble(const GArmV7Processor *pr } - /* - else - result = g_raw_instruction_new_array_old(data, MDS_32_BITS, 1, pos, end, - G_ARCH_PROCESSOR(proc)->endianness); - */ return result; } diff --git a/src/arch/immediate.c b/src/arch/immediate.c index 3720bff..4c9ea84 100644 --- a/src/arch/immediate.c +++ b/src/arch/immediate.c @@ -32,6 +32,7 @@ #include "operand-int.h" +#include "../common/asm.h" #include "../common/extstr.h" #include "../format/format.h" @@ -739,12 +740,15 @@ static size_t g_imm_operand_to_string(const GImmOperand *operand, AsmSyntax synt const char *zpad; /* Remplissage par des zéros */ const char *lmod; /* Modification de longueur */ const char *conv; /* Opérateur de conversion */ - char format[16]; /* Format d'impression final */ + char binval[65]; /* Conversion intégrée */ + unsigned int max; /* Indice du plus fort bit */ + unsigned int i; /* Boucle de parcours #1 */ + 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[] = { "c", "d", "x", "o" }; - static const char *conv_us_defs[] = { "c", "u", "x", "o" }; + static const char *conv_si_defs[] = { "", "o", "d", "x", "c" }; + static const char *conv_us_defs[] = { "", "o", "u", "x", "c" }; result = 0; /* Gcc... */ @@ -762,28 +766,77 @@ static size_t g_imm_operand_to_string(const GImmOperand *operand, AsmSyntax synt suffix = ""; } - /* Préfix de forme '0x' ou '0' */ - if (operand->display == IOD_HEX) - alternate = "0x"; - else if (operand->display == IOD_OCT) - alternate = "0"; - else - alternate = ""; + /* Préfix de forme '0x', 'b' ou '0' */ + switch (operand->display) + { + case IOD_BIN: + alternate = "b"; + break; + case IOD_OCT: + alternate = "0"; + break; + case IOD_HEX: + alternate = "0x"; + break; + default: + alternate = ""; + break; + } /* Drapeau de remplissage ? */ - if (operand->display == IOD_HEX) - zpad = (operand->zpad ? zpad_defs[range] : ""); - else - zpad = ""; + switch (operand->display) + { + case IOD_BIN: + case IOD_CHAR: + zpad = ""; + break; + default: + zpad = (operand->zpad ? zpad_defs[range] : ""); + break; + } /* Modification de la longueur fournie */ lmod = lmod_defs[range]; /* Spécification de la conversion */ - if (MDS_IS_SIGNED(operand->size)) - conv = conv_si_defs[operand->display]; + + if (operand->display != IOD_BIN) + { + if (MDS_IS_SIGNED(operand->size)) + conv = conv_si_defs[operand->display]; + else + conv = conv_us_defs[operand->display]; + + } else - conv = conv_us_defs[operand->display]; + { + if (operand->zpad) + max = range * 8 + 1; + else + { + if (!msb_64(operand->raw, &max)) + { + conv = "0"; + max = 0; + } + else + max++; + } + + if (max > 0) + { + conv = binval; + + for (i = max; i > 0; i--) + binval[max - i] = (operand->raw & (1 << (i - 1)) ? '1' : '0'); + + binval[max] = '\0'; + + } + + } + + /* Impression finale */ snprintf(format, sizeof(format), "%s%s%%%s%s%s%s", prefix, alternate, zpad, lmod, conv, suffix); diff --git a/src/arch/raw.c b/src/arch/raw.c index 41f46c1..a9fc3df 100644 --- a/src/arch/raw.c +++ b/src/arch/raw.c @@ -243,63 +243,6 @@ GArchInstruction *g_raw_instruction_new_from_value(const vmpa2t *addr, MemoryDat /****************************************************************************** * * -* Paramètres : data = flux de données à analyser. * -* size = taille de chacun des éléments à représenter. * -* count = nombre de ces éléments. * -* addr = position courante dans ce flux. [OUT] * -* end = limite des données à analyser. * -* endian = ordre des bits dans la source. * -* * -* Description : Crée une instruction de type 'db/dw/etc' étendue. * -* * -* Retour : Instruction mise en place. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GArchInstruction *g_raw_instruction_new_array_old(const bin_t *data, MemoryDataSize size, size_t count, vmpa2t *addr, off_t end, SourceEndian endian) -{ - GArchInstruction *result; /* Instruction à retourner */ - vmpa2t old; /* Sauvegarde de la position */ - size_t i; /* Boucle de parcours */ - GArchOperand *operand; /* Octet non décodé à afficher */ - mrange_t range; /* Couverture de l'instruction */ - - /* Par soucis de cohérence */ - if (count == 0) return NULL; - - result = g_object_new(G_TYPE_RAW_INSTRUCTION, NULL); - - copy_vmpa(&old, addr); - - for (i = 0; i < count; i++) - { - operand = g_imm_operand_new_from_data_old(size, data, addr, end, endian); - if (operand == NULL) goto grina_error; - - g_imm_operand_pad(G_IMM_OPERAND(operand), true); - - g_arch_instruction_attach_extra_operand(result, operand); - } - - init_mrange(&range, &old, compute_vmpa_diff(addr, &old)); - - g_arch_instruction_set_range(result, &range); - - return result; - - grina_error: - - g_object_unref(G_OBJECT(result)); - - return NULL; - -} - - -/****************************************************************************** -* * * Paramètres : content = flux de données à analyser. * * size = taille de chacun des éléments à représenter. * * count = nombre de ces éléments. * diff --git a/src/arch/raw.h b/src/arch/raw.h index 6712b81..459ade2 100644 --- a/src/arch/raw.h +++ b/src/arch/raw.h @@ -56,9 +56,6 @@ GType g_raw_instruction_get_type(void); GArchInstruction *g_raw_instruction_new_from_value(const vmpa2t *, MemoryDataSize, uint64_t); /* Crée une instruction de type 'db/dw/etc' étendue. */ -GArchInstruction *g_raw_instruction_new_array_old(const bin_t *, MemoryDataSize, size_t, vmpa2t *, off_t, SourceEndian); - -/* Crée une instruction de type 'db/dw/etc' étendue. */ GArchInstruction *g_raw_instruction_new_array(const GBinContent *, MemoryDataSize, size_t, vmpa2t *, SourceEndian); /* Marque l'instruction comme ne contenant que du bourrage. */ diff --git a/src/common/asm.c b/src/common/asm.c index 597013a..0e92938 100644 --- a/src/common/asm.c +++ b/src/common/asm.c @@ -65,3 +65,41 @@ bool msb_32(uint32_t v, unsigned int *p) return true; } + + +/****************************************************************************** +* * +* Paramètres : v = valeur quelconque sur 64 bits. * +* p = position du premier bit à 1 (poids fort). [OUT] * +* * +* Description : Détermine l'indice du premier bit à 1, côté gauche. * +* * +* Retour : true si le nombre est différent de zéro, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool msb_64(uint64_t v, unsigned int *p) +{ + static const unsigned int bval[] = { 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4 }; + + /* S'il n'y a aucun bit à 1... */ + if (v == 0) return false; + + /** + * Cf. msb_32(). + */ + + *p = 0; + + if (v & 0xffffffff00000000ull) { *p += 32 / 1; v >>= 32 / 1; } + if (v & 0x00000000ffff0000ull) { *p += 32 / 2; v >>= 32 / 2; } + if (v & 0x000000000000ff00ull) { *p += 32 / 4; v >>= 32 / 4; } + if (v & 0x00000000000000f0ull) { *p += 32 / 8; v >>= 32 / 8; } + + *p += bval[v]; + + return true; + +} diff --git a/src/common/asm.h b/src/common/asm.h index 047d8db..5207bf7 100644 --- a/src/common/asm.h +++ b/src/common/asm.h @@ -33,6 +33,9 @@ /* Détermine l'indice du premier bit à 1, côté gauche. */ bool msb_32(uint32_t, unsigned int *); +/* Détermine l'indice du premier bit à 1, côté gauche. */ +bool msb_64(uint64_t, unsigned int *); + #endif /* _COMMON_ASM_H */ |