# 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
|