Skip to content
Browse files

Working Xen bytecode microkernel (via the `.bcxen` target)

For some reason, ocamlc -output-obj doesnt entirely respect -nostdlib
and so references to -ltermcap sneak into the default primitives.
Therefore, ocamlclean is required or else undefined primitives result.
  • Loading branch information...
1 parent 492afe1 commit 527bc83e40c0f2bf53c1cb68f90db4708e58c2d8 @avsm committed Apr 20, 2012
View
5 NOTES.md
@@ -32,6 +32,11 @@ For the UNIX targets, there are 3 targets (by the filename extension):
* `.bcbin`: bytecode as an embedded callback
* `.bcxbin`: bytecode with deadcode-elimination via ocamlclean [1]
+For Xen, there is a bytecode (that requires ocamlclean) and native code:
+
+* `.xen`: native code microkernel
+* `.bcxen`: bytecode microkernel with deadcode-elimination via ocamlclean [1]
+
Note that ocamlclean can be quite slow (minutes) for larger applications,
hence it isnt done by default for the bytecode target.
View
2 assemble.sh
@@ -23,7 +23,7 @@ function assemble_xen {
echo Assembling: Xen
OBJ=${BUILDDIR}/xen
mkdir -p ${OBJ}/lib ${OBJ}/syntax
- for i in dietlibc/libdiet.a libm/libm.a ocaml/libocaml.a ocaml/libocamlbc.a kernel/libxen.a kernel/libxencaml.a kernel/x86_64.o; do
+ for i in dietlibc/libdiet.a libm/libm.a ocaml/libocaml.a ocaml/libocamlbc.a kernel/libxen.a kernel/libxencaml.a kernel/longjmp.o kernel/x86_64.o; do
cp ${ROOT}/lib/_build/xen/os/runtime_xen/$i ${OBJ}/lib/
done
cp ${ROOT}/lib/os/runtime_xen/kernel/mirage-x86_64.lds ${OBJ}/lib/
View
1 lib/os/runtime_xen/all.itarget
@@ -4,4 +4,5 @@ kernel/libxen.a
kernel/libxencaml.a
ocaml/libocaml.a
ocaml/libocamlbc.a
+kernel/longjmp.o
kernel/x86_64.o
View
23 lib/os/runtime_xen/kernel/longjmp.S
@@ -0,0 +1,23 @@
+#include <setjmp.h>
+
+.text
+.global __longjmp
+.type __longjmp,@function
+__longjmp:
+ mov $1,%eax
+ /* Restore the return address now. */
+ movq (JB_PC*8)(%rdi),%rdx
+ /* Restore registers. */
+ movq (JB_RBX*8)(%rdi),%rbx
+ movq (JB_RBP*8)(%rdi),%rbp
+ movq (JB_R12*8)(%rdi),%r12
+ movq (JB_R13*8)(%rdi),%r13
+ movq (JB_R14*8)(%rdi),%r14
+ movq (JB_R15*8)(%rdi),%r15
+ movq (JB_RSP*8)(%rdi),%rsp
+ /* never return 0 */
+ test %esi,%esi
+ cmovne %esi,%eax
+ /* Jump to saved PC. */
+ jmp *%rdx
+.size __longjmp,.-__longjmp;
View
5 lib/os/runtime_xen/ocaml/backtrace_bc.c
@@ -125,6 +125,9 @@ void caml_stash_backtrace(value exn, code_t pc, value * sp)
#define O_BINARY 0
#endif
+#ifdef SYS_xen
+static value read_debug_info(void) { return Val_false; }
+#else
static value read_debug_info(void)
{
CAMLparam0();
@@ -165,6 +168,7 @@ static value read_debug_info(void)
caml_close_channel(chan);
CAMLreturn(events);
}
+#endif
/* Search the event for the given PC. Return Val_false if not found. */
@@ -263,6 +267,7 @@ CAMLexport void caml_print_exception_backtrace(void)
struct loc_info li;
events = read_debug_info();
+
if (events == Val_false) {
fprintf(stderr,
"(Program not linked with -g, cannot print stack backtrace)\n");
View
8 lib/os/runtime_xen/ocaml/dynlink.c
@@ -60,10 +60,12 @@ static c_primitive lookup_primitive(char * name)
if (strcmp(name, caml_names_of_builtin_cprim[i]) == 0)
return caml_builtin_cprim[i];
}
+#ifndef SYS_xen
for (i = 0; i < shared_libs.size; i++) {
res = caml_dlsym(shared_libs.contents[i], name);
if (res != NULL) return (c_primitive) res;
}
+#endif
return NULL;
}
@@ -72,6 +74,7 @@ static c_primitive lookup_primitive(char * name)
#define LD_CONF_NAME "ld.conf"
+#ifndef SYS_xen
static char * parse_ld_conf(void)
{
char * stdlib, * ldconfname, * config, * p, * q;
@@ -177,6 +180,8 @@ void caml_build_primitive_table(char * lib_path,
caml_ext_table_free(&caml_shared_libs_path, 0);
}
+#endif /* SYS_xen */
+
/* Build the table of primitives as a copy of the builtin primitive table.
Used for executables generated by ocamlc -output-obj. */
@@ -191,7 +196,7 @@ void caml_build_primitive_table_builtin(void)
#endif /* NATIVE_CODE */
/** dlopen interface for the bytecode linker **/
-
+#ifndef SYS_xen
#define Handle_val(v) (*((void **) (v)))
CAMLprim value caml_dynlink_open_lib(value mode, value filename)
@@ -265,3 +270,4 @@ value caml_dynlink_get_current_libs(value unit)
}
#endif /* NATIVE_CODE */
+#endif
View
170 lib/os/runtime_xen/ocaml/fail_bc.c
@@ -0,0 +1,170 @@
+/***********************************************************************/
+/* */
+/* Objective Caml */
+/* */
+/* Xavier Leroy, projet Cristal, INRIA Rocquencourt */
+/* */
+/* Copyright 1996 Institut National de Recherche en Informatique et */
+/* en Automatique. All rights reserved. This file is distributed */
+/* under the terms of the GNU Library General Public License, with */
+/* the special exception on linking described in file ../LICENSE. */
+/* */
+/***********************************************************************/
+
+/* $Id$ */
+
+/* Raising exceptions from C. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "alloc.h"
+#include "fail.h"
+#include "io.h"
+#include "gc.h"
+#include "memory.h"
+#include "misc.h"
+#include "mlvalues.h"
+#include "printexc.h"
+#include "signals.h"
+#include "stacks.h"
+
+CAMLexport struct longjmp_buffer * caml_external_raise = NULL;
+value caml_exn_bucket;
+
+CAMLexport void caml_raise(value v)
+{
+ Unlock_exn();
+ caml_exn_bucket = v;
+ if (caml_external_raise == NULL) caml_fatal_uncaught_exception(v);
+ siglongjmp(caml_external_raise->buf, 1);
+}
+
+CAMLexport void caml_raise_constant(value tag)
+{
+ CAMLparam1 (tag);
+ CAMLlocal1 (bucket);
+
+ bucket = caml_alloc_small (1, 0);
+ Field(bucket, 0) = tag;
+ caml_raise(bucket);
+ CAMLnoreturn;
+}
+
+CAMLexport void caml_raise_with_arg(value tag, value arg)
+{
+ CAMLparam2 (tag, arg);
+ CAMLlocal1 (bucket);
+
+ bucket = caml_alloc_small (2, 0);
+ Field(bucket, 0) = tag;
+ Field(bucket, 1) = arg;
+ caml_raise(bucket);
+ CAMLnoreturn;
+}
+
+CAMLexport void caml_raise_with_args(value tag, int nargs, value args[])
+{
+ CAMLparam1 (tag);
+ CAMLxparamN (args, nargs);
+ value bucket;
+ int i;
+
+ Assert(1 + nargs <= Max_young_wosize);
+ bucket = caml_alloc_small (1 + nargs, 0);
+ Field(bucket, 0) = tag;
+ for (i = 0; i < nargs; i++) Field(bucket, 1 + i) = args[i];
+ caml_raise(bucket);
+ CAMLnoreturn;
+}
+
+CAMLexport void caml_raise_with_string(value tag, char const *msg)
+{
+ CAMLparam1 (tag);
+ CAMLlocal1 (vmsg);
+
+ vmsg = caml_copy_string(msg);
+ caml_raise_with_arg(tag, vmsg);
+ CAMLnoreturn;
+}
+
+/* PR#5115: Failure and Invalid_argument can be triggered by
+ input_value while reading the initial value of [caml_global_data]. */
+
+CAMLexport void caml_failwith (char const *msg)
+{
+ if (caml_global_data == 0) {
+ fprintf(stderr, "Fatal error: exception Failure(\"%s\")\n", msg);
+ exit(2);
+ }
+ caml_raise_with_string(Field(caml_global_data, FAILURE_EXN), msg);
+}
+
+CAMLexport void caml_invalid_argument (char const *msg)
+{
+ if (caml_global_data == 0) {
+ fprintf(stderr, "Fatal error: exception Invalid_argument(\"%s\")\n", msg);
+ exit(2);
+ }
+ caml_raise_with_string(Field(caml_global_data, INVALID_EXN), msg);
+}
+
+CAMLexport void caml_array_bound_error(void)
+{
+ caml_invalid_argument("index out of bounds");
+}
+
+/* Problem: we can't use [caml_raise_constant], because it allocates and
+ we're out of memory... Here, we allocate statically the exn bucket
+ for [Out_of_memory]. */
+
+static struct {
+ header_t hdr;
+ value exn;
+} out_of_memory_bucket = { 0, 0 };
+
+CAMLexport void caml_raise_out_of_memory(void)
+{
+ if (out_of_memory_bucket.exn == 0)
+ caml_fatal_error
+ ("Fatal error: out of memory while raising Out_of_memory\n");
+ caml_raise((value) &(out_of_memory_bucket.exn));
+}
+
+CAMLexport void caml_raise_stack_overflow(void)
+{
+ caml_raise_constant(Field(caml_global_data, STACK_OVERFLOW_EXN));
+}
+
+CAMLexport void caml_raise_sys_error(value msg)
+{
+ caml_raise_with_arg(Field(caml_global_data, SYS_ERROR_EXN), msg);
+}
+
+CAMLexport void caml_raise_end_of_file(void)
+{
+ caml_raise_constant(Field(caml_global_data, END_OF_FILE_EXN));
+}
+
+CAMLexport void caml_raise_zero_divide(void)
+{
+ caml_raise_constant(Field(caml_global_data, ZERO_DIVIDE_EXN));
+}
+
+CAMLexport void caml_raise_not_found(void)
+{
+ caml_raise_constant(Field(caml_global_data, NOT_FOUND_EXN));
+}
+
+CAMLexport void caml_raise_sys_blocked_io(void)
+{
+ caml_raise_constant(Field(caml_global_data, SYS_BLOCKED_IO));
+}
+
+/* Initialization of statically-allocated exception buckets */
+
+void caml_init_exceptions(void)
+{
+ out_of_memory_bucket.hdr = Make_header(1, 0, Caml_white);
+ out_of_memory_bucket.exn = Field(caml_global_data, OUT_OF_MEMORY_EXN);
+ caml_register_global_root(&out_of_memory_bucket.exn);
+}
View
2 lib/os/runtime_xen/ocaml/interp.c
@@ -11,7 +11,7 @@
/* */
/***********************************************************************/
-/* $Id: interp.c 9547 2010-01-22 12:48:24Z doligez $ */
+/* $Id$ */
/* The bytecode interpreter */
#include <stdio.h>
View
37 lib/os/runtime_xen/ocaml/jumptbl.h
@@ -0,0 +1,37 @@
+ &&lbl_ACC0, &&lbl_ACC1, &&lbl_ACC2, &&lbl_ACC3, &&lbl_ACC4, &&lbl_ACC5, &&lbl_ACC6, &&lbl_ACC7,
+ &&lbl_ACC, &&lbl_PUSH,
+ &&lbl_PUSHACC0, &&lbl_PUSHACC1, &&lbl_PUSHACC2, &&lbl_PUSHACC3,
+ &&lbl_PUSHACC4, &&lbl_PUSHACC5, &&lbl_PUSHACC6, &&lbl_PUSHACC7,
+ &&lbl_PUSHACC, &&lbl_POP, &&lbl_ASSIGN,
+ &&lbl_ENVACC1, &&lbl_ENVACC2, &&lbl_ENVACC3, &&lbl_ENVACC4, &&lbl_ENVACC,
+ &&lbl_PUSHENVACC1, &&lbl_PUSHENVACC2, &&lbl_PUSHENVACC3, &&lbl_PUSHENVACC4, &&lbl_PUSHENVACC,
+ &&lbl_PUSH_RETADDR, &&lbl_APPLY, &&lbl_APPLY1, &&lbl_APPLY2, &&lbl_APPLY3,
+ &&lbl_APPTERM, &&lbl_APPTERM1, &&lbl_APPTERM2, &&lbl_APPTERM3,
+ &&lbl_RETURN, &&lbl_RESTART, &&lbl_GRAB,
+ &&lbl_CLOSURE, &&lbl_CLOSUREREC,
+ &&lbl_OFFSETCLOSUREM2, &&lbl_OFFSETCLOSURE0, &&lbl_OFFSETCLOSURE2, &&lbl_OFFSETCLOSURE,
+ &&lbl_PUSHOFFSETCLOSUREM2, &&lbl_PUSHOFFSETCLOSURE0,
+ &&lbl_PUSHOFFSETCLOSURE2, &&lbl_PUSHOFFSETCLOSURE,
+ &&lbl_GETGLOBAL, &&lbl_PUSHGETGLOBAL, &&lbl_GETGLOBALFIELD, &&lbl_PUSHGETGLOBALFIELD, &&lbl_SETGLOBAL,
+ &&lbl_ATOM0, &&lbl_ATOM, &&lbl_PUSHATOM0, &&lbl_PUSHATOM,
+ &&lbl_MAKEBLOCK, &&lbl_MAKEBLOCK1, &&lbl_MAKEBLOCK2, &&lbl_MAKEBLOCK3, &&lbl_MAKEFLOATBLOCK,
+ &&lbl_GETFIELD0, &&lbl_GETFIELD1, &&lbl_GETFIELD2, &&lbl_GETFIELD3, &&lbl_GETFIELD, &&lbl_GETFLOATFIELD,
+ &&lbl_SETFIELD0, &&lbl_SETFIELD1, &&lbl_SETFIELD2, &&lbl_SETFIELD3, &&lbl_SETFIELD, &&lbl_SETFLOATFIELD,
+ &&lbl_VECTLENGTH, &&lbl_GETVECTITEM, &&lbl_SETVECTITEM,
+ &&lbl_GETSTRINGCHAR, &&lbl_SETSTRINGCHAR,
+ &&lbl_BRANCH, &&lbl_BRANCHIF, &&lbl_BRANCHIFNOT, &&lbl_SWITCH, &&lbl_BOOLNOT,
+ &&lbl_PUSHTRAP, &&lbl_POPTRAP, &&lbl_RAISE, &&lbl_CHECK_SIGNALS,
+ &&lbl_C_CALL1, &&lbl_C_CALL2, &&lbl_C_CALL3, &&lbl_C_CALL4, &&lbl_C_CALL5, &&lbl_C_CALLN,
+ &&lbl_CONST0, &&lbl_CONST1, &&lbl_CONST2, &&lbl_CONST3, &&lbl_CONSTINT,
+ &&lbl_PUSHCONST0, &&lbl_PUSHCONST1, &&lbl_PUSHCONST2, &&lbl_PUSHCONST3, &&lbl_PUSHCONSTINT,
+ &&lbl_NEGINT, &&lbl_ADDINT, &&lbl_SUBINT, &&lbl_MULINT, &&lbl_DIVINT, &&lbl_MODINT,
+ &&lbl_ANDINT, &&lbl_ORINT, &&lbl_XORINT, &&lbl_LSLINT, &&lbl_LSRINT, &&lbl_ASRINT,
+ &&lbl_EQ, &&lbl_NEQ, &&lbl_LTINT, &&lbl_LEINT, &&lbl_GTINT, &&lbl_GEINT,
+ &&lbl_OFFSETINT, &&lbl_OFFSETREF, &&lbl_ISINT,
+ &&lbl_GETMETHOD,
+ &&lbl_BEQ, &&lbl_BNEQ, &&lbl_BLTINT, &&lbl_BLEINT, &&lbl_BGTINT, &&lbl_BGEINT,
+ &&lbl_ULTINT, &&lbl_UGEINT,
+ &&lbl_BULTINT, &&lbl_BUGEINT,
+ &&lbl_GETPUBMET, &&lbl_GETDYNMET,
+ &&lbl_STOP,
+ &&lbl_EVENT, &&lbl_BREAK
View
42 lib/os/runtime_xen/ocaml/libcamlrun.cclib
@@ -0,0 +1,42 @@
+amd64.bc.o
+alloc.bc.o
+array.bc.o
+backtrace.bc.o
+callback.bc.o
+compact.bc.o
+compare.bc.o
+custom.bc.o
+debugger.bc.o
+dynlink.bc.o
+extern.bc.o
+fail.bc.o
+finalise.bc.o
+floats.bc.o
+freelist.bc.o
+gc_ctrl.bc.o
+globroots.bc.o
+hash.bc.o
+instrtrace.bc.o
+intern.bc.o
+ints.bc.o
+io.bc.o
+lexing.bc.o
+main.bc.o
+major_gc.bc.o
+md5.bc.o
+memory.bc.o
+meta.bc.o
+minor_gc.bc.o
+misc.bc.o
+natdynlink.bc.o
+obj.bc.o
+parsing.bc.o
+printexc.bc.o
+roots.bc.o
+signals.bc.o
+stacks.bc.o
+startup_bc.bc.o
+str.bc.o
+sys.bc.o
+terminfo.bc.o
+weak.bc.o
View
5 lib/os/runtime_xen/ocaml/libocamlbc.cclib
@@ -7,14 +7,15 @@ custom.bc.o
debugger.bc.o
dynlink.bc.o
extern.bc.o
-fail.bc.o
+fail_bc.bc.o
finalise.bc.o
floats.bc.o
freelist.bc.o
gc_ctrl.bc.o
globroots.bc.o
hash.bc.o
intern.bc.o
+interp.bc.o
ints.bc.o
io.bc.o
lexing.bc.o
@@ -30,10 +31,12 @@ obj.bc.o
parsing.bc.o
printexc.bc.o
roots_bc.bc.o
+signals_byt.bc.o
signals.bc.o
stacks.bc.o
str.bc.o
sys.bc.o
+fix_code.bc.o
weak.bc.o
bigarray_stubs.bc.o
startup_bc.bc.o
View
95 lib/os/runtime_xen/ocaml/signals_byt.c
@@ -0,0 +1,95 @@
+/***********************************************************************/
+/* */
+/* Objective Caml */
+/* */
+/* Xavier Leroy and Damien Doligez, INRIA Rocquencourt */
+/* */
+/* Copyright 2007 Institut National de Recherche en Informatique et */
+/* en Automatique. All rights reserved. This file is distributed */
+/* under the terms of the GNU Library General Public License, with */
+/* the special exception on linking described in file ../LICENSE. */
+/* */
+/***********************************************************************/
+
+/* $Id$ */
+
+/* Signal handling, code specific to the bytecode interpreter */
+
+#include <signal.h>
+#include "config.h"
+#include "memory.h"
+#include "osdeps.h"
+#include "signals.h"
+#include "signals_machdep.h"
+
+#ifndef NSIG
+#define NSIG 64
+#endif
+
+#ifdef _WIN32
+typedef void (*sighandler)(int sig);
+extern sighandler caml_win32_signal(int sig, sighandler action);
+#define signal(sig,act) caml_win32_signal(sig,act)
+#endif
+
+CAMLexport int volatile caml_something_to_do = 0;
+CAMLexport void (* volatile caml_async_action_hook)(void) = NULL;
+
+void caml_process_event(void)
+{
+ void (*async_action)(void);
+
+ if (caml_force_major_slice) caml_minor_collection ();
+ /* FIXME should be [caml_check_urgent_gc] */
+ caml_process_pending_signals();
+ async_action = caml_async_action_hook;
+ if (async_action != NULL) {
+ caml_async_action_hook = NULL;
+ (*async_action)();
+ }
+}
+
+static void handle_signal(int signal_number)
+{
+#if !defined(POSIX_SIGNALS) && !defined(BSD_SIGNALS)
+ signal(signal_number, handle_signal);
+#endif
+ if (signal_number < 0 || signal_number >= NSIG) return;
+ if (caml_try_leave_blocking_section_hook()) {
+ caml_execute_signal(signal_number, 1);
+ caml_enter_blocking_section_hook();
+ }else{
+ caml_record_signal(signal_number);
+ }
+}
+
+int caml_set_signal_action(int signo, int action)
+{
+ void (*act)(int signo), (*oldact)(int signo);
+#ifdef POSIX_SIGNALS
+ struct sigaction sigact, oldsigact;
+#endif
+
+ switch (action) {
+ case 0: act = SIG_DFL; break;
+ case 1: act = SIG_IGN; break;
+ default: act = handle_signal; break;
+ }
+
+#ifdef POSIX_SIGNALS
+ sigact.sa_handler = act;
+ sigemptyset(&sigact.sa_mask);
+ sigact.sa_flags = 0;
+ if (sigaction(signo, &sigact, &oldsigact) == -1) return -1;
+ oldact = oldsigact.sa_handler;
+#else
+ oldact = signal(signo, act);
+ if (oldact == SIG_ERR) return -1;
+#endif
+ if (oldact == handle_signal)
+ return 2;
+ else if (oldact == SIG_IGN)
+ return 1;
+ else
+ return 0;
+}
View
10 lib/os/runtime_xen/ocaml/startup_bc.c
@@ -100,6 +100,7 @@ static int read_trailer(int fd, struct exec_trailer *trail)
return BAD_BYTECODE;
}
+#ifndef SYS_xen
int caml_attempt_open(char **name, struct exec_trailer *trail,
int do_open_script)
{
@@ -197,7 +198,7 @@ static char * read_section(int fd, struct exec_trailer *trail, char *name)
data[len] = 0;
return data;
}
-
+#endif
/* Invocation of ocamlrun: 4 cases.
1. runtime + bytecode
@@ -233,7 +234,7 @@ static uintnat heap_size_init = Init_heap_def;
static uintnat max_stack_init = Max_stack_def;
/* Parse options on the command line */
-
+#ifndef SYS_xen
static int parse_command_line(char **argv)
{
int i, j;
@@ -323,13 +324,15 @@ static void parse_camlrunparam(void)
}
}
}
+#endif /* SYS_xen */
extern void caml_init_ieee_floats (void);
#ifdef _WIN32
extern void caml_signal_thread(void * lpParam);
#endif
+#ifndef SYS_xen
/* Main entry point when loading code from a file */
CAMLexport void caml_main(char **argv)
@@ -432,6 +435,7 @@ CAMLexport void caml_main(char **argv)
caml_fatal_uncaught_exception(caml_exn_bucket);
}
}
+#endif
/* Main entry point when code is linked in as initialized data */
@@ -449,12 +453,14 @@ CAMLexport void caml_startup_code(
#ifdef DEBUG
caml_verb_gc = 63;
#endif
+#ifndef SYS_xen
cds_file = getenv("CAML_DEBUG_FILE");
if (cds_file != NULL) {
caml_cds_file = caml_stat_alloc(strlen(cds_file) + 1);
strcpy(caml_cds_file, cds_file);
}
parse_camlrunparam();
+#endif
caml_external_raise = NULL;
/* Initialize the abstract machine */
caml_init_gc (minor_heap_init, heap_size_init, heap_chunk_init,
View
30 scripts/myocamlbuild.ml
@@ -100,27 +100,21 @@ module Mir = struct
let cc_unix_bytecode_link = cc_unix_link true
let cc_unix_native_link = cc_unix_link false
- (** Link to a standalone Xen bytecode microkernel *)
- let cc_xen_link tags arg out env =
- let xenlib = lib / "xen" / "lib" in
- let head_obj = Px (xenlib / "x86_64.o") in
- let ldlibs = List.map (fun x -> Px (xenlib / ("lib" ^ x ^ ".a")))
- ["ocaml"; "xen"; "xencaml"; "diet"; "m"] in
- Cmd (S ( A ld :: [ T(tags++"link"++"xen");
- A"-d"; A"-nostdlib"; A"-m"; A"elf_x86_64"; A"-T";
- Px (xenlib / "mirage-x86_64.lds"); head_obj; P arg ]
- @ ldlibs @ [A"-o"; Px out]))
-
(** Link to a standalone Xen microkernel *)
- let cc_xen_link tags arg out env =
+ let cc_xen_link bc tags arg out env =
let xenlib = lib / "xen" / "lib" in
+ let jmp_obj = Px (xenlib / "longjmp.o") in
let head_obj = Px (xenlib / "x86_64.o") in
+ let ocamllib = match bc with true -> "ocamlbc" |false -> "ocaml" in
let ldlibs = List.map (fun x -> Px (xenlib / ("lib" ^ x ^ ".a")))
- ["ocaml"; "xen"; "xencaml"; "diet"; "m"] in
+ [ocamllib; "xen"; "xencaml"; "diet"; "m"] in
Cmd (S ( A ld :: [ T(tags++"link"++"xen");
A"-d"; A"-nostdlib"; A"-m"; A"elf_x86_64"; A"-T";
- Px (xenlib / "mirage-x86_64.lds"); head_obj; P arg ]
- @ ldlibs @ [A"-o"; Px out]))
+ Px (xenlib / "mirage-x86_64.lds"); head_obj; P arg ]
+ @ ldlibs @ [jmp_obj; A"-o"; Px out]))
+
+ let cc_xen_bc_link = cc_xen_link true
+ let cc_xen_nc_link = cc_xen_link false
(* Rewrite sections for Xen LDS layout *)
let xen_objcopy dst src env builder =
@@ -216,13 +210,13 @@ module Mir = struct
rule ("final link: xen/%__.mx.o -> xen/%.xen")
~prod:"xen/%(file).xen"
~dep:"xen/%(file)__.mx.o"
- (cc_link_c_implem cc_xen_link "xen/%(file)__.mx.o" "xen/%(file).xen");
+ (cc_link_c_implem cc_xen_nc_link "xen/%(file)__.mx.o" "xen/%(file).xen");
(* Xen bytecode link rule *)
rule ("final link: xen/%__.mb.o -> xen/%.bcxen")
~prod:"xen/%(file).bcxen"
- ~dep:"xen/%(file)__.mb.o"
- (cc_link_c_implem cc_xen_link "xen/%(file)__.mb.o" "xen/%(file).bcxen");
+ ~dep:"xen/%(file)__.mc.o"
+ (cc_link_c_implem cc_xen_bc_link "xen/%(file)__.mc.o" "xen/%(file).bcxen");
(* UNIX link rule *)
rule ("final link: %__.m.o -> %.unix-%(mode).bin")

0 comments on commit 527bc83

Please sign in to comment.
Something went wrong with that request. Please try again.