From b3efd0bbc506e701ea9872f50b8b4db974f35954 Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Mon, 5 Dec 2016 00:09:45 +0100
Subject: Read ELF notes when requested.

---
 ChangeLog                | 14 ++++++++++++
 src/arch/vmpa.c          | 28 ++++++++++++++++++++++++
 src/arch/vmpa.h          |  3 +++
 src/format/elf/elf-int.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++
 src/format/elf/elf-int.h |  3 +++
 src/format/elf/elf_def.h | 25 ++++++++++++++++++++-
 src/plugins/pglist.c     |  2 +-
 7 files changed, 129 insertions(+), 2 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 1c9fa76..a89b57f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+16-12-05  Cyrille Bagard <nocbos@gmail.com>
+
+	* src/arch/vmpa.c:
+	* src/arch/vmpa.h:
+	Provide a function to align positions.
+
+	* src/format/elf/elf-int.c:
+	* src/format/elf/elf-int.h:
+	* src/format/elf/elf_def.h:
+	Read ELF notes when requested.
+
+	* src/plugins/pglist.c:
+	Use a generic directories separator.
+
 16-11-28  Cyrille Bagard <nocbos@gmail.com>
 
 	* configure.ac:
diff --git a/src/arch/vmpa.c b/src/arch/vmpa.c
index fe159f6..8f550fe 100644
--- a/src/arch/vmpa.c
+++ b/src/arch/vmpa.c
@@ -281,6 +281,34 @@ void deminish_vmpa(vmpa2t *addr, phys_t qty)
 
 /******************************************************************************
 *                                                                             *
+*  Paramètres  : addr  = élément à modifier.                                  *
+*                bytes = nombre d'octets sur lequel aligner la position.      *
+*                                                                             *
+*  Description : Aligne une localisation sur un nombre d'octets donné.        *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void align_vmpa(vmpa2t *addr, phys_t bytes)
+{
+    if (bytes > 1)
+    {
+        if (addr->physical != VMPA_NO_PHYSICAL)
+            addr->physical = (addr->physical + bytes - 1) & ~(bytes - 1);
+
+        if (addr->virtual != VMPA_NO_VIRTUAL)
+            addr->virtual = (addr->virtual + bytes - 1) & ~(bytes - 1);
+
+    }
+
+}
+
+
+/******************************************************************************
+*                                                                             *
 *  Paramètres  : a = première élément à venir consulter.                      *
 *                b = second élément à traiter en parallèle.                   *
 *                                                                             *
diff --git a/src/arch/vmpa.h b/src/arch/vmpa.h
index 695e21e..1e17f17 100644
--- a/src/arch/vmpa.h
+++ b/src/arch/vmpa.h
@@ -113,6 +113,9 @@ void advance_vmpa(vmpa2t *, phys_t);
 /* Décalle une position d'une certaine quantité. */
 void deminish_vmpa(vmpa2t *, phys_t);
 
+/* Aligne une localisation sur un nombre d'octets donné. */
+void align_vmpa(vmpa2t *, phys_t);
+
 /* Calcule au mieux la distance entre deux coordonnées. */
 phys_t compute_vmpa_diff(const vmpa2t *, const vmpa2t *);
 
diff --git a/src/format/elf/elf-int.c b/src/format/elf/elf-int.c
index e3333c4..97a3ffa 100644
--- a/src/format/elf/elf-int.c
+++ b/src/format/elf/elf-int.c
@@ -373,3 +373,59 @@ bool read_elf_relocation(const GElfFormat *format, phys_t *phys, elf_rel *reloc)
     return result;
 
 }
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : format = informations chargées à consulter.                  *
+*                content = contenu binaire mis à disposition ou NULL.         *
+*                pos    = position de début de lecture. [OUT]                 *
+*                note   = structure lue à retourner. [OUT]                    *
+*                                                                             *
+*  Description : Procède à la lecture d'une note ELF.                         *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool read_elf_note(const GElfFormat *format, GBinContent *content, phys_t *phys, elf_note *note)
+{
+    bool result;                            /* Bilan à retourner           */
+    vmpa2t pos;                             /* Position de lecture         */
+
+    if (content == NULL)
+        content = G_BIN_FORMAT(format)->content;
+
+    init_vmpa(&pos, *phys, VMPA_NO_VIRTUAL);
+
+    result = g_binary_content_read_u32(content, &pos, format->endian, &note->namesz);
+    result &= g_binary_content_read_u32(content, &pos, format->endian, &note->descsz);
+    result &= g_binary_content_read_u32(content, &pos, format->endian, &note->type);
+
+    if (result && note->namesz > 0)
+    {
+        align_vmpa(&pos, 4);
+
+        note->name = (const char *)g_binary_content_get_raw_access(content, &pos, note->namesz);
+
+        result &= (note->name != NULL);
+
+    }
+    else note->name = NULL;
+
+    if (result && note->descsz > 0)
+    {
+        align_vmpa(&pos, 4);
+
+        note->desc = (const void *)g_binary_content_get_raw_access(content, &pos, note->descsz);
+
+        result &= (note->desc != NULL);
+
+    }
+    else note->desc = NULL;
+
+    return result;
+
+}
diff --git a/src/format/elf/elf-int.h b/src/format/elf/elf-int.h
index 0382e29..7ed2ffd 100644
--- a/src/format/elf/elf-int.h
+++ b/src/format/elf/elf-int.h
@@ -70,6 +70,9 @@ bool read_elf_symbol(const GElfFormat *, phys_t *, elf_sym *);
 /* Procède à la lecture d'une relocalisation ELF. */
 bool read_elf_relocation(const GElfFormat *, phys_t *, elf_rel *);
 
+/* Procède à la lecture d'une note ELF. */
+bool read_elf_note(const GElfFormat *, GBinContent *, phys_t *, elf_note *);
+
 
 
 #endif  /* _FORMAT_ELF_ELF_INT_H */
diff --git a/src/format/elf/elf_def.h b/src/format/elf/elf_def.h
index 04e3bcc..e29ec03 100644
--- a/src/format/elf/elf_def.h
+++ b/src/format/elf/elf_def.h
@@ -605,7 +605,30 @@ typedef union _elf_rel
 
 /* Type de relocalisation (ARM) */
 
-#define R_ARM_JUMP_SLOT         22      /* Create PLT entry */
+#define R_ARM_JUMP_SLOT         22          /* Create PLT entry */
+
+
+
+/* --------------------------- NOTES ARBITRAIRES LAISSEES --------------------------- */
+
+
+/**
+ * Notes contenues dans un fichier ELF.
+ * Se rapporter au chapitre 5, partie "Note Section", des spécifications ABI
+ * du Système V pour d'avantage d'informations.
+ */
+
+typedef struct _elf_note
+{
+    uint32_t namesz;                        /* Taille du nom éventuel      */
+    uint32_t descsz;                        /* Qté de données éventuelles  */
+    uint32_t type;                          /* Indication supplémentaire   */
+
+    const char *name;                       /* Auteur de la note           */
+    const void *desc;                       /* Données complémentaires     */
+
+} elf_note;
+
 
 
 #endif  /* _FORMAT_ELF_ELF_DEF_H */
diff --git a/src/plugins/pglist.c b/src/plugins/pglist.c
index 0b478eb..93721b6 100644
--- a/src/plugins/pglist.c
+++ b/src/plugins/pglist.c
@@ -189,7 +189,7 @@ void browse_directory_for_plugins(plugins_list *list, const char *dir)
         filename = (char *)calloc(strlen(dir) + 1 + strlen(namelist[ret]->d_name) + 1, sizeof(char));
 
         strcpy(filename, dir);
-        strcat(filename, "/");    /* FIXME : Win */
+        strcat(filename, G_DIR_SEPARATOR_S);
         strcat(filename, namelist[ret]->d_name);
 
         if (namelist[ret]->d_type == DT_DIR)
-- 
cgit v0.11.2-87-g4458