diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2010-07-29 00:02:49 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2010-07-29 00:02:49 (GMT) |
commit | 73af1bd66e5d1a2e30d56151532710f2b28d12df (patch) | |
tree | 88f98194359accd8349193f4cbe3c4cabee24d23 /src/common/endianness.c | |
parent | f150f36ee0297b4499a41bbbfc06699cd2f72db5 (diff) |
Improved the GDB client.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@175 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'src/common/endianness.c')
-rwxr-xr-x | src/common/endianness.c | 197 |
1 files changed, 197 insertions, 0 deletions
diff --git a/src/common/endianness.c b/src/common/endianness.c index 5a14e1c..0b7e192 100755 --- a/src/common/endianness.c +++ b/src/common/endianness.c @@ -24,6 +24,9 @@ #include "endianness.h" +#include <stdarg.h> + + /****************************************************************************** * * @@ -318,3 +321,197 @@ bool read_u64(uint64_t *target, const bin_t *data, off_t *pos, off_t len, Source return true; } + + +/****************************************************************************** +* * +* Paramètres : target = lieu d'enregistrement de la lecture. [OUT] * +* data = flux de données à analyser. * +* pos = position courante dans ce flux. [OUT] * +* len = taille totale des données à analyser. * +* endian = ordre des bits dans la source. * +* * +* Description : Lit un nombre hexadécimal non signé sur deux octets. * +* * +* Retour : Bilan de l'opération : true en cas de succès, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool strtou8(uint8_t *target, const char *data, size_t *pos, size_t len, SourceEndian endian) +{ + size_t i; /* Boucle de parcours */ + + if (*pos < 0) return false; + if ((len - *pos) < 2) return false; + + *target = 0; + + for (i = 0; i < 2; i++) + switch (data[*pos + i]) + { + case '0' ... '9': + *target |= ((data[*pos + i] - '0') << (4 * (1 - i))); + break; + + case 'A' ... 'F': + *target |= ((data[*pos + i] + 10 - 'A') << (4 * (1 - i))); + break; + + case 'a' ... 'f': + *target |= ((data[*pos + i] + 10 - 'a') << (4 * (1 - i))); + break; + + } + + *pos += 2; + + return true; + +} + + + +/****************************************************************************** +* * +* Paramètres : n = nombre d'octets constituant le nombre à lire. * +* data = flux de données à analyser. * +* pos = position courante dans ce flux. [OUT] * +* len = taille totale des données à analyser. * +* endian = ordre des bits dans la source. * +* ... = lieu d'enregistrement de la lecture. [OUT] * +* * +* Description : Lit un nombre hexadécimal non signé sur n octets. * +* * +* Retour : Bilan de l'opération : true en cas de succès, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool _strtoun(uint8_t n, const char *data, size_t *pos, size_t len, SourceEndian endian, ...) +{ + bool result; /* Bilan à renvoyer */ + va_list ap; /* Arguments variables */ + uint8_t *target8; /* Enregistrement sur 8 bits */ + uint16_t *target16; /* Enregistrement sur 16 bits */ + uint32_t *target32; /* Enregistrement sur 32 bits */ + uint64_t *target64; /* Enregistrement sur 64 bits */ + uint8_t i; /* Boucle de parcours #1 */ + size_t j; /* Boucle de parcours #2 */ + uint8_t tmp; /* Valeur temporaire de 8 bits */ + + if (*pos < 0) return false; + if ((len - *pos) < (n * 2)) return false; + + /* Récupération de la destination */ + + va_start(ap, endian); + + switch (n) + { + case 1: + target8 = va_arg(ap, uint8_t *); + *target8 = 0; + target64 = (uint64_t *)target8; + break; + case 2: + target16 = va_arg(ap, uint16_t *); + *target16 = 0; + target64 = (uint64_t *)target16; + break; + case 4: + target32 = va_arg(ap, uint32_t *); + *target32 = 0; + target64 = (uint64_t *)target32; + break; + case 8: + target64 = va_arg(ap, uint64_t *); + *target64 = 0ull; + break; + default: + va_end(ap); + return false; + break; + } + + va_end(ap); + + /* Lecture des données */ + + result = true; + + for (i = 0; i < n && result; i++) + { + tmp = 0; + + for (j = 0; j < 2 && result; j++) + switch (data[*pos + j]) + { + case '0' ... '9': + tmp |= ((data[*pos + j] - '0') << (4 * (1 - j))); + break; + + case 'A' ... 'F': + tmp |= ((data[*pos + j] + 10 - 'A') << (4 * (1 - j))); + break; + + case 'a' ... 'f': + tmp |= ((data[*pos + j] + 10 - 'a') << (4 * (1 - j))); + break; + + default: + printf(" string :: '%s'\n", &data[*pos + j]); + result = false; + break; + + } + + *pos += 2; + + switch (endian) + { + case SRE_LITTLE: + +#if __BYTE_ORDER == __LITTLE_ENDIAN + + *target64 |= ((uint64_t)tmp) << (8 * i); + +#elif __BYTE_ORDER == __BIG_ENDIAN + + *target64 |= ((uint64_t)tmp) << (8 * (n - 1 - i)); + +#else + +# error "TODO : PDP !" + +#endif + + break; + + case SRE_BIG: + +#if __BYTE_ORDER == __LITTLE_ENDIAN + + *target64 |= ((uint64_t)tmp) << (8 * (n - 1 - i)); + +#elif __BYTE_ORDER == __BIG_ENDIAN + + *target64 |= ((uint64_t)tmp) << (8 * i); + +#else + +# error "TODO : PDP !" + +#endif + + break; + + } + + } + + return result; + +} |