-
Notifications
You must be signed in to change notification settings - Fork 91
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Removing the dependency on the libucontext library makes it easier to…
… build for macOS on arm processors (#892)
- Loading branch information
Showing
9 changed files
with
248 additions
and
48 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,199 @@ | ||
// Compiler for PHP (aka KPHP) | ||
// libucontext (c) https://github.com/kaniini/libucontext/tree/master (copied as third-party and slightly modified) | ||
// Copyright (c) 2023 LLC «V Kontakte» | ||
// Distributed under the GPL v3 License, see LICENSE.notice.txt | ||
|
||
#include "common/ucontext/ucontext.h" | ||
|
||
#include <cstdarg> | ||
#include <cstdint> | ||
#include <cstdio> | ||
#include <cstdlib> | ||
|
||
enum { SP_OFFSET = 432, PC_OFFSET = 440, PSTATE_OFFSET = 448, FPSIMD_CONTEXT_OFFSET = 464 }; | ||
|
||
#define R0_OFFSET REG_OFFSET(0) | ||
|
||
#define REG_OFFSET(__reg) (MCONTEXT_GREGS + ((__reg)*REG_SZ)) | ||
|
||
#define REG_SZ (8) | ||
#define MCONTEXT_GREGS (184) | ||
|
||
_Static_assert(offsetof(libucontext_ucontext, uc_mcontext.regs[0]) == R0_OFFSET, "R0_OFFSET is invalid"); | ||
_Static_assert(offsetof(libucontext_ucontext, uc_mcontext.sp) == SP_OFFSET, "SP_OFFSET is invalid"); | ||
_Static_assert(offsetof(libucontext_ucontext, uc_mcontext.pc) == PC_OFFSET, "PC_OFFSET is invalid"); | ||
_Static_assert(offsetof(libucontext_ucontext, uc_mcontext.pstate) == PSTATE_OFFSET, "PSTATE_OFFSET is invalid"); | ||
|
||
__attribute__((visibility("hidden"))) void libucontext_trampoline() { | ||
libucontext_ucontext *uc_link = nullptr; | ||
|
||
asm("mov %0, x19" : "=r"((uc_link))); | ||
|
||
if (uc_link == nullptr) { | ||
exit(0); | ||
} | ||
|
||
libucontext_setcontext(uc_link); | ||
} | ||
|
||
void libucontext_makecontext(libucontext_ucontext *ucp, void (*func)(), int argc, ...) { | ||
unsigned long *sp; | ||
unsigned long *regp; | ||
va_list va; | ||
int i; | ||
|
||
sp = reinterpret_cast<unsigned long *>(reinterpret_cast<uintptr_t>(ucp->uc_stack.ss_sp) + ucp->uc_stack.ss_size); | ||
sp -= argc < 8 ? 0 : argc - 8; | ||
sp = reinterpret_cast<unsigned long *>(((reinterpret_cast<uintptr_t>(sp) & -16L))); | ||
|
||
ucp->uc_mcontext.sp = reinterpret_cast<uintptr_t>(sp); | ||
ucp->uc_mcontext.pc = reinterpret_cast<uintptr_t>(func); | ||
ucp->uc_mcontext.regs[19] = reinterpret_cast<uintptr_t>(ucp->uc_link); | ||
ucp->uc_mcontext.regs[30] = reinterpret_cast<uintptr_t>(&libucontext_trampoline); | ||
|
||
va_start(va, argc); | ||
|
||
regp = &(ucp->uc_mcontext.regs[0]); | ||
|
||
for (i = 0; (i < argc && i < 8); i++) { | ||
*regp++ = va_arg(va, unsigned long); | ||
} | ||
|
||
for (; i < argc; i++) { | ||
*sp++ = va_arg(va, unsigned long); | ||
} | ||
|
||
va_end(va); | ||
} | ||
|
||
asm(R"( | ||
.global _libucontext_getcontext; | ||
.align 2; | ||
_libucontext_getcontext: | ||
str xzr, [x0, #((184) + ((0) * (8)))] // #REG_OFFSET(0) | ||
/* save GPRs */ | ||
stp x0, x1, [x0, #((184) + ((0) * (8)))] // REG_OFFSET(0) | ||
stp x2, x3, [x0, #((184) + ((2) * (8)))] // REG_OFFSET(2) | ||
stp x4, x5, [x0, #((184) + ((4) * (8)))] // REG_OFFSET(4) | ||
stp x6, x7, [x0, #((184) + ((6) * (8)))] // REG_OFFSET(6) | ||
stp x8, x9, [x0, #((184) + ((8) * (8)))] // REG_OFFSET(8) | ||
stp x10, x11, [x0, #((184) + ((10) * (8)))] // REG_OFFSET(10) | ||
stp x12, x13, [x0, #((184) + ((12) * (8)))] // REG_OFFSET(12) | ||
stp x14, x15, [x0, #((184) + ((14) * (8)))] // REG_OFFSET(14) | ||
stp x16, x17, [x0, #((184) + ((16) * (8)))] // REG_OFFSET(16) | ||
stp x18, x19, [x0, #((184) + ((18) * (8)))] // REG_OFFSET(18) | ||
stp x20, x21, [x0, #((184) + ((20) * (8)))] // REG_OFFSET(20) | ||
stp x22, x23, [x0, #((184) + ((22) * (8)))] // REG_OFFSET(22) | ||
stp x24, x25, [x0, #((184) + ((24) * (8)))] // REG_OFFSET(24) | ||
stp x26, x27, [x0, #((184) + ((26) * (8)))] // REG_OFFSET(26) | ||
stp x28, x29, [x0, #((184) + ((28) * (8)))] // REG_OFFSET(28) | ||
str x30, [x0, #((184) + ((30) * (8)))] // REG_OFFSET(30) | ||
/* save current program counter in link register */ | ||
str x30, [x0, #440] // PC_OFFSET | ||
/* save current stack pointer */ | ||
mov x2, sp | ||
str x2, [x0, #432] // SP_OFFSET | ||
/* save pstate */ | ||
str xzr, [x0, #448] // PSTATE_OFFSET | ||
add x2, x0, #464 // FPSIMD_CONTEXT_OFFSET | ||
stp q8, q9, [x2, #144] | ||
stp q10, q11, [x2, #176] | ||
stp q12, q13, [x2, #208] | ||
stp q14, q15, [x2, #240] | ||
mov x0, #0 | ||
ret | ||
)"); | ||
|
||
asm(R"( | ||
.global _libucontext_setcontext; | ||
.align 2; | ||
_libucontext_setcontext: | ||
/* restore GPRs */ | ||
ldp x18, x19, [x0, #((184) + ((18) * (8)))] // REG_OFFSET(18) | ||
ldp x20, x21, [x0, #((184) + ((20) * (8)))] // REG_OFFSET(20) | ||
ldp x22, x23, [x0, #((184) + ((22) * (8)))] // REG_OFFSET(22) | ||
ldp x24, x25, [x0, #((184) + ((24) * (8)))] // REG_OFFSET(24) | ||
ldp x26, x27, [x0, #((184) + ((26) * (8)))] // REG_OFFSET(26) | ||
ldp x28, x29, [x0, #((184) + ((28) * (8)))] // REG_OFFSET(28) | ||
ldr x30, [x0, #((184) + ((30) * (8)))] // REG_OFFSET(30) | ||
/* save current stack pointer */ | ||
ldr x2, [x0, #432] // SP_OFFSET | ||
mov sp, x2 | ||
add x2, x0, #464 // FPSIMD_CONTEXT_OFFSET | ||
ldp q8, q9, [x2, #144] | ||
ldp q10, q11, [x2, #176] | ||
ldp q12, q13, [x2, #208] | ||
ldp q14, q15, [x2, #240] | ||
/* save current program counter in link register */ | ||
ldr x16, [x0, #440] // PC_OFFSET | ||
/* restore args */ | ||
ldp x2, x3, [x0, #((184) + ((2) * (8)))] // REG_OFFSET(2) | ||
ldp x4, x5, [x0, #((184) + ((4) * (8)))] // REG_OFFSET(4) | ||
ldp x6, x7, [x0, #((184) + ((6) * (8)))] // REG_OFFSET(6) | ||
ldp x0, x1, [x0, #((184) + ((0) * (8)))] // REG_OFFSET(8) | ||
/* jump to new PC */ | ||
br x16 | ||
)"); | ||
|
||
asm(R"( | ||
.global _libucontext_swapcontext; | ||
.align 2; | ||
_libucontext_swapcontext: | ||
str xzr, [x0, #((184) + ((0) * (8)))] // REG_OFFSET(0) | ||
/* save GPRs */ | ||
stp x2, x3, [x0, #((184) + ((2) * (8)))] // REG_OFFSET(2) | ||
stp x4, x5, [x0, #((184) + ((4) * (8)))] // REG_OFFSET(4) | ||
stp x6, x7, [x0, #((184) + ((6) * (8)))] // REG_OFFSET(6) | ||
stp x8, x9, [x0, #((184) + ((8) * (8)))] // REG_OFFSET(8) | ||
stp x10, x11, [x0, #((184) + ((10) * (8)))] // REG_OFFSET(10) | ||
stp x12, x13, [x0, #((184) + ((12) * (8)))] // REG_OFFSET(12) | ||
stp x14, x15, [x0, #((184) + ((14) * (8)))] // REG_OFFSET(14) | ||
stp x16, x17, [x0, #((184) + ((16) * (8)))] // REG_OFFSET(16) | ||
stp x18, x19, [x0, #((184) + ((18) * (8)))] // REG_OFFSET(18) | ||
stp x20, x21, [x0, #((184) + ((20) * (8)))] // REG_OFFSET(20) | ||
stp x22, x23, [x0, #((184) + ((22) * (8)))] // REG_OFFSET(22) | ||
stp x24, x25, [x0, #((184) + ((24) * (8)))] // REG_OFFSET(24) | ||
stp x26, x27, [x0, #((184) + ((26) * (8)))] // REG_OFFSET(26) | ||
stp x28, x29, [x0, #((184) + ((28) * (8)))] // REG_OFFSET(28) | ||
str x30, [x0, #((184) + ((30) * (8)))] // REG_OFFSET(30) | ||
/* save current program counter in link register */ | ||
str x30, [x0, #440] // PC_OFFSET | ||
/* save current stack pointer */ | ||
mov x2, sp | ||
str x2, [x0, #432] // SP_OFFSET | ||
/* save pstate */ | ||
str xzr, [x0, #448] // PSTATE_OFFSET | ||
add x2, x0, #464 // FPSIMD_CONTEXT_OFFSET | ||
stp q8, q9, [x2, #144] | ||
stp q10, q11, [x2, #176] | ||
stp q12, q13, [x2, #208] | ||
stp q14, q15, [x2, #240] | ||
/* context to swap to is in x1 so... we move to x0 and call setcontext */ | ||
/* store our link register in x28 */ | ||
mov x28, x30 | ||
/* move x1 to x0 and call setcontext */ | ||
mov x0, x1 | ||
bl _libucontext_setcontext | ||
/* hmm, we came back here try to return */ | ||
mov x30, x28 | ||
ret | ||
)"); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
// Compiler for PHP (aka KPHP) | ||
// Copyright (c) 2018-2022 Ariadne Conill <[email protected]> | ||
// https://github.com/kaniini/libucontext/tree/master (copied as third-party and slightly modified) | ||
// Copyright (c) 2023 LLC «V Kontakte» | ||
// Distributed under the GPL v3 License, see LICENSE.notice.txt | ||
|
||
#pragma once | ||
|
||
#include <cstddef> | ||
|
||
struct libucontext_mcontext { | ||
unsigned long fault_address; | ||
unsigned long regs[31]; | ||
unsigned long sp, pc, pstate; | ||
long double __reserved[256]; | ||
}; | ||
|
||
struct libucontext_stack { | ||
void *ss_sp; | ||
int ss_flags; | ||
size_t ss_size; | ||
}; | ||
|
||
struct libucontext_ucontext { | ||
unsigned long uc_flags; | ||
struct libucontext_ucontext *uc_link; | ||
libucontext_stack uc_stack; | ||
unsigned char __pad[136]; | ||
libucontext_mcontext uc_mcontext; | ||
}; | ||
|
||
extern "C" { | ||
void libucontext_makecontext(libucontext_ucontext *, void (*)(), int, ...); | ||
int libucontext_getcontext(libucontext_ucontext *); | ||
int libucontext_setcontext(const libucontext_ucontext *); | ||
int libucontext_swapcontext(libucontext_ucontext *, const libucontext_ucontext *); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters