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

[Xen-changelog] [xen-unstable] Merge



# HG changeset patch
# User Tim Deegan <Tim.Deegan@xxxxxxxxxxxxx>
# Date 1186041746 -3600
# Node ID e0b424bc95724904dbf984f8184e3647f54637dd
# Parent  bf85b467ee8963c986997654452911bd82a27edb
# Parent  07364f8574b8fa9cb84d446c83fb13deee24fd81
Merge
---
 tools/xenstore/utils.c             |    7 +-
 tools/xenstore/utils.h             |    2 
 tools/xenstore/xenstored_core.c    |   16 ++---
 xen/arch/x86/domain_build.c        |    7 +-
 xen/common/libelf/libelf-dominfo.c |  101 ++++++++++++++++++++++++++++++++++++-
 xen/common/libelf/libelf-loader.c  |   44 +++++++++++++---
 xen/common/libelf/libelf-tools.c   |   30 ++++++++++
 xen/include/public/libelf.h        |   76 +++++++++++++++------------
 8 files changed, 228 insertions(+), 55 deletions(-)

diff -r bf85b467ee89 -r e0b424bc9572 tools/xenstore/utils.c
--- a/tools/xenstore/utils.c    Thu Aug 02 09:02:08 2007 +0100
+++ b/tools/xenstore/utils.c    Thu Aug 02 09:02:26 2007 +0100
@@ -10,18 +10,17 @@
 #include <signal.h>
 #include "utils.h"
 
-void xprintf(const char *fmt, ...)
+static void default_xprintf(const char *fmt, ...)
 {
        va_list args;
-
-       if (!stderr)
-               return; /* could trace()? */
 
        va_start(args, fmt);
        vfprintf(stderr, fmt, args);
        va_end(args);
        fflush(stderr);
 }
+
+void (*xprintf)(const char *fmt, ...) = default_xprintf;
 
 void barf(const char *fmt, ...)
 {
diff -r bf85b467ee89 -r e0b424bc9572 tools/xenstore/utils.h
--- a/tools/xenstore/utils.h    Thu Aug 02 09:02:08 2007 +0100
+++ b/tools/xenstore/utils.h    Thu Aug 02 09:02:26 2007 +0100
@@ -24,7 +24,7 @@ void barf(const char *fmt, ...) __attrib
 void barf(const char *fmt, ...) __attribute__((noreturn));
 void barf_perror(const char *fmt, ...) __attribute__((noreturn));
 
-void xprintf(const char *fmt, ...);
+void (*xprintf)(const char *fmt, ...);
 
 #define eprintf(_fmt, _args...) xprintf("[ERR] %s" _fmt, __FUNCTION__, ##_args)
 
diff -r bf85b467ee89 -r e0b424bc9572 tools/xenstore/xenstored_core.c
--- a/tools/xenstore/xenstored_core.c   Thu Aug 02 09:02:08 2007 +0100
+++ b/tools/xenstore/xenstored_core.c   Thu Aug 02 09:02:26 2007 +0100
@@ -1880,14 +1880,14 @@ int main(int argc, char *argv[])
 
        /* close stdin/stdout now we're ready to accept connections */
        if (dofork) {
-               close(STDIN_FILENO);
-               close(STDOUT_FILENO);
-               close(STDERR_FILENO);
-
-               /* Get ourselves a nice xenstored crash if these are used. */
-               stdin = NULL;
-               stdout = NULL;
-               stderr = NULL;
+               int devnull = open("/dev/null", O_RDWR);
+               if (devnull == -1)
+                       barf_perror("Could not open /dev/null\n");
+               close(STDIN_FILENO);  dup2(STDIN_FILENO, devnull);
+               close(STDOUT_FILENO); dup2(STDOUT_FILENO, devnull);
+               close(STDERR_FILENO); dup2(STDERR_FILENO, devnull);
+               close(devnull);
+               xprintf = trace;
        }
 
        signal(SIGHUP, trigger_reopen_log);
diff -r bf85b467ee89 -r e0b424bc9572 xen/arch/x86/domain_build.c
--- a/xen/arch/x86/domain_build.c       Thu Aug 02 09:02:08 2007 +0100
+++ b/xen/arch/x86/domain_build.c       Thu Aug 02 09:02:26 2007 +0100
@@ -316,6 +316,9 @@ int __init construct_dom0(
            parms.pae       ? ", PAE"  : "",
            elf_msb(&elf)   ? "msb"    : "lsb",
            elf.pstart, elf.pend);
+    if ( parms.bsd_symtab )
+        printk(" Dom0 symbol map 0x%" PRIx64 " -> 0x%" PRIx64 "\n",
+               elf.sstart, elf.send);
 
     if ( !compatible )
     {
@@ -385,7 +388,7 @@ int __init construct_dom0(
     v_start          = parms.virt_base;
     vkern_start      = parms.virt_kstart;
     vkern_end        = parms.virt_kend;
-    vinitrd_start    = round_pgup(vkern_end);
+    vinitrd_start    = round_pgup(parms.virt_end);
     vinitrd_end      = vinitrd_start + initrd_len;
     vphysmap_start   = round_pgup(vinitrd_end);
     vphysmap_end     = vphysmap_start + (nr_pages * (!is_pv_32on64_domain(d) ?
@@ -795,7 +798,7 @@ int __init construct_dom0(
 
     /* Copy the OS image and free temporary buffer. */
     elf.dest = (void*)vkern_start;
-    elf_load_binary(&elf);
+    elf_xen_dom_load_binary(&elf, &parms);
 
     if ( UNSET_ADDR != parms.virt_hypercall )
     {
diff -r bf85b467ee89 -r e0b424bc9572 xen/common/libelf/libelf-dominfo.c
--- a/xen/common/libelf/libelf-dominfo.c        Thu Aug 02 09:02:08 2007 +0100
+++ b/xen/common/libelf/libelf-dominfo.c        Thu Aug 02 09:02:26 2007 +0100
@@ -333,6 +333,99 @@ static int elf_xen_note_check(struct elf
     return 0;
 }
 
+
+static void elf_xen_loadsymtab(struct elf_binary *elf,
+                               struct elf_dom_parms *parms)
+{
+    unsigned long maxva, len;
+
+    if ( !parms->bsd_symtab )
+        return;
+
+    /* Calculate the required additional kernel space for the elf image */
+
+    /* The absolute base address of the elf image */
+    maxva = elf_round_up(elf, parms->virt_kend);
+    maxva += sizeof(long); /* Space to store the size of the elf image */
+    /* Space for the elf and elf section headers */
+    maxva += (elf_uval(elf, elf->ehdr, e_ehsize) +
+              elf_shdr_count(elf) * elf_uval(elf, elf->ehdr, e_shentsize));
+    maxva = elf_round_up(elf, maxva);
+
+    /* Space for the symbol and string tabs */
+    len = (unsigned long)elf->send - (unsigned long)elf->sstart;
+    maxva = elf_round_up(elf, maxva + len);
+
+    /* The address the kernel must expanded to */
+    parms->virt_end = maxva;
+}
+
+int elf_xen_dom_load_binary(struct elf_binary *elf,
+                            struct elf_dom_parms *parms)
+{
+    elf_ehdr *sym_ehdr;
+    unsigned long shdr, symtab_addr;
+    unsigned long maxva, symbase;
+    uint8_t i;
+    char *p;
+
+    elf_load_binary(elf);
+
+    if ( !parms->bsd_symtab )
+        return 0;
+
+#define elf_hdr_elm(_elf, _hdr, _elm, _val)     \
+do {                                            \
+    if ( elf_64bit(_elf) )                      \
+        (_hdr)->e64._elm = _val;                \
+    else                                        \
+        (_hdr)->e32._elm = _val;                \
+} while ( 0 )
+
+    /* ehdr right after the kernel image (4 byte aligned) */
+    symbase = elf_round_up(elf, parms->virt_kend);
+    symtab_addr = maxva = symbase + sizeof(long);
+
+    /* Set up Elf header. */
+    sym_ehdr = (elf_ehdr *)symtab_addr;
+    maxva = elf_copy_ehdr(elf, sym_ehdr);
+
+    elf_hdr_elm(elf, sym_ehdr, e_phoff, 0);
+    elf_hdr_elm(elf, sym_ehdr, e_shoff, elf_uval(elf, elf->ehdr, e_ehsize));
+    elf_hdr_elm(elf, sym_ehdr, e_phentsize, 0);
+    elf_hdr_elm(elf, sym_ehdr, e_phnum, 0);
+
+    /* Copy Elf section headers. */
+    shdr = maxva;
+    maxva = elf_copy_shdr(elf, (elf_shdr *)shdr);
+
+    for ( i = 0; i < elf_shdr_count(elf); i++ )
+    {
+        uint8_t type;
+        unsigned long tmp;
+        type = elf_uval(elf, (elf_shdr *)shdr, sh_type);
+        if ( (type == SHT_STRTAB) || (type == SHT_SYMTAB) )
+        {
+             elf_msg(elf, "%s: shdr %i at 0x%p -> 0x%p\n", __func__, i,
+                     elf_section_start(elf, (elf_shdr *)shdr), (void *)maxva);
+             tmp = elf_copy_section(elf, (elf_shdr *)shdr, (void *)maxva);
+             /* Mangled to be based on ELF header location. */
+             elf_hdr_elm(elf, (elf_shdr *)shdr, sh_offset,
+                         maxva - symtab_addr);
+             maxva = tmp;
+        }
+        shdr += elf_uval(elf, elf->ehdr, e_shentsize);
+    }
+
+    /* Write down the actual sym size. */
+    p = (char *)symbase;
+    *(long *)p = maxva - symtab_addr; /* sym size */
+
+#undef elf_ehdr_elm
+
+    return 0;
+}
+
 static int elf_xen_addr_calc_check(struct elf_binary *elf,
                                    struct elf_dom_parms *parms)
 {
@@ -374,9 +467,13 @@ static int elf_xen_addr_calc_check(struc
     parms->virt_offset = parms->virt_base - parms->elf_paddr_offset;
     parms->virt_kstart = elf->pstart + parms->virt_offset;
     parms->virt_kend   = elf->pend   + parms->virt_offset;
+    parms->virt_end    = parms->virt_kend;
 
     if ( parms->virt_entry == UNSET_ADDR )
         parms->virt_entry = elf_uval(elf, elf->ehdr, e_entry);
+
+    if ( parms->bsd_symtab )
+        elf_xen_loadsymtab(elf, parms);
 
     elf_msg(elf, "%s: addresses:\n", __FUNCTION__);
     elf_msg(elf, "    virt_base        = 0x%" PRIx64 "\n", parms->virt_base);
@@ -384,12 +481,14 @@ static int elf_xen_addr_calc_check(struc
     elf_msg(elf, "    virt_offset      = 0x%" PRIx64 "\n", parms->virt_offset);
     elf_msg(elf, "    virt_kstart      = 0x%" PRIx64 "\n", parms->virt_kstart);
     elf_msg(elf, "    virt_kend        = 0x%" PRIx64 "\n", parms->virt_kend);
+    elf_msg(elf, "    virt_end         = 0x%" PRIx64 "\n", parms->virt_end);
     elf_msg(elf, "    virt_entry       = 0x%" PRIx64 "\n", parms->virt_entry);
 
     if ( (parms->virt_kstart > parms->virt_kend) ||
          (parms->virt_entry < parms->virt_kstart) ||
          (parms->virt_entry > parms->virt_kend) ||
-         (parms->virt_base > parms->virt_kstart) )
+         (parms->virt_base > parms->virt_kstart) ||
+         (parms->virt_kend > parms->virt_end) )
     {
         elf_err(elf, "%s: ERROR: ELF start or entries are out of bounds.\n",
                 __FUNCTION__);
diff -r bf85b467ee89 -r e0b424bc9572 xen/common/libelf/libelf-loader.c
--- a/xen/common/libelf/libelf-loader.c Thu Aug 02 09:02:08 2007 +0100
+++ b/xen/common/libelf/libelf-loader.c Thu Aug 02 09:02:26 2007 +0100
@@ -10,6 +10,8 @@ int elf_init(struct elf_binary *elf, con
 {
     const elf_shdr *shdr;
     uint64_t i, count, section, offset;
+    uint64_t low = -1;
+    uint64_t high = 0;
 
     if ( !elf_is_elfbinary(image) )
     {
@@ -24,7 +26,11 @@ int elf_init(struct elf_binary *elf, con
     elf->class = elf->ehdr->e32.e_ident[EI_CLASS];
     elf->data = elf->ehdr->e32.e_ident[EI_DATA];
 
-    /* sanity check phdr */
+#ifdef VERBOSE
+    elf_set_verbose(elf);
+#endif
+
+    /* Sanity check phdr. */
     offset = elf_uval(elf, elf->ehdr, e_phoff) +
         elf_uval(elf, elf->ehdr, e_phentsize) * elf_phdr_count(elf);
     if ( offset > elf->size )
@@ -34,7 +40,7 @@ int elf_init(struct elf_binary *elf, con
         return -1;
     }
 
-    /* sanity check shdr */
+    /* Sanity check shdr. */
     offset = elf_uval(elf, elf->ehdr, e_shoff) +
         elf_uval(elf, elf->ehdr, e_shentsize) * elf_shdr_count(elf);
     if ( offset > elf->size )
@@ -44,29 +50,55 @@ int elf_init(struct elf_binary *elf, con
         return -1;
     }
 
-    /* find section string table */
+    /* Find section string table. */
     section = elf_uval(elf, elf->ehdr, e_shstrndx);
     shdr = elf_shdr_by_index(elf, section);
     if ( shdr != NULL )
         elf->sec_strtab = elf_section_start(elf, shdr);
 
-    /* find symbol table, symbol string table */
+    /* Find symbol table and symbol string table. */
     count = elf_shdr_count(elf);
     for ( i = 0; i < count; i++ )
     {
+        const char *sh_symend, *sh_strend;
+
         shdr = elf_shdr_by_index(elf, i);
         if ( elf_uval(elf, shdr, sh_type) != SHT_SYMTAB )
             continue;
         elf->sym_tab = shdr;
+        sh_symend = (const char *)elf_section_end(elf, shdr);
         shdr = elf_shdr_by_index(elf, elf_uval(elf, shdr, sh_link));
         if ( shdr == NULL )
         {
             elf->sym_tab = NULL;
+            sh_symend = 0;
             continue;
         }
         elf->sym_strtab = elf_section_start(elf, shdr);
-        break;
-    }
+        sh_strend = (const char *)elf_section_end(elf, shdr);
+
+        if ( low > (unsigned long)elf->sym_tab )
+            low = (unsigned long)elf->sym_tab;
+        if ( low > (unsigned long)shdr )
+            low = (unsigned long)shdr;
+
+        if ( high < ((unsigned long)sh_symend) )
+            high = (unsigned long)sh_symend;
+        if ( high < ((unsigned long)sh_strend) )
+            high = (unsigned long)sh_strend;
+
+        elf_msg(elf, "%s: shdr: sym_tab=%p size=0x%" PRIx64 "\n",
+                __FUNCTION__, elf->sym_tab,
+                elf_uval(elf, elf->sym_tab, sh_size));
+        elf_msg(elf, "%s: shdr: str_tab=%p size=0x%" PRIx64 "\n",
+                __FUNCTION__, elf->sym_strtab, elf_uval(elf, shdr, sh_size));
+
+        elf->sstart = low;
+        elf->send = high;
+        elf_msg(elf, "%s: symbol map: 0x%" PRIx64 " -> 0x%" PRIx64 "\n",
+                __FUNCTION__, elf->sstart, elf->send);
+    }
+
     return 0;
 }
 
diff -r bf85b467ee89 -r e0b424bc9572 xen/common/libelf/libelf-tools.c
--- a/xen/common/libelf/libelf-tools.c  Thu Aug 02 09:02:08 2007 +0100
+++ b/xen/common/libelf/libelf-tools.c  Thu Aug 02 09:02:26 2007 +0100
@@ -236,6 +236,36 @@ int elf_phdr_is_loadable(struct elf_bina
     uint64_t p_flags = elf_uval(elf, phdr, p_flags);
 
     return ((p_type == PT_LOAD) && (p_flags & (PF_W | PF_X)) != 0);
+}
+
+unsigned long
+elf_copy_ehdr(struct elf_binary *elf, void *dest)
+{
+    uint64_t size;
+
+    size = elf_uval(elf, elf->ehdr, e_ehsize);
+    memcpy(dest, elf->ehdr, size);
+    return elf_round_up(elf, (unsigned long)(dest) + size);
+}
+
+unsigned long
+elf_copy_shdr(struct elf_binary *elf, void *dest)
+{
+    uint64_t size;
+
+    size = elf_shdr_count(elf) * elf_uval(elf, elf->ehdr, e_shentsize);
+    memcpy(dest, elf->image + elf_uval(elf, elf->ehdr, e_shoff), size);
+    return elf_round_up(elf, (unsigned long)(dest) + size);
+}
+
+unsigned long
+elf_copy_section(struct elf_binary *elf, const elf_shdr *shdr, void *dest)
+{
+    uint64_t size;
+
+    size = elf_uval(elf, shdr, sh_size);
+    memcpy(dest, elf_section_start(elf, shdr), size);
+    return elf_round_up(elf, (unsigned long)(dest) + size);
 }
 
 /*
diff -r bf85b467ee89 -r e0b424bc9572 xen/include/public/libelf.h
--- a/xen/include/public/libelf.h       Thu Aug 02 09:02:08 2007 +0100
+++ b/xen/include/public/libelf.h       Thu Aug 02 09:02:26 2007 +0100
@@ -65,6 +65,8 @@ struct elf_binary {
 
     /* loaded to */
     char *dest;
+    uint64_t sstart;
+    uint64_t send;
     uint64_t pstart;
     uint64_t pend;
     uint64_t reloc_offset;
@@ -91,33 +93,32 @@ struct elf_binary {
 #define elf_lsb(elf)   (ELFDATA2LSB == (elf)->data)
 #define elf_swap(elf)  (NATIVE_ELFDATA != (elf)->data)
 
-#define elf_uval(elf, str, elem)                       \
-       ((ELFCLASS64 == (elf)->class)                   \
-       ? elf_access_unsigned((elf), (str),             \
-               offsetof(typeof(*(str)),e64.elem),      \
-               sizeof((str)->e64.elem))                \
-       : elf_access_unsigned((elf), (str),             \
-               offsetof(typeof(*(str)),e32.elem),      \
-               sizeof((str)->e32.elem)))
-
-#define elf_sval(elf, str, elem)                       \
-       ((ELFCLASS64 == (elf)->class)                   \
-       ? elf_access_signed((elf), (str),               \
-               offsetof(typeof(*(str)),e64.elem),      \
-               sizeof((str)->e64.elem))                \
-       : elf_access_signed((elf), (str),               \
-               offsetof(typeof(*(str)),e32.elem),      \
-               sizeof((str)->e32.elem)))
-
-#define elf_size(elf, str)             \
-       ((ELFCLASS64 == (elf)->class)   \
-       ? sizeof((str)->e64)            \
-       : sizeof((str)->e32))
+#define elf_uval(elf, str, elem)                                        \
+    ((ELFCLASS64 == (elf)->class)                                       \
+     ? elf_access_unsigned((elf), (str),                                \
+                           offsetof(typeof(*(str)),e64.elem),           \
+                           sizeof((str)->e64.elem))                     \
+     : elf_access_unsigned((elf), (str),                                \
+                           offsetof(typeof(*(str)),e32.elem),           \
+                           sizeof((str)->e32.elem)))
+
+#define elf_sval(elf, str, elem)                                        \
+    ((ELFCLASS64 == (elf)->class)                                       \
+     ? elf_access_signed((elf), (str),                                  \
+                         offsetof(typeof(*(str)),e64.elem),             \
+                         sizeof((str)->e64.elem))                       \
+     : elf_access_signed((elf), (str),                                  \
+                         offsetof(typeof(*(str)),e32.elem),             \
+                         sizeof((str)->e32.elem)))
+
+#define elf_size(elf, str)                              \
+    ((ELFCLASS64 == (elf)->class)                       \
+     ? sizeof((str)->e64) : sizeof((str)->e32))
 
 uint64_t elf_access_unsigned(struct elf_binary *elf, const void *ptr,
-                            uint64_t offset, size_t size);
+                             uint64_t offset, size_t size);
 int64_t elf_access_signed(struct elf_binary *elf, const void *ptr,
-                         uint64_t offset, size_t size);
+                          uint64_t offset, size_t size);
 
 uint64_t elf_round_up(struct elf_binary *elf, uint64_t addr);
 
@@ -149,6 +150,11 @@ int elf_is_elfbinary(const void *image);
 int elf_is_elfbinary(const void *image);
 int elf_phdr_is_loadable(struct elf_binary *elf, const elf_phdr * phdr);
 
+unsigned long elf_copy_ehdr(struct elf_binary *elf, void *dest);
+unsigned long elf_copy_shdr(struct elf_binary *elf, void *dest);
+unsigned long elf_copy_section(struct elf_binary *elf,
+                               const elf_shdr *shdr, void *dest);
+
 /* ------------------------------------------------------------------------ */
 /* xc_libelf_loader.c                                                       */
 
@@ -185,8 +191,8 @@ struct xen_elfnote {
     enum xen_elfnote_type type;
     const char *name;
     union {
-       const char *str;
-       uint64_t num;
+        const char *str;
+        uint64_t num;
     } data;
 };
 
@@ -215,7 +221,8 @@ struct elf_dom_parms {
     /* calculated */
     uint64_t virt_offset;
     uint64_t virt_kstart;
-    uint64_t virt_kend;
+    uint64_t virt_kend; /* end of kernel image */
+    uint64_t virt_end;  /* end of kernel symtab (== virt_kend if none) */
 };
 
 static inline void elf_xen_feature_set(int nr, uint32_t * addr)
@@ -228,14 +235,17 @@ static inline int elf_xen_feature_get(in
 }
 
 int elf_xen_parse_features(const char *features,
-                          uint32_t *supported,
-                          uint32_t *required);
+                           uint32_t *supported,
+                           uint32_t *required);
 int elf_xen_parse_note(struct elf_binary *elf,
-                      struct elf_dom_parms *parms,
-                      const elf_note *note);
+                       struct elf_dom_parms *parms,
+                       const elf_note *note);
 int elf_xen_parse_guest_info(struct elf_binary *elf,
-                            struct elf_dom_parms *parms);
+                             struct elf_dom_parms *parms);
 int elf_xen_parse(struct elf_binary *elf,
-                 struct elf_dom_parms *parms);
+                  struct elf_dom_parms *parms);
+
+int elf_xen_dom_load_binary(struct elf_binary *elf,
+                            struct elf_dom_parms *parms);
 
 #endif /* __XC_LIBELF__ */

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

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