mirror of
https://github.com/ziglang/zig.git
synced 2025-12-06 14:23:09 +00:00
linux: add getcontext for x86_64
This commit is contained in:
parent
6abf1fbfe6
commit
41832aa1e6
@ -86,6 +86,7 @@ pub const timeval = arch_bits.timeval;
|
|||||||
pub const timezone = arch_bits.timezone;
|
pub const timezone = arch_bits.timezone;
|
||||||
pub const ucontext_t = arch_bits.ucontext_t;
|
pub const ucontext_t = arch_bits.ucontext_t;
|
||||||
pub const user_desc = arch_bits.user_desc;
|
pub const user_desc = arch_bits.user_desc;
|
||||||
|
pub const getcontext = arch_bits.getcontext;
|
||||||
|
|
||||||
pub const tls = @import("linux/tls.zig");
|
pub const tls = @import("linux/tls.zig");
|
||||||
pub const pie = @import("linux/start_pie.zig");
|
pub const pie = @import("linux/start_pie.zig");
|
||||||
@ -4694,7 +4695,7 @@ else
|
|||||||
/// processes.
|
/// processes.
|
||||||
RTPRIO,
|
RTPRIO,
|
||||||
|
|
||||||
/// Maximum CPU time in µs that a process scheduled under a real-time
|
/// Maximum CPU time in µs that a process scheduled under a real-time
|
||||||
/// scheduling policy may consume without making a blocking system
|
/// scheduling policy may consume without making a blocking system
|
||||||
/// call before being forcibly descheduled.
|
/// call before being forcibly descheduled.
|
||||||
RTTIME,
|
RTTIME,
|
||||||
|
|||||||
@ -395,3 +395,71 @@ pub const ucontext_t = extern struct {
|
|||||||
sigmask: sigset_t,
|
sigmask: sigset_t,
|
||||||
fpregs_mem: [64]usize,
|
fpregs_mem: [64]usize,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
fn gpRegisterOffset(comptime reg_index: comptime_int) usize {
|
||||||
|
return @offsetOf(ucontext_t, "mcontext") + @offsetOf(mcontext_t, "gregs") + @sizeOf(usize) * reg_index;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub inline fn getcontext(context: *ucontext_t) usize {
|
||||||
|
asm volatile (
|
||||||
|
\\ movq %%r8, (%[r8_offset])(%[context])
|
||||||
|
\\ movq %%r9, (%[r9_offset])(%[context])
|
||||||
|
\\ movq %%r10, (%[r10_offset])(%[context])
|
||||||
|
\\ movq %%r11, (%[r11_offset])(%[context])
|
||||||
|
\\ movq %%r12, (%[r12_offset])(%[context])
|
||||||
|
\\ movq %%r13, (%[r13_offset])(%[context])
|
||||||
|
\\ movq %%r14, (%[r14_offset])(%[context])
|
||||||
|
\\ movq %%r15, (%[r15_offset])(%[context])
|
||||||
|
\\ movq %%rdi, (%[rdi_offset])(%[context])
|
||||||
|
\\ movq %%rsi, (%[rsi_offset])(%[context])
|
||||||
|
\\ movq %%rbp, (%[rbp_offset])(%[context])
|
||||||
|
\\ movq %%rbx, (%[rbx_offset])(%[context])
|
||||||
|
\\ movq %%rdx, (%[rdx_offset])(%[context])
|
||||||
|
\\ movq %%rax, (%[rax_offset])(%[context])
|
||||||
|
\\ movq %%rcx, (%[rcx_offset])(%[context])
|
||||||
|
\\ movq %%rsp, (%[rsp_offset])(%[context])
|
||||||
|
\\ leaq (%%rip), %%rcx
|
||||||
|
\\ movq %%rcx, (%[rip_offset])(%[context])
|
||||||
|
\\ pushfq
|
||||||
|
\\ popq (%[efl_offset])(%[context])
|
||||||
|
\\ leaq (%[fpmem_offset])(%[context]), %%rcx
|
||||||
|
\\ movq %%rcx, (%[fpstate_offset])(%[context])
|
||||||
|
\\ fnstenv (%%rcx)
|
||||||
|
\\ stmxcsr (%[mxcsr_offset])(%[context])
|
||||||
|
:
|
||||||
|
: [context] "{rdi}" (context),
|
||||||
|
[r8_offset] "p" (comptime gpRegisterOffset(REG.R8)),
|
||||||
|
[r9_offset] "p" (comptime gpRegisterOffset(REG.R9)),
|
||||||
|
[r10_offset] "p" (comptime gpRegisterOffset(REG.R10)),
|
||||||
|
[r11_offset] "p" (comptime gpRegisterOffset(REG.R11)),
|
||||||
|
[r12_offset] "p" (comptime gpRegisterOffset(REG.R12)),
|
||||||
|
[r13_offset] "p" (comptime gpRegisterOffset(REG.R13)),
|
||||||
|
[r14_offset] "p" (comptime gpRegisterOffset(REG.R14)),
|
||||||
|
[r15_offset] "p" (comptime gpRegisterOffset(REG.R15)),
|
||||||
|
[rdi_offset] "p" (comptime gpRegisterOffset(REG.RDI)),
|
||||||
|
[rsi_offset] "p" (comptime gpRegisterOffset(REG.RSI)),
|
||||||
|
[rbp_offset] "p" (comptime gpRegisterOffset(REG.RBP)),
|
||||||
|
[rbx_offset] "p" (comptime gpRegisterOffset(REG.RBX)),
|
||||||
|
[rdx_offset] "p" (comptime gpRegisterOffset(REG.RDX)),
|
||||||
|
[rax_offset] "p" (comptime gpRegisterOffset(REG.RAX)),
|
||||||
|
[rcx_offset] "p" (comptime gpRegisterOffset(REG.RCX)),
|
||||||
|
[rsp_offset] "p" (comptime gpRegisterOffset(REG.RSP)),
|
||||||
|
[rip_offset] "p" (comptime gpRegisterOffset(REG.RIP)),
|
||||||
|
[efl_offset] "p" (comptime gpRegisterOffset(REG.EFL)),
|
||||||
|
[fpstate_offset] "p" (@offsetOf(ucontext_t, "mcontext") + @offsetOf(mcontext_t, "fpregs")),
|
||||||
|
[fpmem_offset] "p" (@offsetOf(ucontext_t, "fpregs_mem")),
|
||||||
|
[mxcsr_offset] "p" (@offsetOf(ucontext_t, "fpregs_mem") + @offsetOf(fpstate, "mxcsr")),
|
||||||
|
: "memory", "rcx"
|
||||||
|
);
|
||||||
|
|
||||||
|
// TODO: Read GS/FS registers?
|
||||||
|
|
||||||
|
// TODO: `flags` isn't present in the getcontext man page, figure out what to write here
|
||||||
|
context.flags = 0;
|
||||||
|
context.link = null;
|
||||||
|
|
||||||
|
const altstack_result = linux.sigaltstack(null, &context.stack);
|
||||||
|
if (altstack_result != 0) return altstack_result;
|
||||||
|
|
||||||
|
return linux.sigprocmask(0, null, &context.sigmask);
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user