[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH v1 06/11] xsplice: Add helper elf routines



Add some elf routines and data structures in preparation for loading an
xsplice payload.

Signed-off-by: Ross Lagerwall <ross.lagerwall@xxxxxxxxxx>
---
 xen/common/Makefile           |   1 +
 xen/common/xsplice_elf.c      | 122 ++++++++++++++++++++++++++++++++++++++++++
 xen/include/xen/xsplice_elf.h |  44 +++++++++++++++
 3 files changed, 167 insertions(+)
 create mode 100644 xen/common/xsplice_elf.c
 create mode 100644 xen/include/xen/xsplice_elf.h

diff --git a/xen/common/Makefile b/xen/common/Makefile
index 1b17c9d..de7c08a 100644
--- a/xen/common/Makefile
+++ b/xen/common/Makefile
@@ -57,6 +57,7 @@ obj-y += vsprintf.o
 obj-y += wait.o
 obj-y += xmalloc_tlsf.o
 obj-y += xsplice.o
+obj-y += xsplice_elf.o
 
 obj-bin-$(CONFIG_X86) += $(foreach n,decompress bunzip2 unxz unlzma unlzo 
unlz4 earlycpio,$(n).init.o)
 
diff --git a/xen/common/xsplice_elf.c b/xen/common/xsplice_elf.c
new file mode 100644
index 0000000..13a9229
--- /dev/null
+++ b/xen/common/xsplice_elf.c
@@ -0,0 +1,122 @@
+#include <xen/lib.h>
+#include <xen/errno.h>
+#include <xen/xsplice_elf.h>
+
+struct xsplice_elf_sec *xsplice_elf_sec_by_name(const struct xsplice_elf *elf,
+                                                const char *name)
+{
+    int i;
+
+    for ( i = 0; i < elf->hdr->e_shnum; i++ )
+    {
+        if ( !strcmp(name, elf->sec[i].name) )
+            return &elf->sec[i];
+    }
+
+    return NULL;
+}
+
+static int elf_get_sections(struct xsplice_elf *elf, uint8_t *data)
+{
+    struct xsplice_elf_sec *sec;
+    int i;
+
+    sec = xmalloc_array(struct xsplice_elf_sec, elf->hdr->e_shnum);
+    if ( !sec )
+    {
+        printk(XENLOG_ERR "Could not find section table\n");
+        return -ENOMEM;
+    }
+
+    for ( i = 0; i < elf->hdr->e_shnum; i++ )
+    {
+#ifdef CONFIG_ARM_32
+        sec[i].sec = (Elf32_Shdr *)(data + elf->hdr->e_shoff +
+                                    i * elf->hdr->e_shentsize);
+#else
+        sec[i].sec = (Elf64_Shdr *)(data + elf->hdr->e_shoff +
+                                    i * elf->hdr->e_shentsize);
+#endif
+        sec[i].data = data + sec[i].sec->sh_offset;
+    }
+    elf->sec = sec;
+
+    return 0;
+}
+
+static int elf_get_sym(struct xsplice_elf *elf, uint8_t *data)
+{
+    struct xsplice_elf_sec *symtab, *strtab_sec;
+    struct xsplice_elf_sym *sym;
+    const char *strtab;
+    int i;
+
+    symtab = xsplice_elf_sec_by_name(elf, ".symtab");
+    if ( !symtab )
+    {
+        printk(XENLOG_ERR "Could not find symbol table\n");
+        return -EINVAL;
+    }
+
+    strtab_sec = xsplice_elf_sec_by_name(elf, ".strtab");
+    if ( !strtab_sec )
+    {
+        printk(XENLOG_ERR "Could not find string table\n");
+        return -EINVAL;
+    }
+    strtab = (const char *)(data + strtab_sec->sec->sh_offset);
+
+    elf->nsym = symtab->sec->sh_size / symtab->sec->sh_entsize;
+
+    sym = xmalloc_array(struct xsplice_elf_sym, elf->nsym);
+    if ( !sym )
+    {
+        printk(XENLOG_ERR "Could not allocate memory for symbols\n");
+        return -ENOMEM;
+    }
+
+    for ( i = 0; i < elf->nsym; i++ )
+    {
+#ifdef CONFIG_ARM_32
+        sym[i].sym = (Elf32_Sym *)(symtab->data + i * symtab->sec->sh_entsize);
+#else
+        sym[i].sym = (Elf64_Sym *)(symtab->data + i * symtab->sec->sh_entsize);
+#endif
+        sym[i].name = strtab + sym[i].sym->st_name;
+    }
+    elf->sym = sym;
+
+    return 0;
+}
+
+int xsplice_elf_load(struct xsplice_elf *elf, uint8_t *data, ssize_t len)
+{
+    const char *shstrtab;
+    int i, rc;
+
+#ifdef CONFIG_ARM_32
+    elf->hdr = (Elf32_Ehdr *)data;
+#else
+    elf->hdr = (Elf64_Ehdr *)data;
+#endif
+
+    rc = elf_get_sections(elf, data);
+    if ( rc )
+        return rc;
+
+    shstrtab = (const char *)(data + 
elf->sec[elf->hdr->e_shstrndx].sec->sh_offset);
+    for ( i = 0; i < elf->hdr->e_shnum; i++ )
+        elf->sec[i].name = shstrtab + elf->sec[i].sec->sh_name;
+
+    rc = elf_get_sym(elf, data);
+    if ( rc )
+        return rc;
+
+    return 0;
+}
+
+void xsplice_elf_free(struct xsplice_elf *elf)
+{
+    xfree(elf->sec);
+    xfree(elf->sym);
+}
diff --git a/xen/include/xen/xsplice_elf.h b/xen/include/xen/xsplice_elf.h
new file mode 100644
index 0000000..bac0053
--- /dev/null
+++ b/xen/include/xen/xsplice_elf.h
@@ -0,0 +1,44 @@
+#ifndef __XEN_XSPLICE_ELF_H__
+#define __XEN_XSPLICE_ELF_H__
+
+#include <xen/types.h>
+#include <xen/elfstructs.h>
+
+/* The following describes an Elf file as consumed by xsplice. */
+struct xsplice_elf_sec {
+#ifdef CONFIG_ARM_32
+    Elf32_Shdr *sec;
+#else
+    Elf64_Shdr *sec;
+#endif
+    const char *name;
+    const uint8_t *data;           /* A pointer to the data section */
+    uint8_t *load_addr;            /* A pointer to the allocated destination */
+};
+
+struct xsplice_elf_sym {
+#ifdef CONFIG_ARM_32
+    Elf32_Sym *sym;
+#else
+    Elf64_Sym *sym;
+#endif
+    const char *name;
+};
+
+struct xsplice_elf {
+#ifdef CONFIG_ARM_32
+    Elf32_Ehdr *hdr;
+#else
+    Elf64_Ehdr *hdr;
+#endif
+    struct xsplice_elf_sec *sec;   /* Array of sections */
+    struct xsplice_elf_sym *sym;   /* Array of symbols */
+    int nsym;
+};
+
+struct xsplice_elf_sec *xsplice_elf_sec_by_name(const struct xsplice_elf *elf,
+                                                const char *name);
+int xsplice_elf_load(struct xsplice_elf *elf, uint8_t *data, ssize_t len);
+void xsplice_elf_free(struct xsplice_elf *elf);
+
+#endif /* __XEN_XSPLICE_ELF_H__ */
-- 
2.4.3


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.