debuggers.hg

view xen/common/elf.c @ 3726:88957a238191

bitkeeper revision 1.1159.1.544 (4207248crq3YxiyLWjUehtHv_Yd3tg)

Merge tempest.cl.cam.ac.uk:/auto/groups/xeno-xenod/BK/xeno.bk
into tempest.cl.cam.ac.uk:/local/scratch/smh22/xen-unstable.bk
author smh22@tempest.cl.cam.ac.uk
date Mon Feb 07 08:19:24 2005 +0000 (2005-02-07)
parents bbe8541361dd 4294cfa9fad3
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 #define ELF_ADDR p_vaddr
17 #elif defined(__ia64__)
18 #define FORCE_XENELF_IMAGE 0
19 #define ELF_ADDR p_paddr
20 #endif
22 static inline int is_loadable_phdr(Elf_Phdr *phdr)
23 {
24 return ((phdr->p_type == PT_LOAD) &&
25 ((phdr->p_flags & (PF_W|PF_X)) != 0));
26 }
28 int parseelfimage(char *elfbase,
29 unsigned long elfsize,
30 struct domain_setup_info *dsi)
31 {
32 Elf_Ehdr *ehdr = (Elf_Ehdr *)elfbase;
33 Elf_Phdr *phdr;
34 Elf_Shdr *shdr;
35 unsigned long kernstart = ~0UL, kernend=0UL;
36 char *shstrtab, *guestinfo=NULL, *p;
37 int h;
39 if ( !elf_sanity_check(ehdr) )
40 return -EINVAL;
42 if ( (ehdr->e_phoff + (ehdr->e_phnum * ehdr->e_phentsize)) > elfsize )
43 {
44 printk("ELF program headers extend beyond end of image.\n");
45 return -EINVAL;
46 }
48 if ( (ehdr->e_shoff + (ehdr->e_shnum * ehdr->e_shentsize)) > elfsize )
49 {
50 printk("ELF section headers extend beyond end of image.\n");
51 return -EINVAL;
52 }
54 /* Find the section-header strings table. */
55 if ( ehdr->e_shstrndx == SHN_UNDEF )
56 {
57 printk("ELF image has no section-header strings table (shstrtab).\n");
58 return -EINVAL;
59 }
60 shdr = (Elf_Shdr *)(elfbase + ehdr->e_shoff +
61 (ehdr->e_shstrndx*ehdr->e_shentsize));
62 shstrtab = elfbase + shdr->sh_offset;
64 /* Find the special '__xen_guest' section and check its contents. */
65 for ( h = 0; h < ehdr->e_shnum; h++ )
66 {
67 shdr = (Elf_Shdr *)(elfbase + ehdr->e_shoff + (h*ehdr->e_shentsize));
68 if ( strcmp(&shstrtab[shdr->sh_name], "__xen_guest") != 0 )
69 continue;
71 guestinfo = elfbase + shdr->sh_offset;
72 printk("Xen-ELF header found: '%s'\n", guestinfo);
74 if ( (strstr(guestinfo, "LOADER=generic") == NULL) &&
75 (strstr(guestinfo, "GUEST_OS=linux") == NULL) )
76 {
77 printk("ERROR: Xen will only load images built for the generic "
78 "loader or Linux images\n");
79 return -EINVAL;
80 }
82 if ( (strstr(guestinfo, "XEN_VER=2.0") == NULL) )
83 {
84 printk("ERROR: Xen will only load images built for Xen v2.0\n");
85 return -EINVAL;
86 }
88 break;
89 }
90 if ( guestinfo == NULL )
91 {
92 printk("Not a Xen-ELF image: '__xen_guest' section not found.\n");
93 #if FORCE_XENELF_IMAGE
94 return -EINVAL;
95 #endif
96 }
98 for ( h = 0; h < ehdr->e_phnum; h++ )
99 {
100 phdr = (Elf_Phdr *)(elfbase + ehdr->e_phoff + (h*ehdr->e_phentsize));
101 if ( !is_loadable_phdr(phdr) )
102 continue;
103 if ( phdr->ELF_ADDR < kernstart )
104 kernstart = phdr->ELF_ADDR;
105 if ( (phdr->ELF_ADDR + phdr->p_memsz) > kernend )
106 kernend = phdr->ELF_ADDR + phdr->p_memsz;
107 }
109 if ( (kernstart > kernend) ||
110 (ehdr->e_entry < kernstart) ||
111 (ehdr->e_entry > kernend) )
112 {
113 printk("Malformed ELF image.\n");
114 return -EINVAL;
115 }
117 dsi->v_start = kernstart;
119 if ( guestinfo != NULL )
120 {
121 if ( (p = strstr(guestinfo, "VIRT_BASE=")) != NULL )
122 dsi->v_start = simple_strtoul(p+10, &p, 0);
124 if ( (p = strstr(guestinfo, "PT_MODE_WRITABLE")) != NULL )
125 dsi->use_writable_pagetables = 1;
126 }
128 dsi->v_kernstart = kernstart;
129 dsi->v_kernend = kernend;
130 dsi->v_kernentry = ehdr->e_entry;
132 return 0;
133 }
135 int loadelfimage(char *elfbase)
136 {
137 Elf_Ehdr *ehdr = (Elf_Ehdr *)elfbase;
138 Elf_Phdr *phdr;
139 int h;
141 for ( h = 0; h < ehdr->e_phnum; h++ )
142 {
143 phdr = (Elf_Phdr *)(elfbase + ehdr->e_phoff + (h*ehdr->e_phentsize));
144 if ( !is_loadable_phdr(phdr) )
145 continue;
146 if ( phdr->p_filesz != 0 )
147 memcpy((char *)phdr->ELF_ADDR, elfbase + phdr->p_offset,
148 phdr->p_filesz);
149 if ( phdr->p_memsz > phdr->p_filesz )
150 memset((char *)phdr->ELF_ADDR + phdr->p_filesz, 0,
151 phdr->p_memsz - phdr->p_filesz);
152 }
154 return 0;
155 }