summaryrefslogtreecommitdiff
path: root/src/glibext
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2015-02-16 07:07:15 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2015-02-16 07:07:15 (GMT)
commit635640a32fecbb9b8a5ddf239b819c022c4b9977 (patch)
treef8fc69a2c2db411000996146536ca5cc4f54d417 /src/glibext
parentbf879f2562545ab7de23f9d38364b7bd4b43fb2c (diff)
Added a basic support for Mobicore truslets.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@472 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'src/glibext')
-rw-r--r--src/glibext/gbincontent.c392
-rw-r--r--src/glibext/gbincontent.h25
2 files changed, 414 insertions, 3 deletions
diff --git a/src/glibext/gbincontent.c b/src/glibext/gbincontent.c
index c72ac15..e0c64d4 100644
--- a/src/glibext/gbincontent.c
+++ b/src/glibext/gbincontent.c
@@ -24,6 +24,7 @@
#include "gbincontent.h"
+#include <assert.h>
#include <fcntl.h>
#include <malloc.h>
#include <stdio.h>
@@ -33,6 +34,9 @@
#include <sys/stat.h>
+#include "../common/endianness.h"
+
+
/* Aire de contenu binaire */
typedef struct _binary_part
@@ -73,6 +77,9 @@ static void g_binary_content_dispose(GBinContent *);
/* Procède à la libération totale de la mémoire. */
static void g_binary_content_finalize(GBinContent *);
+/* Retrouve la zone adaptée pour une localisation de données. */
+static const binary_part *g_binary_content_find_part(const GBinContent *, const vmpa2t *, phys_t *);
+
/* Indique le type défini par la GLib pour les contenus de données. */
@@ -239,10 +246,43 @@ GBinContent *g_binary_content_new_from_file(const char *filename)
}
+/******************************************************************************
+* *
+* Paramètres : content = contenu binaire à venir lire. *
+* addr = position de la tête de lecture globale demandée. *
+* start = position de la tête de lecture dans la zone. [OUT] *
+* *
+* Description : Retrouve la zone adaptée pour une localisation de données. *
+* *
+* Retour : Partie trouvée ou NULL en cas d'échec. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+static const binary_part *g_binary_content_find_part(const GBinContent *content, const vmpa2t *addr, phys_t *start)
+{
+ const binary_part *result; /* Trouvaille à retourner */
+ size_t i; /* Boucle de parcours */
+ binary_part *part; /* Zone mémoire manipulée */
+ result = NULL;
+ for (i = 0; i < content->count && result == NULL; i++)
+ {
+ part = &content->parts[i];
+
+ if (mrange_contains_addr(&part->range, addr))
+ result = part;
+
+ }
+ if (result != NULL)
+ *start = compute_vmpa_diff(get_mrange_addr(&result->range), addr);
+
+ return result;
+
+}
/******************************************************************************
@@ -260,19 +300,367 @@ GBinContent *g_binary_content_new_from_file(const char *filename)
* *
******************************************************************************/
-bool g_binary_content_get_raw(const GBinContent *content, const vmpa2t *addr, phys_t length, bin_t *out)
+bool g_binary_content_get_raw(const GBinContent *content, vmpa2t *addr, phys_t length, bin_t *out)
{
+ bool result;
+ phys_t offset;
+
/* FIXME */
- memcpy(out, &content->parts[0].data[get_phy_addr(addr)], length);
+ offset = get_phy_addr(addr);
+
+ memcpy(out, &content->parts[0].data[offset], length);
+
+ advance_vmpa(addr, length);
+
+ return true;
+
+}
+
+
+
+
+
+
+
+/******************************************************************************
+* *
+* Paramètres : content = contenu binaire à venir lire. *
+* addr = position de la tête de lecture. *
+* low = position éventuelle des 4 bits visés. [OUT] *
+* endian = ordre des bits dans la source. *
+* val = lieu d'enregistrement de la lecture. [OUT] *
+* *
+* Description : Lit un nombre non signé sur quatre bits. *
+* *
+* Retour : Bilan de l'opération : true en cas de succès, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool g_binary_content_read_u4(const GBinContent *content, vmpa2t *addr, bool *low, SourceEndian endian, uint8_t *val)
+{
+ phys_t start; /* Tête de lecture relative */
+ const binary_part *part; /* Zone de mémoire effective */
+ bin_t *data; /* Contenu binaire représenté */
+
+ part = g_binary_content_find_part(content, addr, &start);
+ if (part == NULL) return false;
+
+ if ((get_mrange_length(&part->range) - start) < 1) return false;
+
+ data = part->data;
+
+ if (*low)
+ {
+ *val = data[start] & 0x0f;
+ *low = false;
+ }
+ else
+ {
+ *val = (data[start] & 0xf0) >> 4;
+ *low = true;
+ advance_vmpa(addr, 4);
+ }
+
+ return true;
+
+}
+
+
+
+/******************************************************************************
+* *
+* Paramètres : content = contenu binaire à venir lire. *
+* addr = position de la tête de lecture. *
+* endian = ordre des bits dans la source. *
+* val = lieu d'enregistrement de la lecture. [OUT] *
+* *
+* Description : Lit un nombre non signé sur un octet. *
+* *
+* Retour : Bilan de l'opération : true en cas de succès, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool g_binary_content_read_u8(const GBinContent *content, vmpa2t *addr, SourceEndian endian, uint8_t *val)
+{
+ phys_t start; /* Tête de lecture relative */
+ const binary_part *part; /* Zone de mémoire effective */
+ bin_t *data; /* Contenu binaire représenté */
+
+ part = g_binary_content_find_part(content, addr, &start);
+ if (part == NULL) return false;
+
+ if ((get_mrange_length(&part->range) - start) < 1) return false;
+
+ data = part->data;
+
+ *val = data[start];
+
+ advance_vmpa(addr, 1);
+
+ return true;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : content = contenu binaire à venir lire. *
+* addr = position de la tête de lecture. *
+* endian = ordre des bits dans la source. *
+* val = lieu d'enregistrement de la lecture. [OUT] *
+* *
+* Description : Lit un nombre non signé sur deux octets. *
+* *
+* Retour : Bilan de l'opération : true en cas de succès, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool g_binary_content_read_u16(const GBinContent *content, vmpa2t *addr, SourceEndian endian, uint16_t *val)
+{
+ phys_t start; /* Tête de lecture relative */
+ const binary_part *part; /* Zone de mémoire effective */
+ bin_t *data; /* Contenu binaire représenté */
+
+ part = g_binary_content_find_part(content, addr, &start);
+ if (part == NULL) return false;
+
+ if ((get_mrange_length(&part->range) - start) < 2) return false;
+
+ data = part->data;
+
+ switch (endian)
+ {
+ case SRE_LITTLE:
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+
+ *val = data[start] | (uint16_t)data[start + 1] << 8;
+
+#elif __BYTE_ORDER == __BIG_ENDIAN
+
+ *val = data[start + 1] | (uint16_t)data[start] << 8;
+
+#else
+
+# error "TODO : extra byte order !"
+
+#endif
+
+ break;
+
+ case SRE_MIDDLE:
+ assert(false); /* TODO */
+ break;
+
+ case SRE_BIG:
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+
+ *val = data[start + 1] | (uint16_t)data[start] << 8;
+
+#elif __BYTE_ORDER == __BIG_ENDIAN
+
+ *val = data[start] | (uint16_t)data[start + 1] << 8;
+
+#else
+
+# error "TODO : extra byte order !"
+
+#endif
+
+ break;
+
+
+ }
+
+ advance_vmpa(addr, 2);
+
+ return true;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : content = contenu binaire à venir lire. *
+* addr = position de la tête de lecture. *
+* endian = ordre des bits dans la source. *
+* val = lieu d'enregistrement de la lecture. [OUT] *
+* *
+* Description : Lit un nombre non signé sur quatre octets. *
+* *
+* Retour : Bilan de l'opération : true en cas de succès, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool g_binary_content_read_u32(const GBinContent *content, vmpa2t *addr, SourceEndian endian, uint32_t *val)
+{
+ phys_t start; /* Tête de lecture relative */
+ const binary_part *part; /* Zone de mémoire effective */
+ bin_t *data; /* Contenu binaire représenté */
+
+ part = g_binary_content_find_part(content, addr, &start);
+ if (part == NULL) return false;
+
+ if ((get_mrange_length(&part->range) - start) < 4) return false;
+
+ data = part->data;
+
+ switch (endian)
+ {
+ case SRE_LITTLE:
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+
+ *val = data[start] | (uint32_t)data[start + 1] << 8;
+ *val |= data[start + 2] << 16 | (uint32_t)data[start + 3] << 24;
+
+#elif __BYTE_ORDER == __BIG_ENDIAN
+
+ *val = data[start + 3] | (uint32_t)data[start + 2] << 8;
+ *val |= data[start + 1] << 16 | (uint32_t)data[start] << 24;
+
+#else
+
+# error "TODO : extra byte order !"
+
+#endif
+
+ break;
+
+ case SRE_MIDDLE:
+ assert(false); /* TODO */
+ break;
+
+ case SRE_BIG:
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+
+ *val = data[start + 3] | (uint32_t)data[start + 2] << 8;
+ *val |= data[start + 1] << 16 | (uint32_t)data[start] << 24;
+
+#elif __BYTE_ORDER == __BIG_ENDIAN
+
+ *val = data[start] | (uint32_t)data[start + 1] << 8;
+ *val |= data[start + 2] << 16 | (uint32_t)data[start + 3] << 24;
+
+#else
+
+# error "TODO : extra byte order !"
+
+#endif
+
+ break;
+
+
+ }
+
+ advance_vmpa(addr, 4);
return true;
}
+/******************************************************************************
+* *
+* Paramètres : content = contenu binaire à venir lire. *
+* addr = position de la tête de lecture. *
+* endian = ordre des bits dans la source. *
+* val = lieu d'enregistrement de la lecture. [OUT] *
+* *
+* Description : Lit un nombre non signé sur huit octets. *
+* *
+* Retour : Bilan de l'opération : true en cas de succès, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool g_binary_content_read_u64(const GBinContent *content, vmpa2t *addr, SourceEndian endian, uint64_t *val)
+{
+ phys_t start; /* Tête de lecture relative */
+ const binary_part *part; /* Zone de mémoire effective */
+ bin_t *data; /* Contenu binaire représenté */
+
+ part = g_binary_content_find_part(content, addr, &start);
+ if (part == NULL) return false;
+
+ if ((get_mrange_length(&part->range) - start) < 8) return false;
+ data = part->data;
+ switch (endian)
+ {
+ case SRE_LITTLE:
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+
+ *val = (uint64_t)data[start] | (uint64_t)data[start + 1] << 8;
+ *val |= (uint64_t)data[start + 2] << 16 | (uint64_t)data[start + 3] << 24;
+ *val |= (uint64_t)data[start + 4] << 32 | (uint64_t)data[start + 5] << 40;
+ *val |= (uint64_t)data[start + 6] << 48 | (uint64_t)data[start + 7] << 56;
+
+#elif __BYTE_ORDER == __BIG_ENDIAN
+
+ *val = (uint64_t)data[start + 7] | (uint64_t)data[start + 6] << 8;
+ *val |= (uint64_t)data[start + 5] << 16 | (uint64_t)data[start + 4] << 24;
+ *val |= (uint64_t)data[start + 3] << 32 | (uint64_t)data[start + 2] << 40;
+ *val |= (uint64_t)data[start + 1] << 48 | (uint64_t)data[start] << 56;
+
+#else
+
+# error "TODO : extra byte order !"
+
+#endif
+
+ break;
+
+ case SRE_MIDDLE:
+ assert(false); /* TODO */
+ break;
+
+ case SRE_BIG:
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+
+ *val = (uint64_t)data[start + 7] | (uint64_t)data[start + 6] << 8;
+ *val |= (uint64_t)data[start + 5] << 16 | (uint64_t)data[start + 4] << 24;
+ *val |= (uint64_t)data[start + 3] << 32 | (uint64_t)data[start + 2] << 40;
+ *val |= (uint64_t)data[start + 1] << 48 | (uint64_t)data[start] << 56;
+
+#elif __BYTE_ORDER == __BIG_ENDIAN
+
+ *val = (uint64_t)data[start] | (uint64_t)data[start + 1] << 8;
+ *val |= (uint64_t)data[start + 2] << 16 | (uint64_t)data[start + 3] << 24;
+ *val |= (uint64_t)data[start + 4] << 32 | (uint64_t)data[start + 5] << 40;
+ *val |= (uint64_t)data[start + 6] << 48 | (uint64_t)data[start + 7] << 56;
+
+#else
+
+# error "TODO : extra byte order !"
+
+#endif
+
+ break;
+
+
+ }
+
+ advance_vmpa(addr, 8);
+
+ return true;
+
+}
diff --git a/src/glibext/gbincontent.h b/src/glibext/gbincontent.h
index 1bfcfa5..e2f5933 100644
--- a/src/glibext/gbincontent.h
+++ b/src/glibext/gbincontent.h
@@ -59,10 +59,33 @@ GBinContent *g_binary_content_new_from_file(const char *);
/* Fournit une portion des données représentées. */
-bool g_binary_content_get_raw(const GBinContent *, const vmpa2t *, phys_t, bin_t *);
+bool g_binary_content_get_raw(const GBinContent *, vmpa2t *, phys_t, bin_t *);
+/* Lit un nombre non signé sur quatre bits. */
+bool g_binary_content_read_u4(const GBinContent *, vmpa2t *, bool *, SourceEndian, uint8_t *);
+
+/* Lit un nombre non signé sur un octet. */
+bool g_binary_content_read_u8(const GBinContent *, vmpa2t *, SourceEndian, uint8_t *);
+
+/* Lit un nombre non signé sur deux octets. */
+bool g_binary_content_read_u16(const GBinContent *, vmpa2t *, SourceEndian, uint16_t *);
+
+/* Lit un nombre non signé sur quatre octets. */
+bool g_binary_content_read_u32(const GBinContent *, vmpa2t *, SourceEndian, uint32_t *);
+
+/* Lit un nombre non signé sur huit octets. */
+bool g_binary_content_read_u64(const GBinContent *, vmpa2t *, SourceEndian, uint64_t *);
+
+
+#define g_binary_content_read_s4(c, a, l, e, v) g_binary_content_read_u4(c, a, l, e, (uint8_t *)v)
+#define g_binary_content_read_s8(c, a, e, v) g_binary_content_read_u8(c, a, e, (uint8_t *)v)
+#define g_binary_content_read_s16(c, a, e, v) g_binary_content_read_u16(c, a, e, (uint16_t *)v)
+#define g_binary_content_read_s32(c, a, e, v) g_binary_content_read_u32(c, a, e, (uint32_t *)v)
+#define g_binary_content_read_s64(c, a, e, v) g_binary_content_read_u64(c, a, e, (uint64_t *)v)
+
+
const bin_t *g_binary_content_get(GBinContent *content, off_t *length);