summaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2025-03-12 23:53:26 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2025-03-12 23:53:52 (GMT)
commitccb49530f930701b1ca57e560564ae098dcef3c9 (patch)
treedc4abbca57f6838ac764b545181d01a66e6521f4 /src/common
parent04d5af777d42d02d0ec580373f7a50be1bfb3dac (diff)
Update and improve the operations with LEB128 values.
Diffstat (limited to 'src/common')
-rw-r--r--src/common/bits.c1
-rw-r--r--src/common/leb128.c171
-rw-r--r--src/common/leb128.h11
3 files changed, 137 insertions, 46 deletions
diff --git a/src/common/bits.c b/src/common/bits.c
index 26f570f..27296f2 100644
--- a/src/common/bits.c
+++ b/src/common/bits.c
@@ -31,6 +31,7 @@
#include "asm.h"
+#include "io.h"
#include "leb128.h"
diff --git a/src/common/leb128.c b/src/common/leb128.c
index 009aff6..7fae4d0 100644
--- a/src/common/leb128.c
+++ b/src/common/leb128.c
@@ -24,9 +24,20 @@
#include "leb128.h"
+#include <malloc.h>
+
+
#include "io.h"
+/**
+ * Quantité maximale d'octets de représentation.
+ *
+ * sizeof([u]leb128_t) / 7 = 9.142857142857142
+ *
+ */
+#define MAX_LEB128_BYTES 9
+
/******************************************************************************
* *
@@ -133,7 +144,7 @@ bool load_uleb128(uleb128_t *value, int fd)
unsigned int shift; /* Décalage à appliquer */
uint8_t byte; /* Octet à transposer */
- result = true;
+ result = false;
*value = 0;
@@ -142,7 +153,7 @@ bool load_uleb128(uleb128_t *value, int fd)
while (true)
{
/* Encodage sur trop d'octets ? */
- if (shift > (7 * sizeof(uleb128_t)))
+ if (shift > (7 * MAX_LEB128_BYTES))
{
result = false;
break;
@@ -153,6 +164,8 @@ bool load_uleb128(uleb128_t *value, int fd)
*value |= ((byte & 0x7f) << shift);
+ result = true;
+
if ((byte & 0x80) == 0x00)
break;
@@ -207,7 +220,7 @@ bool store_uleb128(const uleb128_t *value, int fd)
/******************************************************************************
* *
* Paramètres : value = valeur à consigner. *
-* pbuf = tampon de données à constituer. [OUT] *
+* len = taille du tampon de données à constitué. [OUT] *
* *
* Description : Encode un nombre non signé encodé au format LEB128. *
* *
@@ -217,26 +230,44 @@ bool store_uleb128(const uleb128_t *value, int fd)
* *
******************************************************************************/
-bool pack_uleb128(const uleb128_t *value, packed_buffer_t *pbuf)
+void *pack_uleb128(const uleb128_t *value, size_t *len)
{
- bool result; /* Bilan à retourner */
+ uint8_t *result; /* Données à retourner */
uleb128_t tmp; /* Valeur modifiable */
- uint8_t byte; /* Octet à transposer */
+ uint8_t *byte; /* Octet à transposer */
+
+ /* Calcul de la quantité d'octets nécessaires */
+
+ *len = 0;
tmp = *value;
do
{
- byte = (tmp & 0x7f);
+ tmp >>= 7;
+ (*len)++;
+ }
+ while (tmp != 0);
+
+ /* Exportation */
+
+ result = malloc(*len * sizeof(uint8_t));
+ byte = result;
+
+ tmp = *value;
+
+ do
+ {
+ *byte = (tmp & 0x7f);
tmp >>= 7;
if (tmp != 0)
- byte |= 0x80;
+ *byte |= 0x80;
- result = extend_packed_buffer(pbuf, &byte, sizeof(uint8_t), false);
+ byte++;
}
- while (result && tmp != 0);
+ while (tmp != 0);
return result;
@@ -246,7 +277,7 @@ bool pack_uleb128(const uleb128_t *value, packed_buffer_t *pbuf)
/******************************************************************************
* *
* Paramètres : value = valeur à consigner. *
-* pbuf = tampon de données à constituer. [OUT] *
+* len = taille du tampon de données à constitué. [OUT] *
* *
* Description : Encode un nombre signé encodé au format LEB128. *
* *
@@ -256,19 +287,24 @@ bool pack_uleb128(const uleb128_t *value, packed_buffer_t *pbuf)
* *
******************************************************************************/
-bool pack_leb128(const leb128_t *value, packed_buffer_t *pbuf)
+void *pack_leb128(const leb128_t *value, size_t *len)
{
-
- bool result; /* Bilan à retourner */
+ uint8_t *result; /* Données à retourner */
+ bool negative; /* Nature de la valeur */
uleb128_t tmp; /* Valeur modifiable */
bool more; /* Poursuite des traitements */
- bool negative; /* Nature de la valeur */
uint8_t byte; /* Octet à transposer */
+ uint8_t *iter; /* Boucle de parcours */
+
+ negative = (*value < 0);
+
+ /* Calcul de la quantité d'octets nécessaires */
+
+ *len = 0;
tmp = *value;
more = true;
- negative = (*value < 0);
while (more)
{
@@ -291,10 +327,44 @@ bool pack_leb128(const leb128_t *value, packed_buffer_t *pbuf)
if ((tmp == 0 && (byte & 0x40) == 0x00) || (tmp == -1 && (byte & 0x40) == 0x40))
more = false;
+ (*len)++;
+
+ }
+
+ /* Exportation */
+
+ result = malloc(*len * sizeof(uint8_t));
+ iter = result;
+
+ tmp = *value;
+
+ more = true;
+
+ while (more)
+ {
+ *iter = (tmp & 0x7f);
+ tmp >>= 7;
+
+ /**
+ * Propagation forcée du bit de signe pour les implémentations de
+ * décalage basées sur une opération logique et non arithmétique.
+ */
+
+ if (negative)
+ tmp |= (~0llu << (LEB128_BITS_COUNT - 7));
+
+ /**
+ * Le bit de signe n'est pas le bit de poids fort ici :
+ * On travaille sur 7 bits, donc le masque est 0x40 !
+ */
+
+ if ((tmp == 0 && (*iter & 0x40) == 0x00) || (tmp == -1 && (*iter & 0x40) == 0x40))
+ more = false;
+
else
- byte |= 0x80;
+ *iter |= 0x80;
- result = extend_packed_buffer(pbuf, &byte, sizeof(uint8_t), false);
+ iter++;
}
@@ -306,7 +376,8 @@ bool pack_leb128(const leb128_t *value, packed_buffer_t *pbuf)
/******************************************************************************
* *
* Paramètres : value = valeur à constituer. [OUT] *
-* pbuf = tampon de données à consulter. *
+* pos = tête de lecture à faire évoluer. [OUT] *
+* max = position maximale liée à la fin des données. *
* *
* Description : Décode un nombre non signé encodé au format LEB128. *
* *
@@ -316,38 +387,45 @@ bool pack_leb128(const leb128_t *value, packed_buffer_t *pbuf)
* *
******************************************************************************/
-bool unpack_uleb128(uleb128_t *value, packed_buffer_t *pbuf)
+bool unpack_uleb128(uleb128_t *value, const void **pos, const void *max)
{
bool result; /* Bilan à retourner */
unsigned int shift; /* Décalage à appliquer */
- uint8_t byte; /* Octet à transposer */
+ uint8_t *byte; /* Octet à transposer */
- result = true;
+ result = false;
*value = 0;
shift = 0;
+ byte = *(uint8_t **)pos;
- while (true)
+ do
{
/* Encodage sur trop d'octets ? */
- if (shift > (7 * sizeof(uleb128_t)))
+ if (shift > (7 * MAX_LEB128_BYTES))
{
result = false;
break;
}
- result = extract_packed_buffer(pbuf, &byte, sizeof(uint8_t), false);
- if (!result) break;
+ /* Atteinte de la fin des données ? */
+ if ((void *)byte >= max)
+ {
+ result = false;
+ break;
+ }
- *value |= ((byte & 0x7f) << shift);
+ *value |= ((*byte & 0x7f) << shift);
- if ((byte & 0x80) == 0x00)
- break;
+ result = true;
shift += 7;
}
+ while ((*byte++ & 0x80) == 0x80);
+
+ *pos = byte;
return result;
@@ -357,7 +435,8 @@ bool unpack_uleb128(uleb128_t *value, packed_buffer_t *pbuf)
/******************************************************************************
* *
* Paramètres : value = valeur à constituer. [OUT] *
-* pbuf = tampon de données à consulter. *
+* pos = tête de lecture à faire évoluer. [OUT] *
+* max = position maximale liée à la fin des données. *
* *
* Description : Décode un nombre signé encodé au format LEB128. *
* *
@@ -367,44 +446,56 @@ bool unpack_uleb128(uleb128_t *value, packed_buffer_t *pbuf)
* *
******************************************************************************/
-bool unpack_leb128(leb128_t *value, packed_buffer_t *pbuf)
+bool unpack_leb128(leb128_t *value, const void **pos, const void *max)
{
bool result; /* Bilan à retourner */
unsigned int shift; /* Décalage à appliquer */
- uint8_t byte; /* Octet à transposer */
+ uint8_t *byte; /* Octet à transposer */
- result = true;
+ result = false;
*value = 0;
shift = 0;
+ byte = *(uint8_t **)pos;
do
{
/* Encodage sur trop d'octets ? */
- if (shift > (7 * sizeof(leb128_t)))
+ if (shift > (7 * MAX_LEB128_BYTES))
{
result = false;
break;
}
- result = extract_packed_buffer(pbuf, &byte, sizeof(uint8_t), false);
- if (!result) break;
+ /* Atteinte de la fin des données ? */
+ if ((void *)byte >= max)
+ {
+ result = false;
+ break;
+ }
- *value |= ((byte & 0x7f) << shift);
+ *value |= ((*byte & 0x7f) << shift);
+
+ result = true;
shift += 7;
}
- while ((byte & 0x80) == 0x80);
+ while ((*byte++ & 0x80) == 0x80);
/**
* Le bit de signe n'est pas le bit de poids fort ici :
* On travaille sur 7 bits, donc le masque est 0x40 !
*/
- if (shift < LEB128_BITS_COUNT && (byte & 0x40) == 0x40)
- *value |= (~0llu << shift);
+ if (result)
+ {
+ if (shift < LEB128_BITS_COUNT && (byte[-1] & 0x40) == 0x40)
+ *value |= (~0llu << shift);
+ }
+
+ *pos = byte;
return result;
diff --git a/src/common/leb128.h b/src/common/leb128.h
index 0313f5c..cb712a3 100644
--- a/src/common/leb128.h
+++ b/src/common/leb128.h
@@ -30,7 +30,6 @@
#include "datatypes.h"
-#include "packed.h"
@@ -65,16 +64,16 @@ bool load_uleb128(uleb128_t *, int);
bool store_uleb128(const uleb128_t *, int);
/* Encode un nombre non signé encodé au format LEB128. */
-bool pack_uleb128(const uleb128_t *, packed_buffer_t *);
+void *pack_uleb128(const uleb128_t *, size_t *);
/* Encode un nombre signé encodé au format LEB128. */
-bool pack_leb128(const leb128_t *, packed_buffer_t *);
+void *pack_leb128(const leb128_t *, size_t *);
-/* Décode un nombre non signé encodé au format LEB128. */
-bool unpack_uleb128(uleb128_t *, packed_buffer_t *);
+/* Encode un nombre non signé encodé au format LEB128. */
+bool unpack_uleb128(uleb128_t *, const void **, const void *);
/* Décode un nombre signé encodé au format LEB128. */
-bool unpack_leb128(leb128_t *, packed_buffer_t *);
+bool unpack_leb128(leb128_t *, const void **, const void *);