summaryrefslogtreecommitdiff
path: root/src/common/endianness.c
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2010-07-29 00:02:49 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2010-07-29 00:02:49 (GMT)
commit73af1bd66e5d1a2e30d56151532710f2b28d12df (patch)
tree88f98194359accd8349193f4cbe3c4cabee24d23 /src/common/endianness.c
parentf150f36ee0297b4499a41bbbfc06699cd2f72db5 (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-xsrc/common/endianness.c197
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;
+
+}