ia64/xen-unstable

view tools/libxc/xc_load_aout9.c @ 7238:971e7c7411b3

Raise an exception if an error appears on the pipes to our children, and make
sure that the child's pipes are closed even under that exception. Move the
handling of POLLHUP to the end of the loop, so that we guarantee to read any
remaining data from the child if POLLHUP and POLLIN appear at the same time.

Signed-off-by: Ewan Mellor <ewan@xensource.com>
author emellor@ewan
date Thu Oct 06 10:13:11 2005 +0100 (2005-10-06)
parents 06d84bf87159
children b3a255e88810
line source
2 #include "xg_private.h"
3 #include "xc_aout9.h"
5 #if defined(__i386__)
6 #define A9_MAGIC I_MAGIC
7 #elif defined(__x86_64__)
8 #define A9_MAGIC S_MAGIC
9 #elif defined(__ia64__)
10 #define A9_MAGIC 0
11 #else
12 #error "Unsupported architecture"
13 #endif
16 #define round_pgup(_p) (((_p)+(PAGE_SIZE-1))&PAGE_MASK)
17 #define KZERO 0x80000000
18 #define KOFFSET(_p) ((_p)&~KZERO)
20 static int parseaout9image(char *, unsigned long, struct domain_setup_info *);
21 static int loadaout9image(char *, unsigned long, int, u32, unsigned long *, struct domain_setup_info *);
22 static void copyout(int, u32, unsigned long *, unsigned long, void *, int);
23 struct Exec *get_header(char *, unsigned long, struct Exec *);
26 int
27 probe_aout9(
28 char *image,
29 unsigned long image_size,
30 struct load_funcs *load_funcs)
31 {
32 struct Exec ehdr;
34 if (!get_header(image, image_size, &ehdr)) {
35 ERROR("Kernel image does not have a a.out9 header.");
36 return -EINVAL;
37 }
39 load_funcs->parseimage = parseaout9image;
40 load_funcs->loadimage = loadaout9image;
41 return 0;
42 }
44 static int
45 parseaout9image(
46 char *image,
47 unsigned long image_size,
48 struct domain_setup_info *dsi)
49 {
50 struct Exec ehdr;
51 unsigned long start, dstart, end;
53 if (!get_header(image, image_size, &ehdr)) {
54 ERROR("Kernel image does not have a a.out9 header.");
55 return -EINVAL;
56 }
58 if (sizeof ehdr + ehdr.text + ehdr.data > image_size) {
59 ERROR("a.out program extends past end of image.");
60 return -EINVAL;
61 }
63 start = ehdr.entry;
64 dstart = round_pgup(start + ehdr.text);
65 end = dstart + ehdr.data + ehdr.bss;
67 dsi->v_start = KZERO;
68 dsi->v_kernstart = start;
69 dsi->v_kernend = end;
70 dsi->v_kernentry = ehdr.entry;
71 dsi->v_end = end;
73 /* XXX load symbols */
75 return 0;
76 }
78 static int
79 loadaout9image(
80 char *image,
81 unsigned long image_size,
82 int xch, u32 dom,
83 unsigned long *parray,
84 struct domain_setup_info *dsi)
85 {
86 struct Exec ehdr;
87 unsigned long start, dstart;
89 if (!get_header(image, image_size, &ehdr)) {
90 ERROR("Kernel image does not have a a.out9 header.");
91 return -EINVAL;
92 }
94 start = ehdr.entry;
95 dstart = round_pgup(start + ehdr.text);
96 copyout(xch, dom, parray, start, image + sizeof ehdr, ehdr.text);
97 copyout(xch, dom, parray, dstart,
98 image + sizeof ehdr + ehdr.text, ehdr.data);
100 /* XXX load symbols */
102 return 0;
103 }
105 /*
106 * copyout data to the domain given an offset to the start
107 * of its memory region described by parray.
108 */
109 static void
110 copyout(
111 int xch, u32 dom,
112 unsigned long *parray,
113 unsigned long addr,
114 void *buf,
115 int sz)
116 {
117 unsigned long pgoff, chunksz, off;
118 void *pg;
120 off = KOFFSET(addr);
121 while (sz > 0) {
122 pgoff = off & (PAGE_SIZE-1);
123 chunksz = sz;
124 if(chunksz > PAGE_SIZE - pgoff)
125 chunksz = PAGE_SIZE - pgoff;
127 pg = xc_map_foreign_range(xch, dom, PAGE_SIZE, PROT_WRITE,
128 parray[off>>PAGE_SHIFT]);
129 memcpy(pg + pgoff, buf, chunksz);
130 munmap(pg, PAGE_SIZE);
132 off += chunksz;
133 buf += chunksz;
134 sz -= chunksz;
135 }
136 }
138 #define swap16(_v) ((((u16)(_v)>>8)&0xff)|(((u16)(_v)&0xff)<<8))
139 #define swap32(_v) (((u32)swap16((u16)(_v))<<16)|(u32)swap16((u32)((_v)>>16)))
141 /*
142 * Decode the header from the start of image and return it.
143 */
144 struct Exec *
145 get_header(
146 char *image,
147 unsigned long image_size,
148 struct Exec *ehdr)
149 {
150 u32 *v, x;
151 int i;
153 if (A9_MAGIC == 0)
154 return 0;
156 if (image_size < sizeof ehdr)
157 return 0;
159 /* ... all big endian words */
160 v = (u32 *)ehdr;
161 for (i = 0; i < sizeof(*ehdr); i += 4) {
162 x = *(u32 *)&image[i];
163 v[i/4] = swap32(x);
164 }
166 if(ehdr->magic != A9_MAGIC)
167 return 0;
168 return ehdr;
169 }
171 /*
172 * Local variables:
173 * mode: C
174 * c-set-style: "BSD"
175 * c-basic-offset: 4
176 * tab-width: 4
177 * indent-tabs-mode: nil
178 * End:
179 */