ia64/xen-unstable

view tools/libxc/xc_load_aout9.c @ 6586:dd668f7527cb

merge?
author cl349@firebug.cl.cam.ac.uk
date Thu Sep 01 10:16:14 2005 +0000 (2005-09-01)
parents f41f8d753b7a f0dc15fd3c1b
children 77d8b5e40da7 7a36f58f64ee a75b08af8d19
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 round_pgdown(_p) ((_p)&PAGE_MASK)
18 #define KZERO 0x80000000
19 #define KOFFSET(_p) ((_p)&~KZERO)
21 static int parseaout9image(char *, unsigned long, struct domain_setup_info *);
22 static int loadaout9image(char *, unsigned long, int, u32, unsigned long *, struct domain_setup_info *);
23 static void copyout(int, u32, unsigned long *, unsigned long, void *, int);
24 struct Exec *get_header(char *, unsigned long, struct Exec *);
27 int
28 probe_aout9(
29 char *image,
30 unsigned long image_size,
31 struct load_funcs *load_funcs)
32 {
33 struct Exec ehdr;
35 if (!get_header(image, image_size, &ehdr)) {
36 ERROR("Kernel image does not have a a.out9 header.");
37 return -EINVAL;
38 }
40 load_funcs->parseimage = parseaout9image;
41 load_funcs->loadimage = loadaout9image;
42 return 0;
43 }
45 static int
46 parseaout9image(
47 char *image,
48 unsigned long image_size,
49 struct domain_setup_info *dsi)
50 {
51 struct Exec ehdr;
52 unsigned long start, txtsz, end;
54 if (!get_header(image, image_size, &ehdr)) {
55 ERROR("Kernel image does not have a a.out9 header.");
56 return -EINVAL;
57 }
59 if (sizeof ehdr + ehdr.text + ehdr.data > image_size) {
60 ERROR("a.out program extends past end of image.");
61 return -EINVAL;
62 }
64 start = round_pgdown(ehdr.entry);
65 txtsz = round_pgup(ehdr.text);
66 end = start + txtsz + ehdr.data + ehdr.bss;
68 dsi->v_start = KZERO;
69 dsi->v_kernstart = start;
70 dsi->v_kernend = end;
71 dsi->v_kernentry = ehdr.entry;
72 dsi->v_end = end;
74 /* XXX load symbols */
76 return 0;
77 }
79 static int
80 loadaout9image(
81 char *image,
82 unsigned long image_size,
83 int xch, u32 dom,
84 unsigned long *parray,
85 struct domain_setup_info *dsi)
86 {
87 struct Exec ehdr;
88 unsigned long start, txtsz;
90 if (!get_header(image, image_size, &ehdr)) {
91 ERROR("Kernel image does not have a a.out9 header.");
92 return -EINVAL;
93 }
95 start = round_pgdown(ehdr.entry);
96 txtsz = round_pgup(ehdr.text);
97 copyout(xch, dom, parray,
98 start, image, sizeof ehdr + ehdr.text);
99 copyout(xch, dom, parray,
100 start+txtsz, image + sizeof ehdr + ehdr.text, ehdr.data);
102 /* XXX load symbols */
104 return 0;
105 }
107 /*
108 * copyout data to the domain given an offset to the start
109 * of its memory region described by parray.
110 */
111 static void
112 copyout(
113 int xch, u32 dom,
114 unsigned long *parray,
115 unsigned long addr,
116 void *buf,
117 int sz)
118 {
119 unsigned long pgoff, chunksz, off;
120 void *pg;
122 off = KOFFSET(addr);
123 while (sz > 0) {
124 pgoff = off & (PAGE_SIZE-1);
125 chunksz = sz;
126 if(chunksz > PAGE_SIZE - pgoff)
127 chunksz = PAGE_SIZE - pgoff;
129 pg = xc_map_foreign_range(xch, dom, PAGE_SIZE, PROT_WRITE,
130 parray[off>>PAGE_SHIFT]);
131 memcpy(pg + pgoff, buf, chunksz);
132 munmap(pg, PAGE_SIZE);
134 off += chunksz;
135 buf += chunksz;
136 sz -= chunksz;
137 }
138 }
140 #define swap16(_v) ((((u16)(_v)>>8)&0xff)|(((u16)(_v)&0xff)<<8))
141 #define swap32(_v) (((u32)swap16((u16)(_v))<<16)|(u32)swap16((u32)((_v)>>16)))
143 /*
144 * Decode the header from the start of image and return it.
145 */
146 struct Exec *
147 get_header(
148 char *image,
149 unsigned long image_size,
150 struct Exec *ehdr)
151 {
152 u32 *v, x;
153 int i;
155 if (A9_MAGIC == 0)
156 return 0;
158 if (image_size < sizeof ehdr)
159 return 0;
161 /* ... all big endian words */
162 v = (u32 *)ehdr;
163 for (i = 0; i < sizeof(*ehdr); i += 4) {
164 x = *(u32 *)&image[i];
165 v[i/4] = swap32(x);
166 }
168 if(ehdr->magic != A9_MAGIC)
169 return 0;
170 return ehdr;
171 }