debuggers.hg
changeset 11276:faadbf5ba8d6
[XEN/LINUX] Define Xen ELF notes in kernel header and update dom0 builder.
ELF notes provide a cleaner interface for passing Xen specific
information from the kernel to the domain builder than the existing
__xen_guest section string. The __xen_guest string is retained in
kernels built with 3.0.2 compatability for domU however dom0 requires
the new interface.
Signed-off-by: Ian Campbell <ian.campbell@xensource.com>
ELF notes provide a cleaner interface for passing Xen specific
information from the kernel to the domain builder than the existing
__xen_guest section string. The __xen_guest string is retained in
kernels built with 3.0.2 compatability for domU however dom0 requires
the new interface.
Signed-off-by: Ian Campbell <ian.campbell@xensource.com>
author | Ian Campbell <ian.campbell@xensource.com> |
---|---|
date | Wed Aug 23 14:41:05 2006 +0100 (2006-08-23) |
parents | d57b174adfd6 |
children | 58b5141c8309 |
files | linux-2.6-xen-sparse/arch/i386/kernel/head-xen.S linux-2.6-xen-sparse/arch/x86_64/kernel/head-xen.S xen/arch/x86/domain_build.c xen/common/elf.c xen/include/xen/elf.h xen/include/xen/sched.h |
line diff
1.1 --- a/linux-2.6-xen-sparse/arch/i386/kernel/head-xen.S Wed Aug 23 14:37:39 2006 +0100 1.2 +++ b/linux-2.6-xen-sparse/arch/i386/kernel/head-xen.S Wed Aug 23 14:41:05 2006 +0100 1.3 @@ -2,6 +2,7 @@ 1.4 1.5 .text 1.6 #include <linux/config.h> 1.7 +#include <linux/elfnote.h> 1.8 #include <linux/threads.h> 1.9 #include <linux/linkage.h> 1.10 #include <asm/segment.h> 1.11 @@ -9,6 +10,7 @@ 1.12 #include <asm/thread_info.h> 1.13 #include <asm/asm-offsets.h> 1.14 #include <xen/interface/arch-x86_32.h> 1.15 +#include <xen/interface/elfnote.h> 1.16 1.17 /* 1.18 * References to members of the new_cpu_data structure. 1.19 @@ -138,6 +140,7 @@ ENTRY(cpu_gdt_table) 1.20 .quad 0x0000000000000000 /* 0xf0 - unused */ 1.21 .quad 0x0000000000000000 /* 0xf8 - GDT entry 31: double-fault TSS */ 1.22 1.23 +#ifdef CONFIG_XEN_COMPAT_030002 1.24 /* 1.25 * __xen_guest information 1.26 */ 1.27 @@ -157,12 +160,8 @@ ENTRY(cpu_gdt_table) 1.28 .ascii ",XEN_VER=xen-3.0" 1.29 .ascii ",VIRT_BASE=0x" 1.30 utoa __PAGE_OFFSET 1.31 -#ifdef CONFIG_XEN_COMPAT_030002 1.32 .ascii ",ELF_PADDR_OFFSET=0x" 1.33 utoa __PAGE_OFFSET 1.34 -#else 1.35 - .ascii ",ELF_PADDR_OFFSET=0x0" 1.36 -#endif /* !CONFIG_XEN_COMPAT_030002 */ 1.37 .ascii ",VIRT_ENTRY=0x" 1.38 utoa (__PAGE_OFFSET + __PHYSICAL_START + VIRT_ENTRY_OFFSET) 1.39 .ascii ",HYPERCALL_PAGE=0x" 1.40 @@ -179,3 +178,24 @@ ENTRY(cpu_gdt_table) 1.41 #endif 1.42 .ascii ",LOADER=generic" 1.43 .byte 0 1.44 +#endif /* CONFIG_XEN_COMPAT_030002 */ 1.45 + 1.46 + 1.47 + ELFNOTE(Xen, XEN_ELFNOTE_GUEST_OS, .asciz, "linux") 1.48 + ELFNOTE(Xen, XEN_ELFNOTE_GUEST_VERSION, .asciz, "2.6") 1.49 + ELFNOTE(Xen, XEN_ELFNOTE_XEN_VERSION, .asciz, "xen-3.0") 1.50 + ELFNOTE(Xen, XEN_ELFNOTE_VIRT_BASE, .long, __PAGE_OFFSET) 1.51 +#ifdef CONFIG_XEN_COMPAT_030002 1.52 + ELFNOTE(Xen, XEN_ELFNOTE_PADDR_OFFSET, .long, __PAGE_OFFSET) 1.53 +#else 1.54 + ELFNOTE(Xen, XEN_ELFNOTE_PADDR_OFFSET, .long, 0) 1.55 +#endif /* !CONFIG_XEN_COMPAT_030002 */ 1.56 + ELFNOTE(Xen, XEN_ELFNOTE_ENTRY, .long, startup_32) 1.57 + ELFNOTE(Xen, XEN_ELFNOTE_HYPERCALL_PAGE, .long, hypercall_page) 1.58 + ELFNOTE(Xen, XEN_ELFNOTE_FEATURES, .asciz, "writable_page_tables|writable_descriptor_tables|auto_translated_physmap|pae_pgdir_above_4gb|supervisor_mode_kernel") 1.59 +#ifdef CONFIG_X86_PAE 1.60 + ELFNOTE(Xen, XEN_ELFNOTE_PAE_MODE, .asciz, "yes") 1.61 +#else 1.62 + ELFNOTE(Xen, XEN_ELFNOTE_PAE_MODE, .asciz, "no") 1.63 +#endif 1.64 + ELFNOTE(Xen, XEN_ELFNOTE_LOADER, .asciz, "generic")
2.1 --- a/linux-2.6-xen-sparse/arch/x86_64/kernel/head-xen.S Wed Aug 23 14:37:39 2006 +0100 2.2 +++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/head-xen.S Wed Aug 23 14:41:05 2006 +0100 2.3 @@ -16,12 +16,15 @@ 2.4 #include <linux/linkage.h> 2.5 #include <linux/threads.h> 2.6 #include <linux/init.h> 2.7 +#include <linux/elfnote.h> 2.8 #include <asm/desc.h> 2.9 #include <asm/segment.h> 2.10 #include <asm/page.h> 2.11 #include <asm/msr.h> 2.12 #include <asm/cache.h> 2.13 2.14 +#include <xen/interface/elfnote.h> 2.15 + 2.16 .text 2.17 .code64 2.18 #define VIRT_ENTRY_OFFSET 0x0 2.19 @@ -131,6 +134,7 @@ gdt_end: 2.20 /* zero the remaining page */ 2.21 .fill PAGE_SIZE / 8 - GDT_ENTRIES,8,0 2.22 2.23 +#ifdef CONFIG_XEN_COMPAT_030002 2.24 /* 2.25 * __xen_guest information 2.26 */ 2.27 @@ -150,12 +154,8 @@ gdt_end: 2.28 .ascii ",XEN_VER=xen-3.0" 2.29 .ascii ",VIRT_BASE=0x" 2.30 utoh __START_KERNEL_map 2.31 -#ifdef CONFIG_XEN_COMPAT_030002 2.32 .ascii ",ELF_PADDR_OFFSET=0x" 2.33 utoh __START_KERNEL_map 2.34 -#else 2.35 - .ascii ",ELF_PADDR_OFFSET=0x0" 2.36 -#endif /* !CONFIG_XEN_COMPAT_030002 */ 2.37 .ascii ",VIRT_ENTRY=0x" 2.38 utoh (__START_KERNEL_map + __PHYSICAL_START + VIRT_ENTRY_OFFSET) 2.39 .ascii ",HYPERCALL_PAGE=0x" 2.40 @@ -166,3 +166,18 @@ gdt_end: 2.41 .ascii "|supervisor_mode_kernel" 2.42 .ascii ",LOADER=generic" 2.43 .byte 0 2.44 +#endif /* CONFIG_XEN_COMPAT_030002 */ 2.45 + 2.46 + ELFNOTE(Xen, XEN_ELFNOTE_GUEST_OS, .asciz, "linux") 2.47 + ELFNOTE(Xen, XEN_ELFNOTE_GUEST_VERSION, .asciz, "2.6") 2.48 + ELFNOTE(Xen, XEN_ELFNOTE_XEN_VERSION, .asciz, "xen-3.0") 2.49 + ELFNOTE(Xen, XEN_ELFNOTE_VIRT_BASE, .quad, __START_KERNEL_map) 2.50 +#ifdef CONFIG_XEN_COMPAT_030002 2.51 + ELFNOTE(Xen, XEN_ELFNOTE_PADDR_OFFSET, .quad, __START_KERNEL_map) 2.52 +#else 2.53 + ELFNOTE(Xen, XEN_ELFNOTE_PADDR_OFFSET, .quad, 0) 2.54 +#endif /* !CONFIG_XEN_COMPAT_030002 */ 2.55 + ELFNOTE(Xen, XEN_ELFNOTE_ENTRY, .quad, startup_64) 2.56 + ELFNOTE(Xen, XEN_ELFNOTE_HYPERCALL_PAGE, .quad, hypercall_page) 2.57 + ELFNOTE(Xen, XEN_ELFNOTE_FEATURES, .asciz, "writable_page_tables|writable_descriptor_tables|auto_translated_physmap|pae_pgdir_above_4gb|supervisor_mode_kernel") 2.58 + ELFNOTE(Xen, XEN_ELFNOTE_LOADER, .asciz, "generic")
3.1 --- a/xen/arch/x86/domain_build.c Wed Aug 23 14:37:39 2006 +0100 3.2 +++ b/xen/arch/x86/domain_build.c Wed Aug 23 14:41:05 2006 +0100 3.3 @@ -28,6 +28,7 @@ 3.4 #include <asm/shadow.h> 3.5 3.6 #include <public/version.h> 3.7 +#include <public/elfnote.h> 3.8 3.9 extern unsigned long initial_images_nrpages(void); 3.10 extern void discard_initial_images(void); 3.11 @@ -210,8 +211,9 @@ int construct_dom0(struct domain *d, 3.12 struct page_info *page = NULL; 3.13 start_info_t *si; 3.14 struct vcpu *v = d->vcpu[0]; 3.15 - char *p; 3.16 + const char *p; 3.17 unsigned long hypercall_page; 3.18 + int hypercall_page_defined; 3.19 #if defined(__i386__) 3.20 char *image_start = (char *)_image_start; /* use lowmem mappings */ 3.21 char *initrd_start = (char *)_initrd_start; /* use lowmem mappings */ 3.22 @@ -288,13 +290,14 @@ int construct_dom0(struct domain *d, 3.23 if ( (rc = parseelfimage(&dsi)) != 0 ) 3.24 return rc; 3.25 3.26 - if ( dsi.xen_section_string == NULL ) 3.27 + if ( dsi.__elfnote_section == NULL ) 3.28 { 3.29 - printk("Not a Xen-ELF image: '__xen_guest' section not found.\n"); 3.30 + printk("Not a Xen-ELF image: no Xen ELF notes were found.\n"); 3.31 return -EINVAL; 3.32 } 3.33 3.34 - dom0_pae = !!strstr(dsi.xen_section_string, "PAE=yes"); 3.35 + p = xen_elfnote_string(&dsi, XEN_ELFNOTE_PAE_MODE); 3.36 + dom0_pae = !!(p != NULL && strcmp(p, "yes") == 0); 3.37 xen_pae = (CONFIG_PAGING_LEVELS == 3); 3.38 if ( dom0_pae != xen_pae ) 3.39 { 3.40 @@ -303,15 +306,14 @@ int construct_dom0(struct domain *d, 3.41 return -EINVAL; 3.42 } 3.43 3.44 - if ( xen_pae && !!strstr(dsi.xen_section_string, "PAE=yes[extended-cr3]") ) 3.45 + if ( xen_pae ) 3.46 set_bit(VMASST_TYPE_pae_extended_cr3, &d->vm_assist); 3.47 3.48 - if ( (p = strstr(dsi.xen_section_string, "FEATURES=")) != NULL ) 3.49 + if ( (p = xen_elfnote_string(&dsi, XEN_ELFNOTE_FEATURES)) != NULL ) 3.50 { 3.51 - parse_features( 3.52 - p + strlen("FEATURES="), 3.53 - dom0_features_supported, 3.54 - dom0_features_required); 3.55 + parse_features(p, 3.56 + dom0_features_supported, 3.57 + dom0_features_required); 3.58 printk("Domain 0 kernel supports features = { %08x }.\n", 3.59 dom0_features_supported[0]); 3.60 printk("Domain 0 kernel requires features = { %08x }.\n", 3.61 @@ -696,20 +698,17 @@ int construct_dom0(struct domain *d, 3.62 /* Copy the OS image and free temporary buffer. */ 3.63 (void)loadelfimage(&dsi); 3.64 3.65 - p = strstr(dsi.xen_section_string, "HYPERCALL_PAGE="); 3.66 - if ( p != NULL ) 3.67 + hypercall_page = 3.68 + xen_elfnote_numeric(&dsi, XEN_ELFNOTE_HYPERCALL_PAGE, &hypercall_page_defined); 3.69 + if ( hypercall_page_defined ) 3.70 { 3.71 - p += strlen("HYPERCALL_PAGE="); 3.72 - hypercall_page = simple_strtoul(p, NULL, 16); 3.73 - hypercall_page = dsi.v_start + (hypercall_page << PAGE_SHIFT); 3.74 if ( (hypercall_page < dsi.v_start) || (hypercall_page >= v_end) ) 3.75 { 3.76 write_ptbase(current); 3.77 local_irq_enable(); 3.78 - printk("Invalid HYPERCALL_PAGE field in guest header.\n"); 3.79 + printk("Invalid HYPERCALL_PAGE field in ELF notes.\n"); 3.80 return -1; 3.81 } 3.82 - 3.83 hypercall_page_initialise(d, (void *)hypercall_page); 3.84 } 3.85
4.1 --- a/xen/common/elf.c Wed Aug 23 14:37:39 2006 +0100 4.2 +++ b/xen/common/elf.c Wed Aug 23 14:41:05 2006 +0100 4.3 @@ -11,6 +11,9 @@ 4.4 #include <xen/elf.h> 4.5 #include <xen/sched.h> 4.6 #include <xen/errno.h> 4.7 +#include <xen/inttypes.h> 4.8 + 4.9 +#include <public/elfnote.h> 4.10 4.11 static void loadelfsymtab(struct domain_setup_info *dsi, int doload); 4.12 static inline int is_loadable_phdr(Elf_Phdr *phdr) 4.13 @@ -19,26 +22,114 @@ static inline int is_loadable_phdr(Elf_P 4.14 ((phdr->p_flags & (PF_W|PF_X)) != 0)); 4.15 } 4.16 4.17 +/* 4.18 + * Interface to the Xen ELF notes. 4.19 + */ 4.20 +#define ELFNOTE_NAME(_n_) ((void*)(_n_) + sizeof(*(_n_))) 4.21 +#define ELFNOTE_DESC(_n_) (ELFNOTE_NAME(_n_) + (((_n_)->namesz+3)&~3)) 4.22 +#define ELFNOTE_NEXT(_n_) (ELFNOTE_DESC(_n_) + (((_n_)->descsz+3)&~3)) 4.23 + 4.24 +static int is_xen_elfnote_section(const char *image, Elf_Shdr *shdr) 4.25 +{ 4.26 + Elf_Note *note; 4.27 + 4.28 + if ( shdr->sh_type != SHT_NOTE ) 4.29 + return 0; 4.30 + 4.31 + for ( note = (Elf_Note *)(image + shdr->sh_offset); 4.32 + note < (Elf_Note *)(image + shdr->sh_offset + shdr->sh_size); 4.33 + note = ELFNOTE_NEXT(note) ) 4.34 + { 4.35 + if ( !strncmp(ELFNOTE_NAME(note), "Xen", 4) ) 4.36 + return 1; 4.37 + } 4.38 + 4.39 + return 0; 4.40 +} 4.41 + 4.42 +static Elf_Note *xen_elfnote_lookup(struct domain_setup_info *dsi, int type) 4.43 +{ 4.44 + Elf_Note *note; 4.45 + 4.46 + if ( !dsi->__elfnote_section ) 4.47 + return NULL; 4.48 + 4.49 + for ( note = (Elf_Note *)dsi->__elfnote_section; 4.50 + note < (Elf_Note *)dsi->__elfnote_section_end; 4.51 + note = ELFNOTE_NEXT(note) ) 4.52 + { 4.53 + if ( strncmp(ELFNOTE_NAME(note), "Xen", 4) ) 4.54 + continue; 4.55 + 4.56 + if ( note->type == type ) 4.57 + return note; 4.58 + } 4.59 + 4.60 + DPRINTK("unable to find Xen ELF note with type %#x\n", type); 4.61 + return NULL; 4.62 +} 4.63 + 4.64 +const char *xen_elfnote_string(struct domain_setup_info *dsi, int type) 4.65 +{ 4.66 + Elf_Note *note; 4.67 + 4.68 + note = xen_elfnote_lookup(dsi, type); 4.69 + if ( note == NULL ) 4.70 + return NULL; 4.71 + 4.72 + DPRINTK("found Xen ELF note type %#x = \"%s\"\n", 4.73 + type, (char *)ELFNOTE_DESC(note)); 4.74 + 4.75 + return (const char *)ELFNOTE_DESC(note); 4.76 +} 4.77 + 4.78 +unsigned long long xen_elfnote_numeric(struct domain_setup_info *dsi, 4.79 + int type, int *defined) 4.80 +{ 4.81 + Elf_Note *note; 4.82 + 4.83 + *defined = 0; 4.84 + 4.85 + note = xen_elfnote_lookup(dsi, type); 4.86 + if ( note == NULL ) 4.87 + { 4.88 + return 0; 4.89 + } 4.90 + 4.91 + switch ( note->descsz ) 4.92 + { 4.93 + case 4: 4.94 + *defined = 1; 4.95 + return *(uint32_t*)ELFNOTE_DESC(note); 4.96 + case 8: 4.97 + *defined = 1; 4.98 + return *(uint64_t*)ELFNOTE_DESC(note); 4.99 + default: 4.100 + return 0; 4.101 + } 4.102 +} 4.103 + 4.104 int parseelfimage(struct domain_setup_info *dsi) 4.105 { 4.106 Elf_Ehdr *ehdr = (Elf_Ehdr *)dsi->image_addr; 4.107 Elf_Phdr *phdr; 4.108 Elf_Shdr *shdr; 4.109 - Elf_Addr kernstart = ~0, kernend = 0, vaddr, virt_base, elf_pa_off; 4.110 - char *shstrtab, *guestinfo=NULL, *p; 4.111 - char *elfbase = (char *)dsi->image_addr; 4.112 - int h, virt_base_defined, elf_pa_off_defined; 4.113 + Elf_Addr kernstart = ~0, kernend = 0, vaddr, virt_entry; 4.114 + const char *shstrtab, *p; 4.115 + const char *image = (char *)dsi->image_addr; 4.116 + const unsigned long image_len = dsi->image_len; 4.117 + int h, virt_base_defined, elf_pa_off_defined, virt_entry_defined; 4.118 4.119 if ( !elf_sanity_check(ehdr) ) 4.120 return -EINVAL; 4.121 4.122 - if ( (ehdr->e_phoff + (ehdr->e_phnum*ehdr->e_phentsize)) > dsi->image_len ) 4.123 + if ( (ehdr->e_phoff + (ehdr->e_phnum*ehdr->e_phentsize)) > image_len ) 4.124 { 4.125 printk("ELF program headers extend beyond end of image.\n"); 4.126 return -EINVAL; 4.127 } 4.128 4.129 - if ( (ehdr->e_shoff + (ehdr->e_shnum*ehdr->e_shentsize)) > dsi->image_len ) 4.130 + if ( (ehdr->e_shoff + (ehdr->e_shnum*ehdr->e_shentsize)) > image_len ) 4.131 { 4.132 printk("ELF section headers extend beyond end of image.\n"); 4.133 return -EINVAL; 4.134 @@ -50,64 +141,71 @@ int parseelfimage(struct domain_setup_in 4.135 printk("ELF image has no section-header strings table (shstrtab).\n"); 4.136 return -EINVAL; 4.137 } 4.138 - shdr = (Elf_Shdr *)(elfbase + ehdr->e_shoff + 4.139 + shdr = (Elf_Shdr *)(image + ehdr->e_shoff + 4.140 (ehdr->e_shstrndx*ehdr->e_shentsize)); 4.141 - shstrtab = elfbase + shdr->sh_offset; 4.142 - 4.143 - /* Find the special '__xen_guest' section and check its contents. */ 4.144 + shstrtab = image + shdr->sh_offset; 4.145 + 4.146 + dsi->__elfnote_section = NULL; 4.147 + 4.148 + /* Look for .notes segment containing at least one Xen note */ 4.149 for ( h = 0; h < ehdr->e_shnum; h++ ) 4.150 { 4.151 - shdr = (Elf_Shdr *)(elfbase + ehdr->e_shoff + (h*ehdr->e_shentsize)); 4.152 - if ( strcmp(&shstrtab[shdr->sh_name], "__xen_guest") != 0 ) 4.153 + shdr = (Elf_Shdr *)(image + ehdr->e_shoff + (h*ehdr->e_shentsize)); 4.154 + if ( !is_xen_elfnote_section(image, shdr) ) 4.155 continue; 4.156 - 4.157 - guestinfo = elfbase + shdr->sh_offset; 4.158 + dsi->__elfnote_section = (void *)image + shdr->sh_offset; 4.159 + dsi->__elfnote_section_end = 4.160 + (void *)image + shdr->sh_offset + shdr->sh_size; 4.161 + break; 4.162 + } 4.163 4.164 - if ( (strstr(guestinfo, "LOADER=generic") == NULL) && 4.165 - (strstr(guestinfo, "GUEST_OS=linux") == NULL) ) 4.166 + /* Check the contents of the Xen notes. */ 4.167 + if ( dsi->__elfnote_section ) 4.168 + { 4.169 + const char *loader = xen_elfnote_string(dsi, XEN_ELFNOTE_LOADER); 4.170 + const char *guest_os = xen_elfnote_string(dsi, XEN_ELFNOTE_GUEST_OS); 4.171 + const char *xen_version = 4.172 + xen_elfnote_string(dsi, XEN_ELFNOTE_XEN_VERSION); 4.173 + 4.174 + if ( ( loader == NULL || strcmp(loader, "generic") ) && 4.175 + ( guest_os == NULL || strcmp(guest_os, "linux") ) ) 4.176 { 4.177 - printk("ERROR: Xen will only load images built for the generic " 4.178 - "loader or Linux images\n"); 4.179 + printk("ERROR: Will only load images built for the generic " 4.180 + "loader or Linux images"); 4.181 return -EINVAL; 4.182 } 4.183 4.184 - if ( (strstr(guestinfo, "XEN_VER=xen-3.0") == NULL) ) 4.185 + if ( xen_version == NULL || strcmp(xen_version, "xen-3.0") ) 4.186 { 4.187 printk("ERROR: Xen will only load images built for Xen v3.0\n"); 4.188 - return -EINVAL; 4.189 } 4.190 - 4.191 - break; 4.192 } 4.193 4.194 - dsi->xen_section_string = guestinfo; 4.195 - 4.196 - if ( guestinfo == NULL ) 4.197 - guestinfo = ""; 4.198 + /* Initial guess for v_start is 0 if it is not explicitly defined. */ 4.199 + dsi->v_start = 4.200 + xen_elfnote_numeric(dsi, XEN_ELFNOTE_VIRT_BASE, &virt_base_defined); 4.201 + if ( !virt_base_defined ) 4.202 + dsi->v_start = 0; 4.203 4.204 - /* Initial guess for virt_base is 0 if it is not explicitly defined. */ 4.205 - p = strstr(guestinfo, "VIRT_BASE="); 4.206 - virt_base_defined = (p != NULL); 4.207 - virt_base = virt_base_defined ? simple_strtoul(p+10, &p, 0) : 0; 4.208 - 4.209 - /* Initial guess for elf_pa_off is virt_base if not explicitly defined. */ 4.210 - p = strstr(guestinfo, "ELF_PADDR_OFFSET="); 4.211 - elf_pa_off_defined = (p != NULL); 4.212 - elf_pa_off = elf_pa_off_defined ? simple_strtoul(p+17, &p, 0) : virt_base; 4.213 + /* We are using the ELF notes interface so the default is 0. */ 4.214 + dsi->elf_paddr_offset = 4.215 + xen_elfnote_numeric(dsi, XEN_ELFNOTE_PADDR_OFFSET, &elf_pa_off_defined); 4.216 + if ( !elf_pa_off_defined ) 4.217 + dsi->elf_paddr_offset = 0; 4.218 4.219 if ( elf_pa_off_defined && !virt_base_defined ) 4.220 { 4.221 printk("ERROR: Neither ELF_PADDR_OFFSET nor VIRT_BASE found in" 4.222 - " __xen_guest section.\n"); 4.223 + " Xen ELF notes.\n"); 4.224 return -EINVAL; 4.225 } 4.226 4.227 for ( h = 0; h < ehdr->e_phnum; h++ ) 4.228 { 4.229 - phdr = (Elf_Phdr *)(elfbase + ehdr->e_phoff + (h*ehdr->e_phentsize)); 4.230 + phdr = (Elf_Phdr *)(image + ehdr->e_phoff + (h*ehdr->e_phentsize)); 4.231 if ( !is_loadable_phdr(phdr) ) 4.232 continue; 4.233 - vaddr = phdr->p_paddr - elf_pa_off + virt_base; 4.234 + vaddr = phdr->p_paddr - dsi->elf_paddr_offset + dsi->v_start; 4.235 if ( (vaddr + phdr->p_memsz) < vaddr ) 4.236 { 4.237 printk("ERROR: ELF program header %d is too large.\n", h); 4.238 @@ -120,19 +218,13 @@ int parseelfimage(struct domain_setup_in 4.239 kernend = vaddr + phdr->p_memsz; 4.240 } 4.241 4.242 - /* 4.243 - * Legacy compatibility and images with no __xen_guest section: assume 4.244 - * header addresses are virtual addresses, and that guest memory should be 4.245 - * mapped starting at kernel load address. 4.246 - */ 4.247 - dsi->v_start = virt_base_defined ? virt_base : kernstart; 4.248 - dsi->elf_paddr_offset = elf_pa_off_defined ? elf_pa_off : dsi->v_start; 4.249 + dsi->v_kernentry = ehdr->e_entry; 4.250 + virt_entry = 4.251 + xen_elfnote_numeric(dsi, XEN_ELFNOTE_ENTRY, &virt_entry_defined); 4.252 + if ( virt_entry_defined ) 4.253 + dsi->v_kernentry = virt_entry; 4.254 4.255 - dsi->v_kernentry = ehdr->e_entry; 4.256 - if ( (p = strstr(guestinfo, "VIRT_ENTRY=")) != NULL ) 4.257 - dsi->v_kernentry = simple_strtoul(p+11, &p, 0); 4.258 - 4.259 - if ( (kernstart > kernend) || 4.260 + if ( (kernstart > kernend) || 4.261 (dsi->v_kernentry < kernstart) || 4.262 (dsi->v_kernentry > kernend) || 4.263 (dsi->v_start > kernstart) ) 4.264 @@ -141,8 +233,9 @@ int parseelfimage(struct domain_setup_in 4.265 return -EINVAL; 4.266 } 4.267 4.268 - if ( (p = strstr(guestinfo, "BSD_SYMTAB")) != NULL ) 4.269 - dsi->load_symtab = 1; 4.270 + p = xen_elfnote_string(dsi, XEN_ELFNOTE_BSD_SYMTAB); 4.271 + if ( p != NULL && strcmp(p, "yes") == 0 ) 4.272 + dsi->load_symtab = 1; 4.273 4.274 dsi->v_kernstart = kernstart; 4.275 dsi->v_kernend = kernend; 4.276 @@ -155,7 +248,7 @@ int parseelfimage(struct domain_setup_in 4.277 4.278 int loadelfimage(struct domain_setup_info *dsi) 4.279 { 4.280 - char *elfbase = (char *)dsi->image_addr; 4.281 + char *image = (char *)dsi->image_addr; 4.282 Elf_Ehdr *ehdr = (Elf_Ehdr *)dsi->image_addr; 4.283 Elf_Phdr *phdr; 4.284 unsigned long vaddr; 4.285 @@ -163,12 +256,12 @@ int loadelfimage(struct domain_setup_inf 4.286 4.287 for ( h = 0; h < ehdr->e_phnum; h++ ) 4.288 { 4.289 - phdr = (Elf_Phdr *)(elfbase + ehdr->e_phoff + (h*ehdr->e_phentsize)); 4.290 + phdr = (Elf_Phdr *)(image + ehdr->e_phoff + (h*ehdr->e_phentsize)); 4.291 if ( !is_loadable_phdr(phdr) ) 4.292 continue; 4.293 vaddr = phdr->p_paddr - dsi->elf_paddr_offset + dsi->v_start; 4.294 if ( phdr->p_filesz != 0 ) 4.295 - memcpy((char *)vaddr, elfbase + phdr->p_offset, phdr->p_filesz); 4.296 + memcpy((char *)vaddr, image + phdr->p_offset, phdr->p_filesz); 4.297 if ( phdr->p_memsz > phdr->p_filesz ) 4.298 memset((char *)vaddr + phdr->p_filesz, 0, 4.299 phdr->p_memsz - phdr->p_filesz); 4.300 @@ -186,7 +279,7 @@ static void loadelfsymtab(struct domain_ 4.301 Elf_Ehdr *ehdr = (Elf_Ehdr *)dsi->image_addr, *sym_ehdr; 4.302 Elf_Shdr *shdr; 4.303 unsigned long maxva, symva; 4.304 - char *p, *elfbase = (char *)dsi->image_addr; 4.305 + char *p, *image = (char *)dsi->image_addr; 4.306 int h, i; 4.307 4.308 if ( !dsi->load_symtab ) 4.309 @@ -203,12 +296,12 @@ static void loadelfsymtab(struct domain_ 4.310 { 4.311 p = (void *)symva; 4.312 shdr = (Elf_Shdr *)(p + sizeof(int) + sizeof(Elf_Ehdr)); 4.313 - memcpy(shdr, elfbase + ehdr->e_shoff, ehdr->e_shnum*sizeof(Elf_Shdr)); 4.314 + memcpy(shdr, image + ehdr->e_shoff, ehdr->e_shnum*sizeof(Elf_Shdr)); 4.315 } 4.316 else 4.317 { 4.318 p = NULL; 4.319 - shdr = (Elf_Shdr *)(elfbase + ehdr->e_shoff); 4.320 + shdr = (Elf_Shdr *)(image + ehdr->e_shoff); 4.321 } 4.322 4.323 for ( h = 0; h < ehdr->e_shnum; h++ ) 4.324 @@ -234,7 +327,7 @@ static void loadelfsymtab(struct domain_ 4.325 (shdr[h].sh_type == SHT_SYMTAB) ) 4.326 { 4.327 if (doload) { 4.328 - memcpy((void *)maxva, elfbase + shdr[h].sh_offset, 4.329 + memcpy((void *)maxva, image + shdr[h].sh_offset, 4.330 shdr[h].sh_size); 4.331 4.332 /* Mangled to be based on ELF header location. */
5.1 --- a/xen/include/xen/elf.h Wed Aug 23 14:37:39 2006 +0100 5.2 +++ b/xen/include/xen/elf.h Wed Aug 23 14:41:05 2006 +0100 5.3 @@ -529,6 +529,10 @@ struct domain_setup_info; 5.4 extern int loadelfimage(struct domain_setup_info *); 5.5 extern int parseelfimage(struct domain_setup_info *); 5.6 5.7 +extern unsigned long long xen_elfnote_numeric(struct domain_setup_info *dsi, 5.8 + int type, int *defined); 5.9 +extern const char *xen_elfnote_string(struct domain_setup_info *dsi, int type); 5.10 + 5.11 #ifdef Elf_Ehdr 5.12 extern int elf_sanity_check(Elf_Ehdr *ehdr); 5.13 #endif
6.1 --- a/xen/include/xen/sched.h Wed Aug 23 14:37:39 2006 +0100 6.2 +++ b/xen/include/xen/sched.h Wed Aug 23 14:41:05 2006 +0100 6.3 @@ -185,7 +185,7 @@ struct domain_setup_info 6.4 unsigned long symtab_addr; 6.5 unsigned long symtab_len; 6.6 /* Indicate whether it's xen specific image */ 6.7 - char *xen_section_string; 6.8 + void *__elfnote_section, *__elfnote_section_end; 6.9 }; 6.10 6.11 extern struct vcpu *idle_vcpu[NR_CPUS];