|
[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
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |