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