debuggers.hg
changeset 11275:d57b174adfd6
[TOOLS] Allow tools to load kernels which use an ELF notes segment.
Compatability with kernels using the __xen_guest section is retained.
Signed-off-by: Ian Campbell <ian.campbell@xensource.com>
Compatability with kernels using the __xen_guest section is retained.
Signed-off-by: Ian Campbell <ian.campbell@xensource.com>
author | Ian Campbell <ian.campbell@xensource.com> |
---|---|
date | Wed Aug 23 14:37:39 2006 +0100 (2006-08-23) |
parents | 7ca72a1c4182 |
children | faadbf5ba8d6 |
files | tools/libxc/xc_linux_build.c tools/libxc/xc_load_bin.c tools/libxc/xc_load_elf.c tools/libxc/xg_private.h |
line diff
1.1 --- a/tools/libxc/xc_linux_build.c Wed Aug 23 14:36:09 2006 +0100 1.2 +++ b/tools/libxc/xc_linux_build.c Wed Aug 23 14:37:39 2006 +0100 1.3 @@ -655,11 +655,13 @@ static int setup_guest(int xc_handle, 1.4 uint32_t required_features[XENFEAT_NR_SUBMAPS]) 1.5 { 1.6 xen_pfn_t *page_array = NULL; 1.7 - unsigned long count, i, hypercall_pfn; 1.8 + unsigned long count, i; 1.9 + unsigned long long hypercall_page; 1.10 + int hypercall_page_defined; 1.11 start_info_t *start_info; 1.12 shared_info_t *shared_info; 1.13 xc_mmu_t *mmu = NULL; 1.14 - char *p; 1.15 + const char *p; 1.16 DECLARE_DOM0_OP; 1.17 int rc; 1.18 1.19 @@ -704,12 +706,9 @@ static int setup_guest(int xc_handle, 1.20 goto error_out; 1.21 1.22 /* Parse and validate kernel features. */ 1.23 - p = strstr(dsi.xen_guest_string, "FEATURES="); 1.24 - if ( p != NULL ) 1.25 + if ( (p = xen_elfnote_string(&dsi, XEN_ELFNOTE_FEATURES)) != NULL ) 1.26 { 1.27 - if ( !parse_features(p + strlen("FEATURES="), 1.28 - supported_features, 1.29 - required_features) ) 1.30 + if ( !parse_features(p, supported_features, required_features) ) 1.31 { 1.32 ERROR("Failed to parse guest kernel features."); 1.33 goto error_out; 1.34 @@ -1071,16 +1070,16 @@ static int setup_guest(int xc_handle, 1.35 if ( xc_finish_mmu_updates(xc_handle, mmu) ) 1.36 goto error_out; 1.37 1.38 - p = strstr(dsi.xen_guest_string, "HYPERCALL_PAGE="); 1.39 - if ( p != NULL ) 1.40 + hypercall_page = xen_elfnote_numeric(&dsi, XEN_ELFNOTE_HYPERCALL_PAGE, 1.41 + &hypercall_page_defined); 1.42 + if ( hypercall_page_defined ) 1.43 { 1.44 - p += strlen("HYPERCALL_PAGE="); 1.45 - hypercall_pfn = strtoul(p, NULL, 16); 1.46 - if ( hypercall_pfn >= nr_pages ) 1.47 + unsigned long long pfn = (hypercall_page - dsi.v_start) >> PAGE_SHIFT; 1.48 + if ( pfn >= nr_pages ) 1.49 goto error_out; 1.50 op.u.hypercall_init.domain = (domid_t)dom; 1.51 op.u.hypercall_init.gmfn = shadow_mode_enabled ? 1.52 - hypercall_pfn : page_array[hypercall_pfn]; 1.53 + pfn : page_array[pfn]; 1.54 op.cmd = DOM0_HYPERCALL_INIT; 1.55 if ( xc_dom0_op(xc_handle, &op) ) 1.56 goto error_out;
2.1 --- a/tools/libxc/xc_load_bin.c Wed Aug 23 14:36:09 2006 +0100 2.2 +++ b/tools/libxc/xc_load_bin.c Wed Aug 23 14:37:39 2006 +0100 2.3 @@ -227,7 +227,7 @@ static int parsebinimage(const char *ima 2.4 dsi->v_kernstart = dsi->v_start; 2.5 dsi->v_kernend = dsi->v_end; 2.6 dsi->v_kernentry = image_info->entry_addr; 2.7 - dsi->xen_guest_string = ""; 2.8 + dsi->__xen_guest_string = ""; 2.9 2.10 return 0; 2.11 }
3.1 --- a/tools/libxc/xc_load_elf.c Wed Aug 23 14:36:09 2006 +0100 3.2 +++ b/tools/libxc/xc_load_elf.c Wed Aug 23 14:37:39 2006 +0100 3.3 @@ -5,6 +5,7 @@ 3.4 #include "xg_private.h" 3.5 #include "xc_elf.h" 3.6 #include <stdlib.h> 3.7 +#include <inttypes.h> 3.8 3.9 #define round_pgup(_p) (((_p)+(PAGE_SIZE-1))&PAGE_MASK) 3.10 #define round_pgdown(_p) ((_p)&PAGE_MASK) 3.11 @@ -65,17 +66,190 @@ static inline int is_loadable_phdr(Elf_P 3.12 ((phdr->p_flags & (PF_W|PF_X)) != 0)); 3.13 } 3.14 3.15 +/* 3.16 + * Fallback for kernels containing only the legacy __xen_guest string 3.17 + * and no ELF notes. 3.18 + */ 3.19 +static int is_xen_guest_section(Elf_Shdr *shdr, const char *shstrtab) 3.20 +{ 3.21 + return strcmp(&shstrtab[shdr->sh_name], "__xen_guest") == 0; 3.22 +} 3.23 + 3.24 +static const char *xen_guest_lookup(struct domain_setup_info *dsi, int type) 3.25 +{ 3.26 + const char *xenguest_fallbacks[] = { 3.27 + [XEN_ELFNOTE_ENTRY] = "VIRT_ENTRY=", 3.28 + [XEN_ELFNOTE_HYPERCALL_PAGE] = "HYPERCALL_PAGE=", 3.29 + [XEN_ELFNOTE_VIRT_BASE] = "VIRT_BASE=", 3.30 + [XEN_ELFNOTE_PADDR_OFFSET] = "ELF_PADDR_OFFSET=", 3.31 + [XEN_ELFNOTE_XEN_VERSION] = "XEN_VER=", 3.32 + [XEN_ELFNOTE_GUEST_OS] = "GUEST_OS=", 3.33 + [XEN_ELFNOTE_GUEST_VERSION] = "GUEST_VER=", 3.34 + [XEN_ELFNOTE_LOADER] = "LOADER=", 3.35 + [XEN_ELFNOTE_PAE_MODE] = "PAE=", 3.36 + [XEN_ELFNOTE_FEATURES] = "FEATURES=", 3.37 + [XEN_ELFNOTE_BSD_SYMTAB] = "BSD_SYMTAB=", 3.38 + }; 3.39 + const char *fallback; 3.40 + const char *p; 3.41 + 3.42 + if ( type > sizeof(xenguest_fallbacks) ) 3.43 + return NULL; 3.44 + 3.45 + if ( (fallback = xenguest_fallbacks[type]) == NULL ) 3.46 + return NULL; 3.47 + 3.48 + if ( (p = strstr(dsi->__xen_guest_string,fallback)) == NULL ) 3.49 + return NULL; 3.50 + 3.51 + return p + strlen(fallback); 3.52 +} 3.53 + 3.54 +static const char *xen_guest_string(struct domain_setup_info *dsi, int type) 3.55 +{ 3.56 + const char *p = xen_guest_lookup(dsi, type); 3.57 + 3.58 + DPRINTF("found __xen_guest entry for type %#x = \"%s\"\n", 3.59 + type, p); 3.60 + 3.61 + /* 3.62 + * We special case this since the __xen_guest_section treats the 3.63 + * mere precense of the BSD_SYMTAB string as true or false. 3.64 + */ 3.65 + if ( type == XEN_ELFNOTE_BSD_SYMTAB ) 3.66 + return p ? "yes" : "no"; 3.67 + return p; 3.68 +} 3.69 + 3.70 +static unsigned long long xen_guest_numeric(struct domain_setup_info *dsi, 3.71 + int type, int *defined) 3.72 +{ 3.73 + const char *p = xen_guest_lookup(dsi, type); 3.74 + unsigned long long value; 3.75 + 3.76 + if ( p == NULL ) 3.77 + return 0; 3.78 + 3.79 + errno = 0; 3.80 + value = strtoull(p, NULL, 0); 3.81 + if ( errno < 0 ) 3.82 + return 0; 3.83 + 3.84 + /* We special case this since __xen_guest_section contains a PFN 3.85 + * for this field not a virtual address. 3.86 + */ 3.87 + if (type == XEN_ELFNOTE_HYPERCALL_PAGE) 3.88 + value = dsi->v_start + (value<<PAGE_SHIFT); 3.89 + 3.90 + DPRINTF("found __xen_guest entry for type %#x = %#llx\n", 3.91 + type, value); 3.92 + 3.93 + *defined = 1; 3.94 + return value; 3.95 +} 3.96 + 3.97 +/* 3.98 + * Interface to the Xen ELF notes. 3.99 + */ 3.100 +#define ELFNOTE_NAME(_n_) ((void*)(_n_) + sizeof(*(_n_))) 3.101 +#define ELFNOTE_DESC(_n_) (ELFNOTE_NAME(_n_) + (((_n_)->namesz+3)&~3)) 3.102 +#define ELFNOTE_NEXT(_n_) (ELFNOTE_DESC(_n_) + (((_n_)->descsz+3)&~3)) 3.103 + 3.104 +static int is_xen_elfnote_section(const char *image, Elf_Shdr *shdr) 3.105 +{ 3.106 + Elf_Note *note; 3.107 + 3.108 + if ( shdr->sh_type != SHT_NOTE ) 3.109 + return 0; 3.110 + 3.111 + for ( note = (Elf_Note *)(image + shdr->sh_offset); 3.112 + note < (Elf_Note *)(image + shdr->sh_offset + shdr->sh_size); 3.113 + note = ELFNOTE_NEXT(note) ) 3.114 + { 3.115 + if ( !strncmp(ELFNOTE_NAME(note), "Xen", 4) ) 3.116 + return 1; 3.117 + } 3.118 + 3.119 + return 0; 3.120 +} 3.121 + 3.122 +static Elf_Note *xen_elfnote_lookup(struct domain_setup_info *dsi, int type) 3.123 +{ 3.124 + Elf_Note *note; 3.125 + 3.126 + for ( note = (Elf_Note *)dsi->__elfnote_section; 3.127 + note < (Elf_Note *)dsi->__elfnote_section_end; 3.128 + note = ELFNOTE_NEXT(note) ) 3.129 + { 3.130 + if ( strncmp(ELFNOTE_NAME(note), "Xen", 4) ) 3.131 + continue; 3.132 + 3.133 + if ( note->type == type ) 3.134 + return note; 3.135 + } 3.136 + 3.137 + DPRINTF("unable to find Xen ELF note with type %#x\n", type); 3.138 + return NULL; 3.139 +} 3.140 + 3.141 +const char *xen_elfnote_string(struct domain_setup_info *dsi, int type) 3.142 +{ 3.143 + Elf_Note *note; 3.144 + 3.145 + if ( !dsi->__elfnote_section ) 3.146 + return xen_guest_string(dsi, type); 3.147 + 3.148 + note = xen_elfnote_lookup(dsi, type); 3.149 + if ( note == NULL ) 3.150 + return NULL; 3.151 + 3.152 + DPRINTF("found Xen ELF note type %#x = \"%s\"\n", 3.153 + type, (char *)ELFNOTE_DESC(note)); 3.154 + 3.155 + return (const char *)ELFNOTE_DESC(note); 3.156 +} 3.157 + 3.158 +unsigned long long xen_elfnote_numeric(struct domain_setup_info *dsi, 3.159 + int type, int *defined) 3.160 +{ 3.161 + Elf_Note *note; 3.162 + 3.163 + *defined = 0; 3.164 + 3.165 + if ( !dsi->__elfnote_section ) 3.166 + return xen_guest_numeric(dsi, type, defined); 3.167 + 3.168 + note = xen_elfnote_lookup(dsi, type); 3.169 + if ( note == NULL ) 3.170 + { 3.171 + return 0; 3.172 + } 3.173 + 3.174 + switch ( note->descsz ) 3.175 + { 3.176 + case 4: 3.177 + *defined = 1; 3.178 + return *(uint32_t*)ELFNOTE_DESC(note); 3.179 + case 8: 3.180 + *defined = 1; 3.181 + return *(uint64_t*)ELFNOTE_DESC(note); 3.182 + default: 3.183 + ERROR("elfnotes: unknown data size %#x for numeric type note %#x\n", 3.184 + note->descsz, type); 3.185 + return 0; 3.186 + } 3.187 +} 3.188 + 3.189 static int parseelfimage(const char *image, 3.190 - unsigned long elfsize, 3.191 + unsigned long image_len, 3.192 struct domain_setup_info *dsi) 3.193 { 3.194 Elf_Ehdr *ehdr = (Elf_Ehdr *)image; 3.195 Elf_Phdr *phdr; 3.196 Elf_Shdr *shdr; 3.197 - Elf_Addr kernstart = ~0, kernend = 0, vaddr, virt_base, elf_pa_off; 3.198 - const char *shstrtab; 3.199 - char *guestinfo=NULL, *p; 3.200 - int h, virt_base_defined, elf_pa_off_defined; 3.201 + Elf_Addr kernstart = ~0, kernend = 0, vaddr, virt_entry; 3.202 + const char *shstrtab, *p; 3.203 + int h, virt_base_defined, elf_pa_off_defined, virt_entry_defined; 3.204 3.205 if ( !IS_ELF(*ehdr) ) 3.206 { 3.207 @@ -92,13 +266,13 @@ static int parseelfimage(const char *ima 3.208 return -EINVAL; 3.209 } 3.210 3.211 - if ( (ehdr->e_phoff + (ehdr->e_phnum * ehdr->e_phentsize)) > elfsize ) 3.212 + if ( (ehdr->e_phoff + (ehdr->e_phnum*ehdr->e_phentsize)) > image_len ) 3.213 { 3.214 ERROR("ELF program headers extend beyond end of image."); 3.215 return -EINVAL; 3.216 } 3.217 3.218 - if ( (ehdr->e_shoff + (ehdr->e_shnum * ehdr->e_shentsize)) > elfsize ) 3.219 + if ( (ehdr->e_shoff + (ehdr->e_shnum*ehdr->e_shentsize)) > image_len ) 3.220 { 3.221 ERROR("ELF section headers extend beyond end of image."); 3.222 return -EINVAL; 3.223 @@ -114,69 +288,119 @@ static int parseelfimage(const char *ima 3.224 (ehdr->e_shstrndx*ehdr->e_shentsize)); 3.225 shstrtab = image + shdr->sh_offset; 3.226 3.227 - /* Find the special '__xen_guest' section and check its contents. */ 3.228 + dsi->__elfnote_section = NULL; 3.229 + dsi->__xen_guest_string = NULL; 3.230 + 3.231 + /* Look for .notes segment containing at least one Xen note */ 3.232 for ( h = 0; h < ehdr->e_shnum; h++ ) 3.233 { 3.234 shdr = (Elf_Shdr *)(image + ehdr->e_shoff + (h*ehdr->e_shentsize)); 3.235 - if ( strcmp(&shstrtab[shdr->sh_name], "__xen_guest") != 0 ) 3.236 + if ( !is_xen_elfnote_section(image, shdr) ) 3.237 continue; 3.238 + DPRINTF("found note section containing Xen entries\n"); 3.239 + dsi->__elfnote_section = (void *)image + shdr->sh_offset; 3.240 + dsi->__elfnote_section_end = 3.241 + (void *)image + shdr->sh_offset + shdr->sh_size; 3.242 + break; 3.243 + } 3.244 3.245 - guestinfo = (char *)image + shdr->sh_offset; 3.246 + /* Fall back to looking for the special '__xen_guest' section. */ 3.247 + if ( dsi->__elfnote_section == NULL ) 3.248 + { 3.249 + for ( h = 0; h < ehdr->e_shnum; h++ ) 3.250 + { 3.251 + shdr = (Elf_Shdr *)(image + ehdr->e_shoff + (h*ehdr->e_shentsize)); 3.252 + if ( is_xen_guest_section(shdr, shstrtab) ) 3.253 + { 3.254 + DPRINTF("found a legacy __xen_guest section\n"); 3.255 + dsi->__xen_guest_string = (char *)image + shdr->sh_offset; 3.256 + break; 3.257 + } 3.258 + } 3.259 + } 3.260 3.261 - if ( (strstr(guestinfo, "LOADER=generic") == NULL) && 3.262 - (strstr(guestinfo, "GUEST_OS=linux") == NULL) ) 3.263 + /* Check the contents of the Xen notes or guest string. */ 3.264 + if ( dsi->__elfnote_section || dsi->__xen_guest_string ) 3.265 + { 3.266 + const char *loader = xen_elfnote_string(dsi, XEN_ELFNOTE_LOADER); 3.267 + const char *guest_os = xen_elfnote_string(dsi, XEN_ELFNOTE_GUEST_OS); 3.268 + const char *xen_version = 3.269 + xen_elfnote_string(dsi, XEN_ELFNOTE_XEN_VERSION); 3.270 + 3.271 + if ( ( loader == NULL || strncmp(loader, "generic", 7) ) && 3.272 + ( guest_os == NULL || strncmp(guest_os, "linux", 5) ) ) 3.273 { 3.274 ERROR("Will only load images built for the generic loader " 3.275 "or Linux images"); 3.276 - ERROR("Actually saw: '%s'", guestinfo); 3.277 return -EINVAL; 3.278 } 3.279 3.280 - if ( (strstr(guestinfo, "XEN_VER=xen-3.0") == NULL) ) 3.281 + if ( xen_version == NULL || strncmp(xen_version, "xen-3.0", 7) ) 3.282 { 3.283 ERROR("Will only load images built for Xen v3.0"); 3.284 - ERROR("Actually saw: '%s'", guestinfo); 3.285 return -EINVAL; 3.286 } 3.287 - 3.288 - dsi->pae_kernel = PAEKERN_no; 3.289 - p = strstr(guestinfo, "PAE=yes"); 3.290 - if ( p != NULL ) 3.291 - { 3.292 - dsi->pae_kernel = PAEKERN_yes; 3.293 - if ( !strncmp(p+7, "[extended-cr3]", 14) ) 3.294 - dsi->pae_kernel = PAEKERN_extended_cr3; 3.295 - } 3.296 - 3.297 - break; 3.298 } 3.299 - 3.300 - if ( guestinfo == NULL ) 3.301 + else 3.302 { 3.303 #ifdef __ia64__ 3.304 - guestinfo = ""; 3.305 + dsi->__elfnote_section = NULL; 3.306 + dsi->__xen_guest_string = ""; 3.307 #else 3.308 - ERROR("Not a Xen-ELF image: '__xen_guest' section not found."); 3.309 + ERROR("Not a Xen-ELF image: " 3.310 + "No ELF notes or '__xen_guest' section found."); 3.311 return -EINVAL; 3.312 #endif 3.313 } 3.314 3.315 - dsi->xen_guest_string = guestinfo; 3.316 + dsi->pae_kernel = PAEKERN_no; 3.317 + if ( dsi->__elfnote_section ) 3.318 + { 3.319 + p = xen_elfnote_string(dsi, XEN_ELFNOTE_PAE_MODE); 3.320 + if ( p != NULL && strncmp(p, "yes", 3) == 0 ) 3.321 + dsi->pae_kernel = PAEKERN_extended_cr3; 3.322 + 3.323 + } 3.324 + else 3.325 + { 3.326 + p = xen_guest_lookup(dsi, XEN_ELFNOTE_PAE_MODE); 3.327 + if ( p != NULL && strncmp(p, "yes", 3) == 0 ) 3.328 + { 3.329 + dsi->pae_kernel = PAEKERN_yes; 3.330 + if ( !strncmp(p+4, "[extended-cr3]", 14) ) 3.331 + dsi->pae_kernel = PAEKERN_extended_cr3; 3.332 + } 3.333 + } 3.334 3.335 - /* Initial guess for virt_base is 0 if it is not explicitly defined. */ 3.336 - p = strstr(guestinfo, "VIRT_BASE="); 3.337 - virt_base_defined = (p != NULL); 3.338 - virt_base = virt_base_defined ? strtoull(p+10, &p, 0) : 0; 3.339 + /* Initial guess for v_start is 0 if it is not explicitly defined. */ 3.340 + dsi->v_start = 3.341 + xen_elfnote_numeric(dsi, XEN_ELFNOTE_VIRT_BASE, &virt_base_defined); 3.342 + if ( !virt_base_defined ) 3.343 + dsi->v_start = 0; 3.344 3.345 - /* Initial guess for elf_pa_off is virt_base if not explicitly defined. */ 3.346 - p = strstr(guestinfo, "ELF_PADDR_OFFSET="); 3.347 - elf_pa_off_defined = (p != NULL); 3.348 - elf_pa_off = elf_pa_off_defined ? strtoull(p+17, &p, 0) : virt_base; 3.349 + /* 3.350 + * If we are using the legacy __xen_guest section then elf_pa_off 3.351 + * defaults to v_start in order to maintain compatibility with 3.352 + * older hypervisors which set padd in the ELF header to 3.353 + * virt_base. 3.354 + * 3.355 + * If we are using the modern ELF notes interface then the default 3.356 + * is 0. 3.357 + */ 3.358 + dsi->elf_paddr_offset = 3.359 + xen_elfnote_numeric(dsi, XEN_ELFNOTE_PADDR_OFFSET, &elf_pa_off_defined); 3.360 + if ( !elf_pa_off_defined ) 3.361 + { 3.362 + if ( dsi->__elfnote_section ) 3.363 + dsi->elf_paddr_offset = 0; 3.364 + else 3.365 + dsi->elf_paddr_offset = dsi->v_start; 3.366 + } 3.367 3.368 if ( elf_pa_off_defined && !virt_base_defined ) 3.369 { 3.370 - ERROR("Neither ELF_PADDR_OFFSET nor VIRT_BASE found in __xen_guest" 3.371 - " section."); 3.372 + ERROR("Neither ELF_PADDR_OFFSET nor VIRT_BASE found in ELF " 3.373 + " notes or __xen_guest section."); 3.374 return -EINVAL; 3.375 } 3.376 3.377 @@ -185,7 +409,7 @@ static int parseelfimage(const char *ima 3.378 phdr = (Elf_Phdr *)(image + ehdr->e_phoff + (h*ehdr->e_phentsize)); 3.379 if ( !is_loadable_phdr(phdr) ) 3.380 continue; 3.381 - vaddr = phdr->p_paddr - elf_pa_off + virt_base; 3.382 + vaddr = phdr->p_paddr - dsi->elf_paddr_offset + dsi->v_start; 3.383 if ( (vaddr + phdr->p_memsz) < vaddr ) 3.384 { 3.385 ERROR("ELF program header %d is too large.", h); 3.386 @@ -198,17 +422,12 @@ static int parseelfimage(const char *ima 3.387 kernend = vaddr + phdr->p_memsz; 3.388 } 3.389 3.390 - /* 3.391 - * Legacy compatibility and images with no __xen_guest section: assume 3.392 - * header addresses are virtual addresses, and that guest memory should be 3.393 - * mapped starting at kernel load address. 3.394 - */ 3.395 - dsi->v_start = virt_base_defined ? virt_base : kernstart; 3.396 - dsi->elf_paddr_offset = elf_pa_off_defined ? elf_pa_off : dsi->v_start; 3.397 + dsi->v_kernentry = ehdr->e_entry; 3.398 3.399 - dsi->v_kernentry = ehdr->e_entry; 3.400 - if ( (p = strstr(guestinfo, "VIRT_ENTRY=")) != NULL ) 3.401 - dsi->v_kernentry = strtoull(p+11, &p, 0); 3.402 + virt_entry = 3.403 + xen_elfnote_numeric(dsi, XEN_ELFNOTE_ENTRY, &virt_entry_defined); 3.404 + if ( virt_entry_defined ) 3.405 + dsi->v_kernentry = virt_entry; 3.406 3.407 if ( (kernstart > kernend) || 3.408 (dsi->v_kernentry < kernstart) || 3.409 @@ -219,7 +438,8 @@ static int parseelfimage(const char *ima 3.410 return -EINVAL; 3.411 } 3.412 3.413 - if ( (p = strstr(guestinfo, "BSD_SYMTAB")) != NULL ) 3.414 + p = xen_elfnote_string(dsi, XEN_ELFNOTE_BSD_SYMTAB); 3.415 + if ( p != NULL && strncmp(p, "yes", 3) == 0 ) 3.416 dsi->load_symtab = 1; 3.417 3.418 dsi->v_kernstart = kernstart;
4.1 --- a/tools/libxc/xg_private.h Wed Aug 23 14:36:09 2006 +0100 4.2 +++ b/tools/libxc/xg_private.h Wed Aug 23 14:37:39 2006 +0100 4.3 @@ -5,6 +5,7 @@ 4.4 #include <errno.h> 4.5 #include <fcntl.h> 4.6 #include <stdio.h> 4.7 +#include <stdlib.h> 4.8 #include <string.h> 4.9 #include <sys/mman.h> 4.10 #include <sys/types.h> 4.11 @@ -16,6 +17,7 @@ 4.12 4.13 #include <xen/sys/privcmd.h> 4.14 #include <xen/memory.h> 4.15 +#include <xen/elfnote.h> 4.16 4.17 /* valgrind cannot see when a hypercall has filled in some values. For this 4.18 reason, we must zero the dom0_op_t instance before a call, if using 4.19 @@ -149,8 +151,15 @@ struct domain_setup_info 4.20 unsigned long symtab_addr; 4.21 unsigned long symtab_len; 4.22 4.23 - /* __xen_guest info string for convenient loader parsing. */ 4.24 - char *xen_guest_string; 4.25 + /* 4.26 + * Only one of __elfnote_* or __xen_guest_string will be 4.27 + * non-NULL. 4.28 + * 4.29 + * You should use the xen_elfnote_* accessors below in order to 4.30 + * pickup the correct one and retain backwards compatibility. 4.31 + */ 4.32 + void *__elfnote_section, *__elfnote_section_end; 4.33 + char *__xen_guest_string; 4.34 }; 4.35 4.36 typedef int (*parseimagefunc)(const char *image, unsigned long image_size, 4.37 @@ -160,6 +169,21 @@ typedef int (*loadimagefunc)(const char 4.38 uint32_t dom, xen_pfn_t *parray, 4.39 struct domain_setup_info *dsi); 4.40 4.41 +/* 4.42 + * If an ELF note of the given type is found then the value contained 4.43 + * in the note is returned and *defined is set to non-zero. If no such 4.44 + * note is found then *defined is set to 0 and 0 is returned. 4.45 + */ 4.46 +extern unsigned long long xen_elfnote_numeric(struct domain_setup_info *dsi, 4.47 + int type, int *defined); 4.48 + 4.49 +/* 4.50 + * If an ELF note of the given type is found then the string contained 4.51 + * in the value is returned, otherwise NULL is returned. 4.52 + */ 4.53 +extern const char * xen_elfnote_string(struct domain_setup_info *dsi, 4.54 + int type); 4.55 + 4.56 struct load_funcs 4.57 { 4.58 parseimagefunc parseimage;