debuggers.hg

view xen/common/elf.c @ 3762:9db7fbdf56b6

bitkeeper revision 1.1159.212.130 (4208dde9v8U9U_7hI23vverH97_FLQ)

Merge scramble.cl.cam.ac.uk:/auto/groups/xeno/BK/xeno.bk
into scramble.cl.cam.ac.uk:/local/scratch/kaf24/xen-unstable.bk
author kaf24@scramble.cl.cam.ac.uk
date Tue Feb 08 15:42:33 2005 +0000 (2005-02-08)
parents 4294cfa9fad3 5612c06cde33
children f5f2757b3aa2
line source
1 /* -*- Mode:C; c-basic-offset:4; tab-width:4; indent-tabs-mode:nil -*- */
2 /******************************************************************************
3 * elf.c
4 *
5 * Generic Elf-loading routines.
6 */
8 #include <xen/config.h>
9 #include <xen/init.h>
10 #include <xen/lib.h>
11 #include <xen/mm.h>
12 #include <xen/elf.h>
14 #ifdef CONFIG_X86
15 #define FORCE_XENELF_IMAGE 1
16 #elif defined(__ia64__)
17 #define FORCE_XENELF_IMAGE 0
18 #endif
20 static inline int is_loadable_phdr(Elf_Phdr *phdr)
21 {
22 return ((phdr->p_type == PT_LOAD) &&
23 ((phdr->p_flags & (PF_W|PF_X)) != 0));
24 }
26 int parseelfimage(char *elfbase,
27 unsigned long elfsize,
28 struct domain_setup_info *dsi)
29 {
30 Elf_Ehdr *ehdr = (Elf_Ehdr *)elfbase;
31 Elf_Phdr *phdr;
32 Elf_Shdr *shdr;
33 unsigned long kernstart = ~0UL, kernend=0UL;
34 char *shstrtab, *guestinfo=NULL, *p;
35 int h;
37 if ( !elf_sanity_check(ehdr) )
38 return -EINVAL;
40 if ( (ehdr->e_phoff + (ehdr->e_phnum * ehdr->e_phentsize)) > elfsize )
41 {
42 printk("ELF program headers extend beyond end of image.\n");
43 return -EINVAL;
44 }
46 if ( (ehdr->e_shoff + (ehdr->e_shnum * ehdr->e_shentsize)) > elfsize )
47 {
48 printk("ELF section headers extend beyond end of image.\n");
49 return -EINVAL;
50 }
52 /* Find the section-header strings table. */
53 if ( ehdr->e_shstrndx == SHN_UNDEF )
54 {
55 printk("ELF image has no section-header strings table (shstrtab).\n");
56 return -EINVAL;
57 }
58 shdr = (Elf_Shdr *)(elfbase + ehdr->e_shoff +
59 (ehdr->e_shstrndx*ehdr->e_shentsize));
60 shstrtab = elfbase + shdr->sh_offset;
62 /* Find the special '__xen_guest' section and check its contents. */
63 for ( h = 0; h < ehdr->e_shnum; h++ )
64 {
65 shdr = (Elf_Shdr *)(elfbase + ehdr->e_shoff + (h*ehdr->e_shentsize));
66 if ( strcmp(&shstrtab[shdr->sh_name], "__xen_guest") != 0 )
67 continue;
69 guestinfo = elfbase + shdr->sh_offset;
70 printk("Xen-ELF header found: '%s'\n", guestinfo);
72 if ( (strstr(guestinfo, "LOADER=generic") == NULL) &&
73 (strstr(guestinfo, "GUEST_OS=linux") == NULL) )
74 {
75 printk("ERROR: Xen will only load images built for the generic "
76 "loader or Linux images\n");
77 return -EINVAL;
78 }
80 if ( (strstr(guestinfo, "XEN_VER=2.0") == NULL) )
81 {
82 printk("ERROR: Xen will only load images built for Xen v2.0\n");
83 return -EINVAL;
84 }
86 break;
87 }
88 if ( guestinfo == NULL )
89 {
90 printk("Not a Xen-ELF image: '__xen_guest' section not found.\n");
91 #if FORCE_XENELF_IMAGE
92 return -EINVAL;
93 #endif
94 }
96 for ( h = 0; h < ehdr->e_phnum; h++ )
97 {
98 phdr = (Elf_Phdr *)(elfbase + ehdr->e_phoff + (h*ehdr->e_phentsize));
99 if ( !is_loadable_phdr(phdr) )
100 continue;
101 if ( phdr->p_paddr < kernstart )
102 kernstart = phdr->p_paddr;
103 if ( (phdr->p_paddr + phdr->p_memsz) > kernend )
104 kernend = phdr->p_paddr + phdr->p_memsz;
105 }
107 if ( (kernstart > kernend) ||
108 (ehdr->e_entry < kernstart) ||
109 (ehdr->e_entry > kernend) )
110 {
111 printk("Malformed ELF image.\n");
112 return -EINVAL;
113 }
115 dsi->v_start = kernstart;
117 if ( guestinfo != NULL )
118 {
119 if ( (p = strstr(guestinfo, "VIRT_BASE=")) != NULL )
120 dsi->v_start = simple_strtoul(p+10, &p, 0);
122 if ( (p = strstr(guestinfo, "PT_MODE_WRITABLE")) != NULL )
123 dsi->use_writable_pagetables = 1;
124 }
126 dsi->v_kernstart = kernstart;
127 dsi->v_kernend = kernend;
128 dsi->v_kernentry = ehdr->e_entry;
130 return 0;
131 }
133 int loadelfimage(char *elfbase)
134 {
135 Elf_Ehdr *ehdr = (Elf_Ehdr *)elfbase;
136 Elf_Phdr *phdr;
137 int h;
139 for ( h = 0; h < ehdr->e_phnum; h++ )
140 {
141 phdr = (Elf_Phdr *)(elfbase + ehdr->e_phoff + (h*ehdr->e_phentsize));
142 if ( !is_loadable_phdr(phdr) )
143 continue;
144 if ( phdr->p_filesz != 0 )
145 memcpy((char *)phdr->p_paddr, elfbase + phdr->p_offset,
146 phdr->p_filesz);
147 if ( phdr->p_memsz > phdr->p_filesz )
148 memset((char *)phdr->p_paddr + phdr->p_filesz, 0,
149 phdr->p_memsz - phdr->p_filesz);
150 }
152 return 0;
153 }