diff options
-rw-r--r-- | .rootkeys | 2 | ||||
-rw-r--r-- | tools/libxc/Makefile | 1 | ||||
-rw-r--r-- | tools/libxc/xc_aout9.h | 30 | ||||
-rw-r--r-- | tools/libxc/xc_linux_build.c | 4 | ||||
-rw-r--r-- | tools/libxc/xc_load_aout9.c | 166 | ||||
-rw-r--r-- | tools/libxc/xc_private.h | 1 |
6 files changed, 203 insertions, 1 deletions
@@ -736,6 +736,7 @@ 41cc934abX-QLXJXW_clV_wRjM0zYg tools/libxc/plan9a.out.h 3fbba6dc1uU7U3IFeF6A-XEOYF2MkQ tools/libxc/rpm.spec 3fbba6dcrNxtygEcgJYAJJ1gCQqfsA tools/libxc/xc.h +42bbe5b9J1BFuxACiiyj38Fucc2xgg tools/libxc/xc_aout9.h 3fbba6dbEVkVMX0JuDFzap9jeaucGA tools/libxc/xc_bvtsched.c 4273458dyF2_sKA6CFkNJQYb8eY2dA tools/libxc/xc_core.c 3fbba6dbasJQV-MVElDC0DGSHMiL5w tools/libxc/xc_domain.c @@ -745,6 +746,7 @@ 3fbba6dbNCU7U6nsMYiXzKkp3ztaJg tools/libxc/xc_linux_build.c 3fbba6dbl267zZOAVHYLOdLCdhcZMw tools/libxc/xc_linux_restore.c 3fbba6db7li3FJiABYtCmuGxOJxEGw tools/libxc/xc_linux_save.c +42bbe5b95gdEdSyDdrK2ts7GEiK5Mw tools/libxc/xc_load_aout9.c 42a40bc3vE3p9fPSJZQZK0MdQF9B8g tools/libxc/xc_load_bin.c 42a40bc4diWfFsPGf0RW7qXMufU4YQ tools/libxc/xc_load_elf.c 3fbba6db7WnnJr0KFrIFrqNlSKvFYg tools/libxc/xc_misc.c diff --git a/tools/libxc/Makefile b/tools/libxc/Makefile index 2a955865e3..4fdb3c210d 100644 --- a/tools/libxc/Makefile +++ b/tools/libxc/Makefile @@ -19,6 +19,7 @@ SRCS += xc_core.c SRCS += xc_domain.c SRCS += xc_evtchn.c SRCS += xc_gnttab.c +SRCS += xc_load_aout9.c SRCS += xc_load_bin.c SRCS += xc_load_elf.c SRCS += xc_linux_build.c diff --git a/tools/libxc/xc_aout9.h b/tools/libxc/xc_aout9.h new file mode 100644 index 0000000000..9a5ada084a --- /dev/null +++ b/tools/libxc/xc_aout9.h @@ -0,0 +1,30 @@ + +typedef struct Exec +{ + long magic; /* magic number */ + long text; /* size of text segment */ + long data; /* size of initialized data */ + long bss; /* size of uninitialized data */ + long syms; /* size of symbol table */ + long entry; /* entry point */ + long spsz; /* size of pc/sp offset table */ + long pcsz; /* size of pc/line number table */ +} Exec; + +#define _MAGIC(b) ((((4*b)+0)*b)+7) +#define A_MAGIC _MAGIC(8) /* 68020 */ +#define I_MAGIC _MAGIC(11) /* intel 386 */ +#define J_MAGIC _MAGIC(12) /* intel 960 (retired) */ +#define K_MAGIC _MAGIC(13) /* sparc */ +#define V_MAGIC _MAGIC(16) /* mips 3000 BE */ +#define X_MAGIC _MAGIC(17) /* att dsp 3210 (retired) */ +#define M_MAGIC _MAGIC(18) /* mips 4000 BE */ +#define D_MAGIC _MAGIC(19) /* amd 29000 (retired) */ +#define E_MAGIC _MAGIC(20) /* arm */ +#define Q_MAGIC _MAGIC(21) /* powerpc */ +#define N_MAGIC _MAGIC(22) /* mips 4000 LE */ +#define L_MAGIC _MAGIC(23) /* dec alpha */ +#define P_MAGIC _MAGIC(24) /* mips 3000 LE */ +#define U_MAGIC _MAGIC(25) /* sparc64 */ +#define S_MAGIC _MAGIC(26) /* amd64 */ + diff --git a/tools/libxc/xc_linux_build.c b/tools/libxc/xc_linux_build.c index 1ce72d3dae..838efe1913 100644 --- a/tools/libxc/xc_linux_build.c +++ b/tools/libxc/xc_linux_build.c @@ -14,6 +14,7 @@ #include "xc_elf.h" +#include "xc_aout9.h" #include <stdlib.h> #include <zlib.h> @@ -38,7 +39,8 @@ static int probeimageformat(char *image, struct load_funcs *load_funcs) { if ( probe_elf(image, image_size, load_funcs) && - probe_bin(image, image_size, load_funcs) ) + probe_bin(image, image_size, load_funcs) && + probe_aout9(image, image_size, load_funcs) ) { ERROR( "Unrecognized image format" ); return -EINVAL; diff --git a/tools/libxc/xc_load_aout9.c b/tools/libxc/xc_load_aout9.c new file mode 100644 index 0000000000..76ee55fcc6 --- /dev/null +++ b/tools/libxc/xc_load_aout9.c @@ -0,0 +1,166 @@ + +#include "xc_private.h" +#include "xc_aout9.h" + +#if defined(__i386__) + #define A9_MAGIC I_MAGIC +#elif defined(__x86_64__) + #define A9_MAGIC S_MAGIC +#elif defined(__ia64__) + #define A9_MAGIC 0 +#else +#error "Unsupported architecture" +#endif + + +#define round_pgup(_p) (((_p)+(PAGE_SIZE-1))&PAGE_MASK) +#define round_pgdown(_p) ((_p)&PAGE_MASK) + +static int parseaout9image(char *, unsigned long, struct domain_setup_info *); +static int loadaout9image(char *, unsigned long, int, u32, unsigned long *, struct domain_setup_info *); +static void copyout(int, u32, unsigned long *, unsigned long, void *, int); +struct Exec *get_header(unsigned char *, unsigned long, struct Exec *); + + +int +probe_aout9( + char *image, + unsigned long image_size, + struct load_funcs *load_funcs) +{ + struct Exec ehdr; + + if (!get_header(image, image_size, &ehdr)) { + ERROR("Kernel image does not have a a.out9 header."); + return -EINVAL; + } + + load_funcs->parseimage = parseaout9image; + load_funcs->loadimage = loadaout9image; + return 0; +} + +static int +parseaout9image( + char *image, + unsigned long image_size, + struct domain_setup_info *dsi) +{ + struct Exec ehdr; + unsigned long start, txtsz, end; + + if (!get_header(image, image_size, &ehdr)) { + ERROR("Kernel image does not have a a.out9 header."); + return -EINVAL; + } + + if (sizeof ehdr + ehdr.text + ehdr.data > image_size) { + ERROR("a.out program extends past end of image."); + return -EINVAL; + } + + start = round_pgdown(ehdr.entry); + txtsz = round_pgup(ehdr.text); + end = start + txtsz + ehdr.data + ehdr.bss; + + dsi->v_start = start; + dsi->v_kernstart = start; + dsi->v_kernend = end; + dsi->v_kernentry = ehdr.entry; + dsi->v_end = end; + + /* XXX load symbols */ + + return 0; +} + +static int +loadaout9image( + char *image, + unsigned long image_size, + int xch, u32 dom, + unsigned long *parray, + struct domain_setup_info *dsi) +{ + struct Exec ehdr; + unsigned long txtsz; + + if (!get_header(image, image_size, &ehdr)) { + ERROR("Kernel image does not have a a.out9 header."); + return -EINVAL; + } + + txtsz = round_pgup(ehdr.text); + copyout(xch, dom, parray, + 0, image, sizeof ehdr + ehdr.text); + copyout(xch, dom, parray, + txtsz, image + sizeof ehdr + ehdr.text, ehdr.data); + /* XXX zeroing of BSS needed? */ + + /* XXX load symbols */ + + return 0; +} + +/* + * copyout data to the domain given an offset to the start + * of its memory region described by parray. + */ +static void +copyout( + int xch, u32 dom, + unsigned long *parray, + unsigned long off, + void *buf, + int sz) +{ + unsigned long pgoff, chunksz; + void *pg; + + while (sz > 0) { + pgoff = off & (PAGE_SIZE-1); + chunksz = sz; + if(chunksz > PAGE_SIZE - pgoff) + chunksz = PAGE_SIZE - pgoff; + + pg = xc_map_foreign_range(xch, dom, PAGE_SIZE, PROT_WRITE, + parray[off>>PAGE_SHIFT]); + memcpy(pg + pgoff, buf, chunksz); + munmap(pg, PAGE_SIZE); + + off += chunksz; + buf += chunksz; + sz -= chunksz; + } +} + +/* + * Decode the header from the start of image and return it. + */ +struct Exec * +get_header( + unsigned char *image, + unsigned long image_size, + struct Exec *ehdr) +{ + unsigned long *v; + int i; + + if (A9_MAGIC == 0) + return 0; + + if (image_size < sizeof ehdr) + return 0; + + /* ... all big endian words */ + v = (unsigned long *)ehdr; + for (i = 0; i < sizeof *ehdr; i += 4) { + v[i/4] = (image[i+0]<<24) | (image[i+1]<<16) | + (image[i+2]<<8) | image[i+3]; + } + + if(ehdr->magic != A9_MAGIC) + return 0; + return ehdr; +} + diff --git a/tools/libxc/xc_private.h b/tools/libxc/xc_private.h index c50813ee3c..2961b00c99 100644 --- a/tools/libxc/xc_private.h +++ b/tools/libxc/xc_private.h @@ -310,5 +310,6 @@ int pin_table(int xc_handle, unsigned int type, unsigned long mfn, /* image loading */ int probe_elf(char *image, unsigned long image_size, struct load_funcs *funcs); int probe_bin(char *image, unsigned long image_size, struct load_funcs *funcs); +int probe_aout9(char *image, unsigned long image_size, struct load_funcs *funcs); #endif /* __XC_PRIVATE_H__ */ |