This implements the required asm functions for sparc64_sysv_elf and
was tested on an OpenBSD/sparc64 system.
Jump_fcontext uses an extra C call frame to store the frame-pointer and
return address. Because of this the code is simply a save (to new reg
window), then forcing a window flush and finally switch stack and restore
from there.
Since jump_fcontext() uses a register window and stack frame, make_fcontext()
reserves two call frames on the stack (one for jump_fcontext() and the other
for the callback function).
OpenBSD/sparc64 uses stackghost which prevents userland from overriding the
return-address on the stack. Because of this make_fcontext() uses an extra
trampoline to implement the _exit(0) call if the callback returns.
All tests pass with this on OpenBSD/sparc64 (also the tests for fiber,
coroutine and coroutine2).
SysV ABI requires a stack alignment of 16 bytes. Currently, for i386
with SysV ABI, the trampoline function is entered with an unaligned
stack. This causes problems for the context-function that is jumped to
as its stack is also unaligned. This causes a crash for our use-case
because the context function contains an SSE instruction which reads
from the stack. The SSE instruction requires the correct alignment.
Fix it by changing the 0x2c offset to 0x30, such that the stack remains
aligned.
Shadow stack is part of Intel's Control-Flow Enforcement Technology.
Whenever a function is called, the return address is pushed onto both
the regular stack and the shadow stack. When that function returns, the
return addresses are popped off both stacks and compared; if they fail
to match, #CP raised.
Backport this commit from https://github.com/php/php-src/pull/9283
With this commit, we create shadow stack with syscall map_shadow_stack
(no.451) for each fiber context and switch the shadow stack accordingly
during fcontext switch.
Signed-off-by: PeterYang12 <yuhan.yang@intel.com>
Signed-off-by: chen-hu-97 <hu1.chen@intel.com>
Indirect Branch Tracking(IBT) is part of Intel's Control-Flow
Enforcement Technology(CET). IBT is hardware based, forward edge
Control-Flow-Integrity mechanism where any indirect CALL/JMP must
target an ENDBR instruction or suffer #CP.
This commit inserts endbr64 instruction in assembly to support IBT.
AIX assembler is a bit more strict than GNU assembler. Thus, adjust
the XCOFF asm files to be able to accept both assembler.
For PPC64 jump and make files, most of the work have already been
made recently, only the functions' header needs to be updated.
For PPC64 ontop and PPC32 files, the algorithms where also wrong.
So the whole files have been reworked.
The PPC32 stack layout is based on AIX documentation:
https://www.ibm.com/docs/en/aix/7.2?topic=overview-runtime-process-stack
For PPC64, as it seems to work fine and is already being used in php,
I've kept the current layout based on PPC64 Linux version.
Tested with boost/context, boost/fiber and boost/coroutine2.
Note that the test_sscanf is still failing in ppc32 because of
float precision. (3.13999 is returned instead of 3.14).
On C++11 static local variables are initialized in thread-safe manner, but even on C++03 it should not be a problem because in our case variables are of trivial types, which means double initialization is not an issue, and they are initialized with the same value in every thread.
Apple silicon M1 uses arm64 architecture, this commit will add arm and
arm64 architecture into combined asm code in order to support newer
apple's machine in combined asm codes.
We set the LSB of the magic symbol @feat.00 to 1.
This is used to communicate from the compiler to the linker, and specifically to express that the object file has opted into "safeseh"; any SEH handlers used in this file must be listed in the .sxdata section.
Since we don't have any SEH handlers in these files, this is trivially satisfied.
Reference: the PE-COFF specification, https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#the-sxdata-section
This fixes fcontext on my PowerBook G4 running Void Linux
ppc-musl-20190901, NetBSD/macppc 8.1, or OpenBSD/macppc 6.6-current,
all with g++. These systems use fcontext for *ppc32_sysv_elf*
(PowerPC 32-bit System V ELF). The assembly code was wrong for BSD
and crashing on Linux musl.
Linux returns a transfer_t in memory (through a hidden pointer in R3),
but other systems (at least NetBSD and OpenBSD) return a transfer_t in
registers R3:R4. jump_fcontext() and ontop_fcontext() were always
using the hidden pointer. Add checks for `#ifdef__linux__`; start
using R3:R4 on other systems.
make_fcontext() was calling _exit(0) through the insecure BSS PLT.
Set R30 to use the secure PLT. This prevents a crash when musl's
ld.so loads the executable; musl seems to require the secure PLT.
Fix ontop_fcontext() to restore the hidden pointer on Linux. It was
passing the wrong context's hidden pointer to the ontop-function fn(),
so fn() returned a transfer_t to the wrong stack. When fn() was
context_exit() in <boost/context/continuation_fcontext.hpp>, it freed
the old stack, then returned `transfer_t{ nullptr, nullptr }` to free
memory. This crashed on Linux musl.
Now that ontop_fcontext() restores the hidden pointer, it must stop
abusing the same pointer to pass a transfer_t argument to fn(). Add a
new ontop_fcontext_tail() in C++, which takes arguments in registers
and allocates a transfer_t. The code is in C++ so it can free the
transfer_t argument if fn() throws a C++ exception.
Rearrange the context frame to shrink it from 244 to 240 bytes. This
fixes the stack alignment: the ABI requires R1 % 16 == 0, and
make_fcontext() respects this, but jump_fcontext() was adding 244 to
R1, so the new context ran with a misaligned stack (244 % 16 == 4).
Remove R13 from the context frame, so new contexts stop loading R13
with garbage. The ABI uses R13 to point to the executable's small
data, so R13 should have the same value in every context.
Add the backchain to the context frame; make room by moving LR to the
caller's frame. Order CR, R14 to R31, F14 to F31 at the frame's end,
as is typical for this ABI. Provide 8-byte alignment for FPSCR and
F14 to F31, to avoid a misalignment penalty.
The existing ontop_fcontext implementation for ppc64 ELFv2
violates the ABI by not storing the callback entry address
in %r12 before branching. This results in crashes on this
platform.
This commit addresses this and allows the context library
to function as expected on ppc64 platforms using the ELFv2 ABI.