I make some very rough port of golang runtime to genode (mostly for nova), https://github.com/tor-m6/genode.git This work is a side result of one of research project made in Innopolis University.
It allow compilation and execution of simple go applications/packages (probably without unsupported os features). I use only gccgo version of golang compiler. Things like "go build" in cross mode not supported yet (while we make some techology to produce makefiles from "go build" to compilei go code, not attached yet). Other limitations see below.
It build a set of libraries, in form of "libport" and "noux-pkg" each (because we need to run configure which is not supported in libport), as static ones. Also it build a set of standard golang packages (namely fmt, os, syscall, runtime/etc) as files for gccgo compilation. Note: Go runtinme support around 9 systems as backend. I use netbsd as simplest one for the base for new system - "inno".
To implement context switching I have to develop it from the scratch; for stack port use alloc_secondary_stack() from Genode. I suspect that I need to use a low-level context switching from kernel (native thread switch), this is not implemented yet.
Configuration after build ========================= Golang package (like fmt) is an object file (e.g. fmt.o) which appears in build/x86_64/noux-pkg/libgo/ directory and subdirectories. This path should be included during golang/gccgo compilation (not only linking). Built libraries for Go will be in ${LIB_CACHE_DIR}/libgo/libgobegin.a ${LIB_CACHE_DIR}/libgo/libgolibbegin.a ${LIB_CACHE_DIR}/libgo/libgo.a
Current limitations =================== - RAM quota in .run file should be >= 1300M: genode do not support MAP_ANON flag, so, we cant reserve memory (544Gb) for arena, and, therefore, go to Windows-like model with "small" immediate allocation; it force 2GB limitation in code and make direct allocation of ~1.1Gb - can run in VM with 1 CPU only: in general it support checking of CPU number (by backporting patch from current genode code) and trying to run everything, but it hangs somewhere in the middle due to recursive locking (error "deadlock ahead" in acquire() in mutex.cc) May be this is small mistake - don't have time to find and fix (in this place due to slot_jump() gdb do not give normal info related to stack). I found that problem during stack unwind in ... runtime.startm -> runtime.newm -> runtime.newm -> runtime.mcommoninit -> runtime.callers -> runtime_callers() -> backtrace_full() ... here it try to call -> strlcpy() -> _jmp_slot() and make again guard inside this function - it works only on x86_64, tested on nova kernel genode do not support makecontex/setcontext/gencontext family; but it is crucial to support go because of goroutine model; I have to implement it by myself. It is machine-dependent; moreover, context swiching do not work after direct port from libc/etc - I have to make 1 step stack unwind procedure to jump using stack frame to the next function. So, I add everywhere compilation option -fno-omit-frame-pointer to be sure that this approach works. Probably it need only for implementation of the file mycontext.cc - it can work on seL4 as well, while I did not submit additional dirty changes for go runtime (I swithed to nova/gdb) - any go application need to add 3 files into it (may be it worth to place them in another library or libgo.a) - dummy.cc with Genode initialization and some empty functions which are not supported on genode, mycontext.cc and myacontext.s with implementation of x86 [sg]etcontext - during port I make a set of dirty fixes for absent on the platform (genode/nova), in particular "empty" C implementaion of sendfile(), getpgid(), lchown(), mount(), settimeofday(), mlock(), munlock(), mlockall(), munlockall(), sigaltstack(); in go part of runtime port I also "damage" some functions, in particualr route.sysctl(), broke poll.ReadDirent(), partially broke logic in runtime.sysMap/sysReserve because of unsupported mem range reservation, do not use ptrace, broke routing in netbsd version of syscall.toRoutingMessage and some others, see patches for libgo in repos/libports/src/lib/libgo/. so, anything in Golang which use them will fail. Potentially new genode releases will contain something which can replace or fix these and other patched functions - once I compile all code with -O3 option, and it hangs. I did not check why...
Questions? tor@innopolis.ru, origin in https://github.com/tor-m6/genode.git
I checked sel4 kernel and my golang port - it works! I need to enlarge number of capabilities (to 200) and size of vm (1400M at least).
And, it can’t exit normally, seems that atexit() do not finish all threads correctly (some of them instead of termination try to access memory to process the signals, while this memory are already released).
It works with the same limitations as for nova. It able to run with 2 CPU (but give some error messages about signal), not able to run with 4 CPU. Seems that the problem is in signal handling (probably my removal of sigaltstack() sys call make a problem).
so, in this moment I can confirm work of simple test for golang on genode 20.05 1 CPU x86 for nova and sel4 kernels.
3 авг. 2020 г., в 03:25, Alexander Tormasov via users users@lists.genode.org написал(а):
I make some very rough port of golang runtime to genode (mostly for nova), https://github.com/tor-m6/genode.git This work is a side result of one of research project made in Innopolis University.