summaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
Diffstat (limited to 'src/common')
-rwxr-xr-xsrc/common/Makefile.am1
-rwxr-xr-xsrc/common/endianness.c34
-rwxr-xr-xsrc/common/endianness.h5
-rw-r--r--src/common/leb128.c111
-rw-r--r--src/common/leb128.h49
5 files changed, 199 insertions, 1 deletions
diff --git a/src/common/Makefile.am b/src/common/Makefile.am
index 7aa255e..f8e4f20 100755
--- a/src/common/Makefile.am
+++ b/src/common/Makefile.am
@@ -6,6 +6,7 @@ libcommon_la_SOURCES = \
endianness.h endianness.c \
environment.h environment.c \
extstr.h extstr.c \
+ leb128.h leb128.c \
macros.h \
xml.h xml.c
diff --git a/src/common/endianness.c b/src/common/endianness.c
index 32bb65a..5c9b183 100755
--- a/src/common/endianness.c
+++ b/src/common/endianness.c
@@ -25,8 +25,42 @@
+/******************************************************************************
+* *
+* 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. *
+* low = position éventuelle des 4 bits visés. [OUT] *
+* endian = ordre des bits dans la source. *
+* *
+* Description : Lit un nombre non signé sur 4 bits. *
+* *
+* Retour : Bilan de l'opération : true en cas de succès, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool read_u4(uint8_t *target, const bin_t *data, off_t *pos, off_t len, bool *low, SourceEndian endian)
+{
+ if ((len - *pos) < 1) return false;
+
+ if (*low)
+ {
+ *target = data[*pos] & 0x0f;
+ *low = false;
+ }
+ else
+ {
+ *target = (data[*pos] & 0xf0) >> 4;
+ *low = true;
+ *pos += 1;
+ }
+ return true;
+}
/******************************************************************************
diff --git a/src/common/endianness.h b/src/common/endianness.h
index f9d421e..f729ac5 100755
--- a/src/common/endianness.h
+++ b/src/common/endianness.h
@@ -26,7 +26,6 @@
#include <stdbool.h>
-#include <sys/types.h>
#include "../arch/archbase.h"
@@ -43,6 +42,9 @@ typedef enum _SourceEndian
} SourceEndian;
+/* Lit un nombre non signé sur 4 bits. */
+bool read_u4(uint8_t *, const bin_t *, off_t *, off_t, bool *, SourceEndian);
+
/* Lit un nombre non signé sur un octet. */
bool read_u8(uint8_t *, const bin_t *, off_t *, off_t, SourceEndian);
@@ -56,6 +58,7 @@ bool read_u32(uint32_t *, const bin_t *, off_t *, off_t, SourceEndian);
bool read_u64(uint64_t *, const bin_t *, off_t *, off_t, SourceEndian);
+#define read_s4(target, data, pos, len, low, endian) read_u4((uint8_t *)target, data, pos, len, low, endian)
#define read_s8(target, data, pos, len, endian) read_u8((uint8_t *)target, data, pos, len, endian)
#define read_s16(target, data, pos, len, endian) read_u16((uint16_t *)target, data, pos, len, endian)
#define read_s32(target, data, pos, len, endian) read_u32((uint32_t *)target, data, pos, len, endian)
diff --git a/src/common/leb128.c b/src/common/leb128.c
new file mode 100644
index 0000000..4a03797
--- /dev/null
+++ b/src/common/leb128.c
@@ -0,0 +1,111 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * leb128.c - support des valeurs encodées au format LEB128.
+ *
+ * Copyright (C) 2010 Cyrille Bagard
+ *
+ * This file is part of OpenIDA.
+ *
+ * OpenIDA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * OpenIDA is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "leb128.h"
+
+
+
+/******************************************************************************
+* *
+* 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. *
+* *
+* Description : Lit un nombre non signé encodé au format LEB128. *
+* *
+* Retour : Bilan de l'opération : true en cas de succès, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool read_uleb128(uleb128_t *target, const bin_t *data, off_t *pos, off_t len)
+{
+ int shift; /* Décallage à appliquer */
+ off_t i; /* Boucle de parcours */
+
+ shift = 0;
+ *target = 0;
+
+ for (i = 0; i < 8; i++)
+ {
+ /* On évite les débordements... */
+ if (*pos >= len) return false;
+
+ *target |= (data[*pos] & 0x7f) << shift;
+
+ shift += 7;
+ (*pos)++;
+
+ if ((data[*pos - 1] & 0x80) == 0x00) break;
+
+ }
+
+ return (i < 8);
+
+}
+
+
+/******************************************************************************
+* *
+* 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. *
+* *
+* Description : Lit un nombre signé encodé au format LEB128. *
+* *
+* Retour : Bilan de l'opération : true en cas de succès, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool read_leb128(leb128_t *target, const bin_t *data, off_t *pos, off_t len)
+{
+ int shift; /* Décallage à appliquer */
+ off_t i; /* Boucle de parcours */
+
+ shift = 0;
+ *target = 0;
+
+ for (i = 0; i < 8; i++)
+ {
+ /* On évite les débordements... */
+ if (*pos >= len) return false;
+
+ *target |= (data[*pos] & 0x7f) << shift;
+
+ shift += 7;
+
+ if ((data[(*pos)++] & 0x80) == 0x00) break;
+
+ }
+
+ if (shift < (8 * sizeof(int64_t)) && (data[*pos - 1] & 0x40) == 0x40)
+ *target |= - (1 << shift);
+
+ return (i < 8);
+
+}
diff --git a/src/common/leb128.h b/src/common/leb128.h
new file mode 100644
index 0000000..0364cf7
--- /dev/null
+++ b/src/common/leb128.h
@@ -0,0 +1,49 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * leb128.h - prototypes pour le support des valeurs encodées au format LEB128.
+ *
+ * Copyright (C) 2010 Cyrille Bagard
+ *
+ * This file is part of OpenIDA.
+ *
+ * OpenIDA is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * OpenIDA is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Foobar. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _COMMON_LEB128_H
+#define _COMMON_LEB128_H
+
+
+#include <stdbool.h>
+
+
+#include "../arch/archbase.h"
+
+
+
+/* Nouveaux types */
+typedef uint64_t uleb128_t;
+typedef int64_t leb128_t;
+
+
+
+/* Lit un nombre non signé encodé au format LEB128. */
+bool read_uleb128(uleb128_t *, const bin_t *, off_t *, off_t);
+
+/* Lit un nombre signé encodé au format LEB128. */
+bool read_leb128(leb128_t *, const bin_t *, off_t *, off_t);
+
+
+
+#endif /* _COMMON_LEB128_H */