Hello Josef, Some relatively long answers below
as a base I borrow some code from glibc, and remove related files (mostly _ucontext.h/ucontext.h) from genode
May I ask what is the reason for choosing and incorporating the glibc implementation rather than using/enabling the one in the FreeBSD libc?
1. current implementation of context switch in FreeBSD done completely in kernel via sys call. E.g. this is full code of getcontext function (stored in genode, not used):
#include <machine/asm.h> __FBSDID("$FreeBSD: releng/12.0/lib/libc/i386/sys/getcontext.S 258451 2013-11-21 22:31:18Z andreast $");
#include <SYS.h>
/* * This has to be magic to handle the multiple returns. * Otherwise, the setcontext() syscall will return here and we'll * pop off the return address and go to the *setcontext* call. */ WEAK_REFERENCE(__sys_getcontext, _getcontext) WEAK_REFERENCE(__sys_getcontext, getcontext) ENTRY(__sys_getcontext) movl (%esp),%ecx /* save getcontext return address */ mov $SYS_getcontext,%eax KERNCALL jb HIDENAME(cerror) addl $4,%esp /* remove stale (setcontext) return address */ jmp *%ecx /* restore return address */ END(__sys_getcontext)
.section .note.GNU-stack,"",%progbits
2. context family support do require complex and misleading structure, e.g. take a look for setcontext code: #include <sys/cdefs.h> __FBSDID("$FreeBSD: releng/12.0/lib/libc/sys/setcontext.c 326576 2017-12-05 20:19:13Z emaste $");
#include <sys/types.h> #include <ucontext.h> #include "libc_private.h"
__weak_reference(__sys_setcontext, __setcontext); __sym_compat(setcontext, __impl_setcontext, FBSD_1.0); __weak_reference(setcontext, __impl_setcontext); __sym_default(setcontext, setcontext, FBSD_1.2);
int setcontext(const ucontext_t *uc) {
return (((int (*)(const ucontext_t *)) __libc_interposing[INTERPOS_setcontext])(uc)); }
I try to understand how all these __libc_interposing works - and fail, this is not currently supported in genode as I understand
3. ucontext.h and related is isolated in current libc and could be easily replaced (because it used only in *context family of functions and signals which has only rudimentary support
4. glibc implementation is straightforward and well supported, relatively small and suitable for big set of platforms, without complex kernel/__libc_interposing analogous and could be borrowed (copied) with minimal efforts, I can confirm this.
5. glibc implementation of these functions do contain potentially useful security feature of shadow stack support (under SHSTK_ENABLED define - not enabled in my patch)
So, I consider option to use existing freeBSD version and replacement of code of functions to ones from glibc - and think that this make everything too complex, related infrastructure not clear and not easy to support. May be I am wrong.
for me simplest for implementation and, especially, for future support - is chosen approach (with part of glibc port). It is simple and straightforward, easy to extend to arm/etc.
Another option I consider is a usage of native context-switch functions for genode low level Os (OS - dependent). Anyway, it will significantly lower performance, and not portable option, so, I do not choose it.
Strictly speaking containg such a large patch makes the commit unsuitable for the Genode main repo as the burden of maintaing it falls on our shoulders at the end and the reason for including it in the first place is not immediately clear.
significant part of patch is a removal of old files like ucontext.h and plain addition of new files, take a look for statistics, no complex updates of files involved: fgrep @@ ./repos/libports/src/lib/libc/patches/zmcontext.patch @@ -0,0 +1,1 @@ @@ -0,0 +1,1 @@ @@ -0,0 +1,1 @@ @@ -0,0 +1,7 @@ @@ -0,0 +1,7 @@ @@ -0,0 +1,1092 @@ @@ -0,0 +1,3 @@ @@ -0,0 +1,3 @@ @@ -0,0 +1,279 @@ @@ -0,0 +1,590 @@ @@ -0,0 +1,3 @@ @@ -0,0 +1,18 @@ @@ -0,0 +1,124 @@ @@ -0,0 +1,137 @@ @@ -1,109 +1,155 @@ @@ -0,0 +1,201 @@ @@ -0,0 +1,256 @@ @@ -0,0 +1,28 @@ @@ -1,48 +0,0 @@ @@ -0,0 +1,97 @@ @@ -0,0 +1,113 @@ @@ -0,0 +1,129 @@ @@ -1,167 +0,0 @@ @@ -1,54 +0,0 @@
By the way, I can make patch smaller if you give me a direction how to remove some files during install or patch process without patch itself, may be via .mk file (e.g. libc-gen.mk)
For better or worse, we still lack the resources (read man-power) as well as a deeper understanding for the issues at hand when it comes to the requirements of the golang-runtime (which somewhat is a consequence of the lack of resources) that such an undertaking arguably deserves.
I need *context() implementation, and it can’t be moved to world repository - its a part of libc.
Also to use functions I need C interface for allocate_seconday_stack() which should be somewhere inside (I choose libc dummies.cchttp://dummies.cc file) Question: may be better other place? e.g. inline C interface function as a part of e.g. thread.h? Any recommendations are welcome!
I understand your point, so, another question is: how I can continue if patch can’t be stored inside genode core? it can’t be significantly smaller (4 functions/files to be add at least)...
Everything else for golang support I will have in world, this is the only part of core (may be together with extended anonymous mmap support).
Sincerely, Alexander