aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>2005-06-24 10:51:38 +0000
committerkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>2005-06-24 10:51:38 +0000
commit06420e5d04dd8b3ccb5785f821b9368e66235c01 (patch)
treee521b0d83eadb0841b3d7b6609a23048496e4cd5
parented30037e48073a7d855fce58c1dfc563e446ff6c (diff)
downloadxen-06420e5d04dd8b3ccb5785f821b9368e66235c01.tar.gz
xen-06420e5d04dd8b3ccb5785f821b9368e66235c01.tar.bz2
xen-06420e5d04dd8b3ccb5785f821b9368e66235c01.zip
bitkeeper revision 1.1752 (42bbe5ba5hLPfcw1f77_F22fq6v6Yw)
The set of patches below add support for loading plan9's a.out format using the linux builder. This is considerably simpler than having a seperate builder, shares more code and should be easier to maintain. Hopefully the original plan9 builder can go away in the future. I've been able to test this manually with vm-tools but am still having some problems (unrelated I think) with xm. Signed-off-by: Tim Newsham <newsham@lava.net>
-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__ */