[set,get,make,swap]context from glibc for amd64 implementation and question for Norman

Alexander Tormasov a.tormasov at innopolis.ru
Sat Mar 13 00:46:02 CET 2021


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.cc<http://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

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.genode.org/pipermail/users/attachments/20210312/320a145b/attachment-0001.html>


More information about the users mailing list