aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.rootkeys2
-rw-r--r--tools/libxc/Makefile1
-rw-r--r--tools/libxc/xc_aout9.h30
-rw-r--r--tools/libxc/xc_linux_build.c4
-rw-r--r--tools/libxc/xc_load_aout9.c166
-rw-r--r--tools/libxc/xc_private.h1
6 files changed, 203 insertions, 1 deletions
diff --git a/.rootkeys b/.rootkeys
index 4ad2a84038..ba0f52af7b 100644
--- a/.rootkeys
+++ b/.rootkeys
@@ -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__ */