initial port of golang to genode

Alexander Tormasov a.tormasov at innopolis.ru
Mon Aug 3 02:25:45 CEST 2020


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 at innopolis.ru, origin in https://github.com/tor-m6/genode.git





More information about the users mailing list