Port of OCaml bytecode runtime

A minimal runtime for executing portable OCaml bytecode.
A bytecode standard library is not yet provided.
This commit is contained in:
Emery Hemingway
2019-01-18 15:14:02 +01:00
committed by Norman Feske
parent ffc8c453e2
commit 6628d03126
13 changed files with 283 additions and 0 deletions

10
lib/mk/ocaml-str.mk Normal file
View File

@@ -0,0 +1,10 @@
include $(REP_DIR)/lib/mk/ocaml.inc
LIBS += libc
INC_DIR += $(OCAML_SRC_DIR)/byterun
INC_DIR += $(OCAML_SRC_DIR)/byterun/caml
vpath %.c $(OCAML_SRC_DIR)/otherlibs/str
SRC_C += strstubs.c

10
lib/mk/ocaml-threads.mk Normal file
View File

@@ -0,0 +1,10 @@
include $(REP_DIR)/lib/mk/ocaml.inc
LIBS += libc
INC_DIR += $(OCAML_SRC_DIR)/byterun
INC_DIR += $(OCAML_SRC_DIR)/byterun/caml
vpath %.c $(OCAML_SRC_DIR)/otherlibs/threads
SRC_C += scheduler.c

26
lib/mk/ocaml-unix.mk Normal file
View File

@@ -0,0 +1,26 @@
include $(REP_DIR)/lib/mk/ocaml.inc
LIBS += libc
INC_DIR += $(OCAML_SRC_DIR)/byterun
INC_DIR += $(OCAML_SRC_DIR)/byterun/caml
vpath %.c $(OCAML_SRC_DIR)/otherlibs/unix
SRC_C += accept.c access.c addrofstr.c alarm.c bind.c chdir.c chmod.c \
chown.c chroot.c close.c closedir.c connect.c cst2constr.c cstringv.c \
dup.c dup2.c envir.c errmsg.c execv.c execve.c execvp.c exit.c \
fchmod.c fchown.c fcntl.c fork.c ftruncate.c \
getaddrinfo.c getcwd.c getegid.c geteuid.c getgid.c \
getgr.c getgroups.c gethost.c gethostname.c getlogin.c \
getnameinfo.c getpeername.c getpid.c getppid.c getproto.c getpw.c \
gettimeofday.c getserv.c getsockname.c getuid.c gmtime.c \
initgroups.c isatty.c itimer.c kill.c link.c listen.c lockf.c lseek.c \
mkdir.c mkfifo.c mmap.c mmap_ba.c \
nice.c open.c opendir.c pipe.c putenv.c read.c \
readdir.c readlink.c rename.c rewinddir.c rmdir.c select.c sendrecv.c \
setgid.c setgroups.c setsid.c setuid.c shutdown.c signals.c \
sleep.c socket.c socketaddr.c \
socketpair.c sockopt.c stat.c strofaddr.c symlink.c termios.c \
time.c times.c truncate.c umask.c unixsupport.c unlink.c \
utimes.c wait.c write.c

4
lib/mk/ocaml.inc Normal file
View File

@@ -0,0 +1,4 @@
OCAML_PORT_DIR := $(call select_from_ports,ocaml)
OCAML_SRC_DIR := $(OCAML_PORT_DIR)/src/ocaml
INC_DIR += $(REP_DIR)/src/app/ocamlrun

1
ports/ocaml.hash Normal file
View File

@@ -0,0 +1 @@
23ddf9418fd8dffbde8f8d52071a13d0541715d4

7
ports/ocaml.port Normal file
View File

@@ -0,0 +1,7 @@
LICENSE = LGPLv2.1
VERSION = 4.07.1
DOWNLOADS = ocaml.archive
URL(ocaml) := http://caml.inria.fr/pub/distrib/ocaml-4.07/ocaml-4.07.1.tar.xz
SHA(ocaml) := dfe48b1da31da9c82d77612582fae74c80e8d1ac650e1c24f5ac9059e48307b8
DIR(ocaml) := src/ocaml

69
run/ocamlrun.run Normal file
View File

@@ -0,0 +1,69 @@
set ocamlc [installed_command ocamlc]
create_boot_directory
proc depot_user {} { return [get_cmd_arg --depot-user genodelabs] }
import_from_depot \
[depot_user]/src/[base_src] \
[depot_user]/src/init \
append build_components {
app/ocamlrun
}
build $build_components
install_config {
<config verbose="yes">
<parent-provides>
<service name="ROM"/>
<service name="LOG"/>
<service name="RM"/>
<service name="CPU"/>
<service name="PD"/>
<service name="IRQ"/>
<service name="IO_MEM"/>
<service name="IO_PORT"/>
</parent-provides>
<default-route>
<any-service> <any-child/> <parent/> </any-service>
</default-route>
<default caps="100"/>
<start name="timer">
<resource name="RAM" quantum="1M"/>
<provides><service name="Timer"/></provides>
</start>
<start name="ocamlrun" caps="500">
<resource name="RAM" quantum="1G"/>
<config verbose="yes">
<libc stdout="/dev/log" stderr="/dev/log"/>
<vfs>
<dir name="dev"> <log/> </dir>
<tar name="bytecode.tar"/>
</vfs>
<arg value="ocamlrun"/>
<arg value="a.out"/>
</config>
</start>
</config>
}
#
# Compile some bytecode and TAR it
#
set fd [open [run_dir]/hello.ml w]
puts $fd "print_string \"Hello world!\n\";;"
close $fd
exec ocamlc -o [run_dir]/a.out [run_dir]/hello.ml
exec tar cf [run_dir]/genode/bytecode.tar -C [run_dir] a.out
build_boot_image {
ocamlrun libc.lib.so vfs.lib.so libm.lib.so posix.lib.so
}
append qemu_args " -nographic -serial mon:stdio "
run_genode_until {child "ocamlrun" exited with exit value 0.*\n} 30

View File

View File

@@ -0,0 +1 @@
#include <ieeefp.h>

12
src/app/ocamlrun/m.h Normal file
View File

@@ -0,0 +1,12 @@
#define ARCH_SIXTYFOUR
#define SIZEOF_INT 4
#define SIZEOF_LONG 4
#define SIZEOF_PTR 8
#define SIZEOF_SHORT 2
#define SIZEOF_LONGLONG 8
#define INT64_LITERAL(s) s ## LL
#undef ARCH_BIG_ENDIAN
#undef ARCH_ALIGN_DOUBLE
#define ARCH_ALIGN_INT64
#define PROFINFO_WIDTH 0
#define FLAT_FLOAT_ARRAY

View File

62
src/app/ocamlrun/s.h Normal file
View File

@@ -0,0 +1,62 @@
#define OCAML_OS_TYPE "Unix"
#define OCAML_STDLIB_DIR "/usr/local/lib/ocaml"
#define POSIX_SIGNALS
#define HAS_C99_FLOAT_OPS
#undef HAS_GETRUSAGE
#define HAS_TIMES
#undef HAS_SECURE_GETENV
#define HAS_SOCKETS
#define HAS_SOCKLEN_T
#define HAS_INET_ATON
#define HAS_IPV6
#define HAS_STDINT_H
#define HAS_UNISTD
#define HAS_OFF_T
#define HAS_DIRENT
#define HAS_REWINDDIR
#define HAS_LOCKF
#define HAS_MKFIFO
#define HAS_GETCWD
#define HAS_GETPRIORITY
#define HAS_UTIME
#define HAS_UTIMES
#define HAS_DUP2
#define HAS_FCHMOD
#define HAS_TRUNCATE
#define HAS_SYS_SELECT_H
#define HAS_SELECT
#define HAS_NANOSLEEP
#define HAS_SYMLINK
#define HAS_WAITPID
#define HAS_WAIT4
#define HAS_GETGROUPS
#define HAS_SETGROUPS
#define HAS_INITGROUPS
#define HAS_TERMIOS
#define HAS_ASYNC_IO
#define HAS_SETITIMER
#define HAS_GETHOSTNAME
#define HAS_UNAME
#define HAS_GETTIMEOFDAY
#define HAS_MKTIME
#define HAS_SETSID
#undef HAS_PUTENV
#define HAS_LOCALE
#define SUPPORT_DYNAMIC_LINKING
#define HAS_MMAP
#define HAS_PWRITE
#undef HAS_NANOSECOND_STAT
#define HAS_GETHOSTBYNAME_R 6
#define HAS_GETHOSTBYADDR_R 8
#define HAS_MKSTEMP
#undef HAS_NICE
#undef HAS_DUP3
#undef HAS_PIPE2
#define HAS_ACCEPT4
#undef HAS_GETAUXVAL
#undef HAS_SYS_SHM_H
#undef HAS_EXECVPE
#undef HAS_STACK_OVERFLOW_DETECTION
#undef HAS_SIGWAIT
#undef HAS_HUGE_PAGES
#undef HUGE_PAGE_SIZE

View File

@@ -0,0 +1,81 @@
TARGET = ocamlrun
LIBS += ocaml-unix ocaml-str ocaml-threads posix libc
OCAML_PORT_DIR := $(call select_from_ports,ocaml)
BYTERUN_DIR := $(OCAML_PORT_DIR)/src/ocaml/byterun
INC_DIR += $(PRG_DIR)
INC_DIR += $(BYTERUN_DIR)
OCAML_VERSION_STRING := $(shell head -n 1 $(BYTERUN_DIR)/../VERSION)
CC_DEF += -DOCAML_VERSION_STRING=\"$(OCAML_VERSION_STRING)\"
CC_DEF += -DOCAML_VERSION=\"$(OCAML_VERSION_STRING)\"
# CC_DEF += -DDEBUG
PRIMS=\
alloc.c array.c compare.c extern.c floats.c gc_ctrl.c hash.c \
intern.c interp.c ints.c io.c lexing.c md5.c meta.c obj.c parsing.c \
signals.c str.c sys.c callback.c weak.c finalise.c stacks.c \
dynlink.c backtrace_prim.c backtrace.c spacetime.c afl.c \
bigarray.c
BYTERUN_SRC=$(addsuffix .c, \
interp misc stacks fix_code startup_aux startup \
freelist major_gc minor_gc memory alloc roots globroots \
fail signals signals_byt printexc backtrace_prim backtrace \
compare ints floats str array io extern intern \
hash sys meta parsing gc_ctrl md5 obj \
lexing callback debugger weak compact finalise custom \
dynlink spacetime afl unix bigarray main instrtrace)
primitives : $(addprefix $(BYTERUN_DIR)/,$(PRIMS))
$(MSG_CONVERT $@)
$(VERBOSE)sed -n -e "s/CAMLprim value \([a-z0-9_][a-z0-9_]*\).*/\1/p" $^ \
| LC_ALL=C sort | uniq > primitives
.headers: caml/opnames.h caml/jumptbl.h
$(VERBOSE)touch $@
prims.c : primitives .headers
$(MSG_CONVERT $@)
$(VERBOSE)(echo '#define CAML_INTERNALS'; \
echo '#include "caml/mlvalues.h"'; \
echo '#include "caml/prims.h"'; \
sed -e 's/.*/extern value &();/' primitives; \
echo 'c_primitive caml_builtin_cprim[] = {'; \
sed -e 's/.*/ &,/' primitives; \
echo ' 0 };'; \
echo 'char * caml_names_of_builtin_cprim[] = {'; \
sed -e 's/.*/ "&",/' primitives; \
echo ' 0 };') > prims.c
caml/opnames.h : $(BYTERUN_DIR)/caml/instruct.h
$(MSG_CONVERT $@)
$(VERBOSE)mkdir -p $(dir $@)
$(VERBOSE)cat $^ | tr -d '\r' | \
sed -e '/\/\*/d' \
-e '/^#/d' \
-e 's/enum /char * names_of_/' \
-e 's/{$$/[] = {/' \
-e 's/\([[:upper:]][[:upper:]_0-9]*\)/"\1"/g' > $@
caml/jumptbl.h: $(BYTERUN_DIR)/caml/instruct.h
$(MSG_CONVERT $@)
$(VERBOSE)mkdir -p $(dir $@)
$(VERBOSE)sed -E -n -e '/^ /s/ ([A-Z])/ \&\&lbl_\1/gp' -e '/^}/q' $< > $@
caml/version.h:
$(MSG_CONVERT $@)
$(VERBOSE)mkdir -p $(dir $@)
$(VERBOSE)echo #define OCAML_VERSION $(OCAML_VERSION_STRING) > $@
SRC_C += $(PRIMS)
SRC_C += $(BYTERUN_SRC)
SRC_C += prims.c
vpath %.c $(BYTERUN_DIR)
$(BYTERUN_SRC:.c=.o): .headers