-
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.
Add user context manipulation routines for linux x86_64
Signed-off-by: Petr Shumilov <[email protected]>
- Loading branch information
1 parent
5e4b58a
commit ab0b951
Showing
25 changed files
with
741 additions
and
107 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
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,54 @@ | ||
// 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[29]; | ||
unsigned long fp, lr, 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; | ||
}; | ||
|
||
inline constexpr void *get_context_stack_ptr_portable(const libucontext_ucontext &ctx) noexcept { | ||
return ctx.uc_stack.ss_sp; | ||
} | ||
|
||
inline constexpr size_t get_context_stack_size_portable(const libucontext_ucontext &ctx) noexcept { | ||
return ctx.uc_stack.ss_size; | ||
} | ||
|
||
inline constexpr void set_context_stack_ptr_portable(libucontext_ucontext &ctx, void *sp) noexcept { | ||
ctx.uc_stack.ss_sp = sp; | ||
} | ||
|
||
inline constexpr void set_context_stack_size_portable(libucontext_ucontext &ctx, size_t size) noexcept { | ||
ctx.uc_stack.ss_size = size; | ||
} | ||
|
||
inline constexpr void set_context_link_portable(libucontext_ucontext &ctx, libucontext_ucontext *link) noexcept { | ||
ctx.uc_link = link; | ||
} | ||
|
||
inline void *get_context_stack_base_ptr_portable(const libucontext_ucontext &ctx) noexcept { | ||
return reinterpret_cast<void *>(ctx.uc_mcontext.fp); | ||
} |
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,25 @@ | ||
#include <ucontext.h> | ||
|
||
inline constexpr void *get_context_stack_ptr_portable(const ucontext_t &ctx) noexcept { | ||
return ctx.uc_stack.ss_sp; | ||
} | ||
|
||
inline constexpr size_t get_context_stack_size_portable(const ucontext_t &ctx) noexcept { | ||
return ctx.uc_stack.ss_size; | ||
} | ||
|
||
inline constexpr void set_context_stack_ptr_portable(ucontext_t &ctx, void *sp) noexcept { | ||
ctx.uc_stack.ss_sp = sp; | ||
} | ||
|
||
inline constexpr void set_context_stack_size_portable(ucontext_t &ctx, size_t size) noexcept { | ||
ctx.uc_stack.ss_size = size; | ||
} | ||
|
||
inline constexpr void set_context_link_portable(ucontext_t &ctx, ucontext_t *link) noexcept { | ||
ctx.uc_link = link; | ||
} | ||
|
||
inline void *get_context_stack_base_ptr_portable(const ucontext_t &ctx) noexcept { | ||
return reinterpret_cast<void *>(ctx.uc_mcontext->__ss.__rbp); | ||
} |
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,26 @@ | ||
#include <ucontext.h> | ||
|
||
inline constexpr void *get_context_stack_ptr_portable(const ucontext_t &ctx) noexcept { | ||
return ctx.uc_stack.ss_sp; | ||
} | ||
|
||
inline constexpr size_t get_context_stack_size_portable(const ucontext_t &ctx) noexcept { | ||
return ctx.uc_stack.ss_size; | ||
} | ||
|
||
inline constexpr void set_context_stack_ptr_portable(ucontext_t &ctx, void *sp) noexcept { | ||
ctx.uc_stack.ss_sp = sp; | ||
} | ||
|
||
inline constexpr void set_context_stack_size_portable(ucontext_t &ctx, size_t size) noexcept { | ||
ctx.uc_stack.ss_size = size; | ||
} | ||
|
||
inline constexpr void set_context_link_portable(ucontext_t &ctx, ucontext_t *link) noexcept { | ||
ctx.uc_link = link; | ||
} | ||
|
||
inline void *get_context_stack_base_ptr_portable(const ucontext_t &ctx) noexcept { | ||
// 29 -- Frame Pointer, based on AArch64 spec | ||
return reinterpret_cast<void *>(ctx.uc_mcontext.regs[29]); | ||
} |
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,113 @@ | ||
#include <cstddef> | ||
#include <cstdint> | ||
#include "defs.h" | ||
|
||
#pragma once | ||
|
||
// Type for general register | ||
using kgreg_t = uint64_t; | ||
|
||
// Container for all general registers | ||
using kgregset_t = kgreg_t[NUM_GENERAL_REG]; | ||
|
||
// Prohibit packing | ||
#pragma pack(push, 1) | ||
|
||
struct kfpxreg { | ||
uint16_t significand[4]; | ||
uint16_t exponent; | ||
uint16_t reserved1[3]; | ||
}; | ||
|
||
struct kxmmreg { | ||
uint32_t element[4]; | ||
}; | ||
|
||
struct kfpstate { | ||
uint16_t cwd; | ||
uint16_t swd; | ||
uint16_t ftw; | ||
uint16_t fop; | ||
uint16_t rip; | ||
uint16_t rdp; | ||
uint16_t mxcsr; | ||
uint16_t mxcr_mask; | ||
kfpxreg st[8]; | ||
kxmmreg xmm[16]; | ||
uint32_t reserved1[24]; | ||
}; | ||
|
||
// Structure to describe FPU registers | ||
using kfpregset_t = kfpstate *; | ||
|
||
// Context to describe whole processor state | ||
struct kmcontext_t { | ||
kgregset_t gregs; | ||
// Note that fpregs is a pointer | ||
kfpregset_t fpregs; | ||
uint64_t reserved1[8]; | ||
}; | ||
|
||
struct kstack_t { | ||
void *sp; | ||
uint64_t size; | ||
}; | ||
|
||
// Userlevel KPHP context | ||
struct kcontext_t { | ||
uint64_t flags; | ||
kcontext_t *link; | ||
kstack_t stack; | ||
kmcontext_t mcontext; | ||
kfpstate fpregs_mem; | ||
}; | ||
|
||
#pragma pack(pop) | ||
|
||
inline constexpr void *get_context_stack_ptr_portable(const kcontext_t &ctx) noexcept { | ||
return ctx.stack.sp; | ||
} | ||
|
||
inline constexpr uint64_t get_context_stack_size_portable(const kcontext_t &ctx) noexcept { | ||
return ctx.stack.size; | ||
} | ||
|
||
inline constexpr void set_context_stack_ptr_portable(kcontext_t &ctx, void *sp) noexcept { | ||
ctx.stack.sp = sp; | ||
} | ||
|
||
inline constexpr void set_context_stack_size_portable(kcontext_t &ctx, uint64_t size) noexcept { | ||
ctx.stack.size = size; | ||
} | ||
|
||
inline constexpr void set_context_link_portable(kcontext_t &ctx, kcontext_t *link) noexcept { | ||
ctx.link = link; | ||
} | ||
|
||
inline void *get_context_stack_base_ptr_portable(const kcontext_t &ctx) noexcept { | ||
return reinterpret_cast<void *>(ctx.mcontext.gregs[GREG_RBP]); | ||
} | ||
|
||
// Zero-cost offsets double-checking | ||
static_assert(offsetof(kcontext_t, mcontext.gregs[GREG_RBP]) == oRBP, "Invalid offset assumption"); | ||
static_assert(offsetof(kcontext_t, mcontext.gregs[GREG_RSP]) == oRSP, "Invalid offset assumption"); | ||
static_assert(offsetof(kcontext_t, mcontext.gregs[GREG_RBX]) == oRBX, "Invalid offset assumption"); | ||
static_assert(offsetof(kcontext_t, mcontext.gregs[GREG_R8]) == oR8, "Invalid offset assumption"); | ||
static_assert(offsetof(kcontext_t, mcontext.gregs[GREG_R9]) == oR9, "Invalid offset assumption"); | ||
static_assert(offsetof(kcontext_t, mcontext.gregs[GREG_R10]) == oR10, "Invalid offset assumption"); | ||
static_assert(offsetof(kcontext_t, mcontext.gregs[GREG_R11]) == oR11, "Invalid offset assumption"); | ||
static_assert(offsetof(kcontext_t, mcontext.gregs[GREG_R12]) == oR12, "Invalid offset assumption"); | ||
static_assert(offsetof(kcontext_t, mcontext.gregs[GREG_R13]) == oR13, "Invalid offset assumption"); | ||
static_assert(offsetof(kcontext_t, mcontext.gregs[GREG_R14]) == oR14, "Invalid offset assumption"); | ||
static_assert(offsetof(kcontext_t, mcontext.gregs[GREG_R15]) == oR15, "Invalid offset assumption"); | ||
static_assert(offsetof(kcontext_t, mcontext.gregs[GREG_RDI]) == oRDI, "Invalid offset assumption"); | ||
static_assert(offsetof(kcontext_t, mcontext.gregs[GREG_RSI]) == oRSI, "Invalid offset assumption"); | ||
static_assert(offsetof(kcontext_t, mcontext.gregs[GREG_RDX]) == oRDX, "Invalid offset assumption"); | ||
static_assert(offsetof(kcontext_t, mcontext.gregs[GREG_RAX]) == oRAX, "Invalid offset assumption"); | ||
static_assert(offsetof(kcontext_t, mcontext.gregs[GREG_RCX]) == oRCX, "Invalid offset assumption"); | ||
static_assert(offsetof(kcontext_t, mcontext.gregs[GREG_RIP]) == oRIP, "Invalid offset assumption"); | ||
static_assert(offsetof(kcontext_t, mcontext.gregs[GREG_EFL]) == oEFL, "Invalid offset assumption"); | ||
static_assert(offsetof(kcontext_t, mcontext.gregs) == KCONTEXT_MCONTEXT_GREGS, "Invalid offset assumption"); | ||
static_assert(offsetof(kcontext_t, mcontext.fpregs) == KCONTEXT_MCONTEXT_FPREGS, "Invalid offset assumption"); | ||
static_assert(offsetof(kcontext_t, fpregs_mem) == KCONTEXT_FPREGS_MEM, "Invalid offset assumption"); | ||
static_assert(offsetof(kcontext_t, fpregs_mem.mxcsr) == KCONTEXT_FPREGS_MEM_MXCSR, "Invalid offset assumption"); |
Oops, something went wrong.