3 ms·
> (1) It only works on one architecture. Even this architecture may change optimal alignment requirements in future, which glibc would transparently handle for
by wahern 4y ago
> (1) It only works on one architecture. Even this architecture may change optimal alignment requirements in future, which glibc would transparently handle for you.
A portable solution (on any POSIX system, actually) for the stack switching would be to jump to the new stack using sigaltstack and initialize a sigjmp_t context (i.e. setjmp) from the signal handler. After calling clone you conditionally invoke longjmp based on the return value. This works because setjmp and longjmp are compiler builtins; but if not, use __builtin_setjmp, __builtin_longjmp. (You can pass the sigjmp_t context using the same trick mentioned in the writeup. And of course this also assumes the compiler won't emit stack-dependent code between the syscall and longjmp.)
You still have the problem of implementing the syscalls, though. But maybe if we scrounge around we can find solutions. On some architectures the vdso Linux maps into the process address space has a syscall implementation. And maybe there are similar compiler builtins for other architectures, or macros in the Linux header files with the necessary inline assembly.
As a learning exercise this type of stuff is fun ;)
- manwe150 4y agosetjmp and longjmp are not normally compiler builtins, just some library functions. They are quite different also from the __builtins that you mention, sometimes in quite surprising ways. Actually compilers are very buggy when you use these functions, even if you do follow their quite strict rules for what is allowed. Calling longjmp in a signal handler is technically undefined behavior in posix and trigger issues on some platforms that I have had the displeasure to run into. Recently various hardening options in the definitions of setjmp now make it detect these sorts of attempts and abort the program. So I wouldn’t call all of that very portable, but I agree it is fun!
- deleted 4y ago[deleted]