ia64/xen-unstable

annotate tools/libxc/xc_load_aout9.c @ 6670:77d8b5e40da7

Small plan9 loader patch from Tim Newsham.
author kaf24@firebug.cl.cam.ac.uk
date Wed Sep 07 09:42:47 2005 +0000 (2005-09-07)
parents dd668f7527cb
children 7a36f58f64ee
rev   line source
kaf24@5577 1
cl349@6404 2 #include "xg_private.h"
kaf24@5577 3 #include "xc_aout9.h"
kaf24@5577 4
kaf24@5577 5 #if defined(__i386__)
kaf24@5577 6 #define A9_MAGIC I_MAGIC
kaf24@5577 7 #elif defined(__x86_64__)
kaf24@5577 8 #define A9_MAGIC S_MAGIC
kaf24@5577 9 #elif defined(__ia64__)
kaf24@5577 10 #define A9_MAGIC 0
kaf24@5577 11 #else
kaf24@5577 12 #error "Unsupported architecture"
kaf24@5577 13 #endif
kaf24@5577 14
kaf24@5577 15
kaf24@5577 16 #define round_pgup(_p) (((_p)+(PAGE_SIZE-1))&PAGE_MASK)
kaf24@6564 17 #define KZERO 0x80000000
kaf24@6564 18 #define KOFFSET(_p) ((_p)&~KZERO)
kaf24@5577 19
kaf24@5577 20 static int parseaout9image(char *, unsigned long, struct domain_setup_info *);
kaf24@5577 21 static int loadaout9image(char *, unsigned long, int, u32, unsigned long *, struct domain_setup_info *);
kaf24@5577 22 static void copyout(int, u32, unsigned long *, unsigned long, void *, int);
kaf24@5579 23 struct Exec *get_header(char *, unsigned long, struct Exec *);
kaf24@5577 24
kaf24@5577 25
kaf24@5577 26 int
kaf24@5577 27 probe_aout9(
kaf24@5577 28 char *image,
kaf24@5577 29 unsigned long image_size,
kaf24@5577 30 struct load_funcs *load_funcs)
kaf24@5577 31 {
kaf24@5577 32 struct Exec ehdr;
kaf24@5577 33
kaf24@5577 34 if (!get_header(image, image_size, &ehdr)) {
kaf24@5577 35 ERROR("Kernel image does not have a a.out9 header.");
kaf24@5577 36 return -EINVAL;
kaf24@5577 37 }
kaf24@5577 38
kaf24@5577 39 load_funcs->parseimage = parseaout9image;
kaf24@5577 40 load_funcs->loadimage = loadaout9image;
kaf24@5577 41 return 0;
kaf24@5577 42 }
kaf24@5577 43
kaf24@5577 44 static int
kaf24@5577 45 parseaout9image(
kaf24@5577 46 char *image,
kaf24@5577 47 unsigned long image_size,
kaf24@5577 48 struct domain_setup_info *dsi)
kaf24@5577 49 {
kaf24@5577 50 struct Exec ehdr;
kaf24@6670 51 unsigned long start, dstart, end;
kaf24@5577 52
kaf24@5577 53 if (!get_header(image, image_size, &ehdr)) {
kaf24@5577 54 ERROR("Kernel image does not have a a.out9 header.");
kaf24@5577 55 return -EINVAL;
kaf24@5577 56 }
kaf24@5577 57
kaf24@5577 58 if (sizeof ehdr + ehdr.text + ehdr.data > image_size) {
kaf24@5577 59 ERROR("a.out program extends past end of image.");
kaf24@5577 60 return -EINVAL;
kaf24@5577 61 }
kaf24@5577 62
kaf24@6670 63 start = ehdr.entry;
kaf24@6670 64 dstart = round_pgup(start + ehdr.text);
kaf24@6670 65 end = dstart + ehdr.data + ehdr.bss;
kaf24@5577 66
kaf24@6564 67 dsi->v_start = KZERO;
kaf24@5577 68 dsi->v_kernstart = start;
kaf24@5577 69 dsi->v_kernend = end;
kaf24@5577 70 dsi->v_kernentry = ehdr.entry;
kaf24@5577 71 dsi->v_end = end;
kaf24@5577 72
kaf24@5577 73 /* XXX load symbols */
kaf24@5577 74
kaf24@5577 75 return 0;
kaf24@5577 76 }
kaf24@5577 77
kaf24@5577 78 static int
kaf24@5577 79 loadaout9image(
kaf24@5577 80 char *image,
kaf24@5577 81 unsigned long image_size,
kaf24@5577 82 int xch, u32 dom,
kaf24@5577 83 unsigned long *parray,
kaf24@5577 84 struct domain_setup_info *dsi)
kaf24@5577 85 {
kaf24@5577 86 struct Exec ehdr;
kaf24@6670 87 unsigned long start, dstart;
kaf24@5577 88
kaf24@5577 89 if (!get_header(image, image_size, &ehdr)) {
kaf24@5577 90 ERROR("Kernel image does not have a a.out9 header.");
kaf24@5577 91 return -EINVAL;
kaf24@5577 92 }
kaf24@5577 93
kaf24@6670 94 start = ehdr.entry;
kaf24@6670 95 dstart = round_pgup(start + ehdr.text);
kaf24@6670 96 copyout(xch, dom, parray, start, image + sizeof ehdr, ehdr.text);
kaf24@6670 97 copyout(xch, dom, parray, dstart,
kaf24@6670 98 image + sizeof ehdr + ehdr.text, ehdr.data);
kaf24@5577 99
kaf24@5577 100 /* XXX load symbols */
kaf24@5577 101
kaf24@5577 102 return 0;
kaf24@5577 103 }
kaf24@5577 104
kaf24@5577 105 /*
kaf24@5577 106 * copyout data to the domain given an offset to the start
kaf24@5577 107 * of its memory region described by parray.
kaf24@5577 108 */
kaf24@5577 109 static void
kaf24@5577 110 copyout(
kaf24@5577 111 int xch, u32 dom,
kaf24@5577 112 unsigned long *parray,
kaf24@6564 113 unsigned long addr,
kaf24@5577 114 void *buf,
kaf24@5577 115 int sz)
kaf24@5577 116 {
kaf24@6564 117 unsigned long pgoff, chunksz, off;
kaf24@5577 118 void *pg;
kaf24@5577 119
kaf24@6564 120 off = KOFFSET(addr);
kaf24@5577 121 while (sz > 0) {
kaf24@5577 122 pgoff = off & (PAGE_SIZE-1);
kaf24@5577 123 chunksz = sz;
kaf24@5577 124 if(chunksz > PAGE_SIZE - pgoff)
kaf24@5577 125 chunksz = PAGE_SIZE - pgoff;
kaf24@5577 126
kaf24@5577 127 pg = xc_map_foreign_range(xch, dom, PAGE_SIZE, PROT_WRITE,
kaf24@5577 128 parray[off>>PAGE_SHIFT]);
kaf24@5577 129 memcpy(pg + pgoff, buf, chunksz);
kaf24@5577 130 munmap(pg, PAGE_SIZE);
kaf24@5577 131
kaf24@5577 132 off += chunksz;
kaf24@5577 133 buf += chunksz;
kaf24@5577 134 sz -= chunksz;
kaf24@5577 135 }
kaf24@5577 136 }
kaf24@5579 137
kaf24@5579 138 #define swap16(_v) ((((u16)(_v)>>8)&0xff)|(((u16)(_v)&0xff)<<8))
kaf24@5579 139 #define swap32(_v) (((u32)swap16((u16)(_v))<<16)|(u32)swap16((u32)((_v)>>16)))
kaf24@5579 140
kaf24@5577 141 /*
kaf24@5577 142 * Decode the header from the start of image and return it.
kaf24@5577 143 */
kaf24@5577 144 struct Exec *
kaf24@5577 145 get_header(
kaf24@5579 146 char *image,
kaf24@5577 147 unsigned long image_size,
kaf24@5577 148 struct Exec *ehdr)
kaf24@5577 149 {
kaf24@5579 150 u32 *v, x;
kaf24@5577 151 int i;
kaf24@5577 152
kaf24@5577 153 if (A9_MAGIC == 0)
kaf24@5577 154 return 0;
kaf24@5577 155
kaf24@5577 156 if (image_size < sizeof ehdr)
kaf24@5577 157 return 0;
kaf24@5577 158
kaf24@5577 159 /* ... all big endian words */
kaf24@5579 160 v = (u32 *)ehdr;
kaf24@5579 161 for (i = 0; i < sizeof(*ehdr); i += 4) {
kaf24@5579 162 x = *(u32 *)&image[i];
kaf24@5579 163 v[i/4] = swap32(x);
kaf24@5577 164 }
kaf24@5577 165
kaf24@5577 166 if(ehdr->magic != A9_MAGIC)
kaf24@5577 167 return 0;
kaf24@5577 168 return ehdr;
kaf24@5577 169 }
kaf24@5577 170