WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] libelf: Clean up and fix up BSD symtab ha

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] libelf: Clean up and fix up BSD symtab handling.
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Tue, 07 Aug 2007 05:30:14 -0700
Delivery-date: Tue, 07 Aug 2007 05:28:07 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User kfraser@xxxxxxxxxxxxxxxxxxxxx
# Date 1186060718 -3600
# Node ID 7ee30cf72fd3bf2e1cd6d016dd383865c6ee50a4
# Parent  78be123257fab0bcd71cd800824c5f552098958b
libelf: Clean up and fix up BSD symtab handling.
Should now (hopefully) work for domU and dom0 builders.
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
---
 xen/arch/x86/domain_build.c        |    8 +-
 xen/common/libelf/libelf-dominfo.c |  104 +-----------------------------
 xen/common/libelf/libelf-loader.c  |  128 ++++++++++++++++++++++++++++---------
 xen/common/libelf/libelf-tools.c   |   30 --------
 xen/include/public/libelf.h        |   18 +----
 5 files changed, 114 insertions(+), 174 deletions(-)

diff -r 78be123257fa -r 7ee30cf72fd3 xen/arch/x86/domain_build.c
--- a/xen/arch/x86/domain_build.c       Thu Aug 02 10:05:14 2007 +0100
+++ b/xen/arch/x86/domain_build.c       Thu Aug 02 14:18:38 2007 +0100
@@ -316,9 +316,9 @@ int __init construct_dom0(
            parms.pae       ? ", PAE"  : "",
            elf_msb(&elf)   ? "msb"    : "lsb",
            elf.pstart, elf.pend);
-    if ( parms.bsd_symtab )
+    if ( elf.bsd_symtab_pstart )
         printk(" Dom0 symbol map 0x%" PRIx64 " -> 0x%" PRIx64 "\n",
-               elf.sstart, elf.send);
+               elf.bsd_symtab_pstart, elf.bsd_symtab_pend);
 
     if ( !compatible )
     {
@@ -388,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(parms.virt_end);
+    vinitrd_start    = round_pgup(vkern_end);
     vinitrd_end      = vinitrd_start + initrd_len;
     vphysmap_start   = round_pgup(vinitrd_end);
     vphysmap_end     = vphysmap_start + (nr_pages * (!is_pv_32on64_domain(d) ?
@@ -798,7 +798,7 @@ int __init construct_dom0(
 
     /* Copy the OS image and free temporary buffer. */
     elf.dest = (void*)vkern_start;
-    elf_xen_dom_load_binary(&elf, &parms);
+    elf_load_binary(&elf);
 
     if ( UNSET_ADDR != parms.virt_hypercall )
     {
diff -r 78be123257fa -r 7ee30cf72fd3 xen/common/libelf/libelf-dominfo.c
--- a/xen/common/libelf/libelf-dominfo.c        Thu Aug 02 10:05:14 2007 +0100
+++ b/xen/common/libelf/libelf-dominfo.c        Thu Aug 02 14:18:38 2007 +0100
@@ -333,99 +333,6 @@ 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)
 {
@@ -467,13 +374,16 @@ 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_parse_bsdsyms(elf, parms->virt_kend);
+        if ( elf->bsd_symtab_pend )
+            parms->virt_kend = elf->bsd_symtab_pend + parms->virt_offset;
+    }
 
     elf_msg(elf, "%s: addresses:\n", __FUNCTION__);
     elf_msg(elf, "    virt_base        = 0x%" PRIx64 "\n", parms->virt_base);
@@ -481,14 +391,12 @@ 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_kend > parms->virt_end) )
+         (parms->virt_base > parms->virt_kstart) )
     {
         elf_err(elf, "%s: ERROR: ELF start or entries are out of bounds.\n",
                 __FUNCTION__);
diff -r 78be123257fa -r 7ee30cf72fd3 xen/common/libelf/libelf-loader.c
--- a/xen/common/libelf/libelf-loader.c Thu Aug 02 10:05:14 2007 +0100
+++ b/xen/common/libelf/libelf-loader.c Thu Aug 02 14:18:38 2007 +0100
@@ -10,8 +10,6 @@ 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) )
     {
@@ -22,7 +20,7 @@ int elf_init(struct elf_binary *elf, con
     memset(elf, 0, sizeof(*elf));
     elf->image = image;
     elf->size = size;
-    elf->ehdr = (elf_ehdr *) image;
+    elf->ehdr = (elf_ehdr *)image;
     elf->class = elf->ehdr->e32.e_ident[EI_CLASS];
     elf->data = elf->ehdr->e32.e_ident[EI_DATA];
 
@@ -56,44 +54,17 @@ int elf_init(struct elf_binary *elf, con
     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);
-        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);
-
         break;
     }
 
@@ -112,6 +83,101 @@ void elf_set_verbose(struct elf_binary *
     elf->verbose = 1;
 }
 #endif
+
+/* Calculate the required additional kernel space for the elf image */
+void elf_parse_bsdsyms(struct elf_binary *elf, uint64_t pstart)
+{
+    uint64_t sz;
+    const elf_shdr *shdr;
+    int i, type;
+
+    if ( !elf->sym_tab )
+        return;
+
+    pstart = elf_round_up(elf, pstart);
+
+    /* Space to store the size of the elf image */
+    sz = sizeof(uint32_t);
+
+    /* Space for the elf and elf section headers */
+    sz += (elf_uval(elf, elf->ehdr, e_ehsize) +
+           elf_shdr_count(elf) * elf_uval(elf, elf->ehdr, e_shentsize));
+    sz = elf_round_up(elf, sz);
+
+    /* Space for the symbol and string tables. */
+    for ( i = 0; i < elf_shdr_count(elf); i++ )
+    {
+        shdr = elf_shdr_by_index(elf, i);
+        type = elf_uval(elf, (elf_shdr *)shdr, sh_type);
+        if ( (type == SHT_STRTAB) || (type == SHT_SYMTAB) )
+            sz = elf_round_up(elf, sz + elf_uval(elf, shdr, sh_size));
+    }
+
+    elf->bsd_symtab_pstart = pstart;
+    elf->bsd_symtab_pend   = pstart + sz;
+}
+
+static void elf_load_bsdsyms(struct elf_binary *elf)
+{
+    elf_ehdr *sym_ehdr;
+    unsigned long sz;
+    char *maxva, *symbase, *symtab_addr;
+    elf_shdr *shdr;
+    int i, type;
+
+    if ( !elf->bsd_symtab_pstart )
+        return;
+
+#define elf_hdr_elm(_elf, _hdr, _elm, _val)     \
+do {                                            \
+    if ( elf_64bit(_elf) )                      \
+        (_hdr)->e64._elm = _val;                \
+    else                                        \
+        (_hdr)->e32._elm = _val;                \
+} while ( 0 )
+
+    symbase = elf_get_ptr(elf, elf->bsd_symtab_pstart);
+    symtab_addr = maxva = symbase + sizeof(uint32_t);
+
+    /* Set up Elf header. */
+    sym_ehdr = (elf_ehdr *)symtab_addr;
+    sz = elf_uval(elf, elf->ehdr, e_ehsize);
+    memcpy(sym_ehdr, elf->ehdr, sz);
+    maxva += sz; /* no round up */
+
+    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 = (elf_shdr *)maxva;
+    sz = elf_shdr_count(elf) * elf_uval(elf, elf->ehdr, e_shentsize);
+    memcpy(shdr, elf->image + elf_uval(elf, elf->ehdr, e_shoff), sz);
+    maxva = (char *)(long)elf_round_up(elf, (long)maxva + sz);
+
+    for ( i = 0; i < elf_shdr_count(elf); i++ )
+    {
+        type = elf_uval(elf, 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, shdr), maxva);
+             sz = elf_uval(elf, shdr, sh_size);
+             memcpy(maxva, elf_section_start(elf, shdr), sz);
+             /* Mangled to be based on ELF header location. */
+             elf_hdr_elm(elf, shdr, sh_offset, maxva - symtab_addr);
+             maxva = (char *)(long)elf_round_up(elf, (long)maxva + sz);
+        }
+        shdr = (elf_shdr *)((long)shdr +
+                            (long)elf_uval(elf, elf->ehdr, e_shentsize));
+    }
+
+    /* Write down the actual sym size. */
+    *(uint32_t *)symbase = maxva - symtab_addr;
+
+#undef elf_ehdr_elm
+}
 
 void elf_parse_binary(struct elf_binary *elf)
 {
@@ -163,6 +229,8 @@ void elf_load_binary(struct elf_binary *
         memcpy(dest, elf->image + offset, filesz);
         memset(dest + filesz, 0, memsz - filesz);
     }
+
+    elf_load_bsdsyms(elf);
 }
 
 void *elf_get_ptr(struct elf_binary *elf, unsigned long addr)
diff -r 78be123257fa -r 7ee30cf72fd3 xen/common/libelf/libelf-tools.c
--- a/xen/common/libelf/libelf-tools.c  Thu Aug 02 10:05:14 2007 +0100
+++ b/xen/common/libelf/libelf-tools.c  Thu Aug 02 14:18:38 2007 +0100
@@ -236,36 +236,6 @@ 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 78be123257fa -r 7ee30cf72fd3 xen/include/public/libelf.h
--- a/xen/include/public/libelf.h       Thu Aug 02 10:05:14 2007 +0100
+++ b/xen/include/public/libelf.h       Thu Aug 02 14:18:38 2007 +0100
@@ -65,11 +65,12 @@ struct elf_binary {
 
     /* loaded to */
     char *dest;
-    uint64_t sstart;
-    uint64_t send;
     uint64_t pstart;
     uint64_t pend;
     uint64_t reloc_offset;
+
+    uint64_t bsd_symtab_pstart;
+    uint64_t bsd_symtab_pend;
 
 #ifndef __XEN__
     /* misc */
@@ -150,11 +151,6 @@ 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                                                       */
 
@@ -170,6 +166,8 @@ void elf_load_binary(struct elf_binary *
 
 void *elf_get_ptr(struct elf_binary *elf, unsigned long addr);
 uint64_t elf_lookup_addr(struct elf_binary *elf, const char *symbol);
+
+void elf_parse_bsdsyms(struct elf_binary *elf, uint64_t pstart); /* private */
 
 /* ------------------------------------------------------------------------ */
 /* xc_libelf_relocate.c                                                     */
@@ -221,8 +219,7 @@ struct elf_dom_parms {
     /* calculated */
     uint64_t virt_offset;
     uint64_t virt_kstart;
-    uint64_t virt_kend; /* end of kernel image */
-    uint64_t virt_end;  /* end of kernel symtab (== virt_kend if none) */
+    uint64_t virt_kend;
 };
 
 static inline void elf_xen_feature_set(int nr, uint32_t * addr)
@@ -245,7 +242,4 @@ int elf_xen_parse(struct elf_binary *elf
 int elf_xen_parse(struct elf_binary *elf,
                   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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] libelf: Clean up and fix up BSD symtab handling., Xen patchbot-unstable <=