aboutsummaryrefslogtreecommitdiff
path: root/lib/std/os/linux
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2023-07-31 15:34:32 -0700
committerGitHub <noreply@github.com>2023-07-31 15:34:32 -0700
commite84cda0ebf8886346d42db78e8f3eb8d0bf515bd (patch)
tree9e0ed316fd374bcc3f7a4f26ff70291a9d1ca9fb /lib/std/os/linux
parent8f5c333ebe6631629be3b88d797a03b1d677d439 (diff)
parent228c956377e4f33e45fad7e0ba5d9eb5073803a5 (diff)
downloadzig-e84cda0ebf8886346d42db78e8f3eb8d0bf515bd.tar.gz
zig-e84cda0ebf8886346d42db78e8f3eb8d0bf515bd.zip
Merge pull request #16622 from jacobly0/cbe-asm-compat
CBE: fix regressions and get new targets passing behavior tests
Diffstat (limited to 'lib/std/os/linux')
-rw-r--r--lib/std/os/linux/arm-eabi.zig44
-rw-r--r--lib/std/os/linux/arm64.zig7
-rw-r--r--lib/std/os/linux/mips.zig10
-rw-r--r--lib/std/os/linux/mips64.zig10
-rw-r--r--lib/std/os/linux/powerpc.zig5
-rw-r--r--lib/std/os/linux/powerpc64.zig5
-rw-r--r--lib/std/os/linux/riscv64.zig5
-rw-r--r--lib/std/os/linux/thumb.zig8
-rw-r--r--lib/std/os/linux/tls.zig20
-rw-r--r--lib/std/os/linux/x86.zig114
-rw-r--r--lib/std/os/linux/x86_64.zig134
11 files changed, 196 insertions, 166 deletions
diff --git a/lib/std/os/linux/arm-eabi.zig b/lib/std/os/linux/arm-eabi.zig
index 057ecc763a..f4870dccbb 100644
--- a/lib/std/os/linux/arm-eabi.zig
+++ b/lib/std/os/linux/arm-eabi.zig
@@ -103,20 +103,40 @@ const CloneFn = *const fn (arg: usize) callconv(.C) u8;
/// This matches the libc clone function.
pub extern fn clone(func: CloneFn, stack: usize, flags: u32, arg: usize, ptid: *i32, tls: usize, ctid: *i32) usize;
-pub fn restore() callconv(.Naked) void {
- return asm volatile ("svc #0"
- :
- : [number] "{r7}" (@intFromEnum(SYS.sigreturn)),
- : "memory"
- );
+pub fn restore() callconv(.Naked) noreturn {
+ switch (@import("builtin").zig_backend) {
+ .stage2_c => asm volatile (
+ \\ mov r7, %[number]
+ \\ svc #0
+ :
+ : [number] "I" (@intFromEnum(SYS.sigreturn)),
+ : "memory"
+ ),
+ else => asm volatile (
+ \\ svc #0
+ :
+ : [number] "{r7}" (@intFromEnum(SYS.sigreturn)),
+ : "memory"
+ ),
+ }
}
-pub fn restore_rt() callconv(.Naked) void {
- return asm volatile ("svc #0"
- :
- : [number] "{r7}" (@intFromEnum(SYS.rt_sigreturn)),
- : "memory"
- );
+pub fn restore_rt() callconv(.Naked) noreturn {
+ switch (@import("builtin").zig_backend) {
+ .stage2_c => asm volatile (
+ \\ mov r7, %[number]
+ \\ svc #0
+ :
+ : [number] "I" (@intFromEnum(SYS.rt_sigreturn)),
+ : "memory"
+ ),
+ else => asm volatile (
+ \\ svc #0
+ :
+ : [number] "{r7}" (@intFromEnum(SYS.rt_sigreturn)),
+ : "memory"
+ ),
+ }
}
pub const MMAP2_UNIT = 4096;
diff --git a/lib/std/os/linux/arm64.zig b/lib/std/os/linux/arm64.zig
index 0824a9e9a4..b87e774306 100644
--- a/lib/std/os/linux/arm64.zig
+++ b/lib/std/os/linux/arm64.zig
@@ -105,16 +105,17 @@ pub extern fn clone(func: CloneFn, stack: usize, flags: u32, arg: usize, ptid: *
pub const restore = restore_rt;
-pub fn restore_rt() callconv(.Naked) void {
+pub fn restore_rt() callconv(.Naked) noreturn {
switch (@import("builtin").zig_backend) {
- .stage2_c => return asm volatile (
+ .stage2_c => asm volatile (
\\ mov x8, %[number]
\\ svc #0
:
: [number] "i" (@intFromEnum(SYS.rt_sigreturn)),
: "memory", "cc"
),
- else => return asm volatile ("svc #0"
+ else => asm volatile (
+ \\ svc #0
:
: [number] "{x8}" (@intFromEnum(SYS.rt_sigreturn)),
: "memory", "cc"
diff --git a/lib/std/os/linux/mips.zig b/lib/std/os/linux/mips.zig
index 781003bedc..cfb2d73bfd 100644
--- a/lib/std/os/linux/mips.zig
+++ b/lib/std/os/linux/mips.zig
@@ -195,16 +195,18 @@ const CloneFn = *const fn (arg: usize) callconv(.C) u8;
/// This matches the libc clone function.
pub extern fn clone(func: CloneFn, stack: usize, flags: u32, arg: usize, ptid: *i32, tls: usize, ctid: *i32) usize;
-pub fn restore() callconv(.Naked) void {
- return asm volatile ("syscall"
+pub fn restore() callconv(.Naked) noreturn {
+ asm volatile (
+ \\ syscall
:
: [number] "{$2}" (@intFromEnum(SYS.sigreturn)),
: "$1", "$3", "$4", "$5", "$6", "$7", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", "$25", "hi", "lo", "memory"
);
}
-pub fn restore_rt() callconv(.Naked) void {
- return asm volatile ("syscall"
+pub fn restore_rt() callconv(.Naked) noreturn {
+ asm volatile (
+ \\ syscall
:
: [number] "{$2}" (@intFromEnum(SYS.rt_sigreturn)),
: "$1", "$3", "$4", "$5", "$6", "$7", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", "$25", "hi", "lo", "memory"
diff --git a/lib/std/os/linux/mips64.zig b/lib/std/os/linux/mips64.zig
index 8d55dee37f..d986110979 100644
--- a/lib/std/os/linux/mips64.zig
+++ b/lib/std/os/linux/mips64.zig
@@ -180,16 +180,18 @@ const CloneFn = *const fn (arg: usize) callconv(.C) u8;
/// This matches the libc clone function.
pub extern fn clone(func: CloneFn, stack: usize, flags: u32, arg: usize, ptid: *i32, tls: usize, ctid: *i32) usize;
-pub fn restore() callconv(.Naked) void {
- return asm volatile ("syscall"
+pub fn restore() callconv(.Naked) noreturn {
+ asm volatile (
+ \\ syscall
:
: [number] "{$2}" (@intFromEnum(SYS.rt_sigreturn)),
: "$1", "$3", "$4", "$5", "$6", "$7", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", "$25", "hi", "lo", "memory"
);
}
-pub fn restore_rt() callconv(.Naked) void {
- return asm volatile ("syscall"
+pub fn restore_rt() callconv(.Naked) noreturn {
+ asm volatile (
+ \\ syscall
:
: [number] "{$2}" (@intFromEnum(SYS.rt_sigreturn)),
: "$1", "$3", "$4", "$5", "$6", "$7", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", "$25", "hi", "lo", "memory"
diff --git a/lib/std/os/linux/powerpc.zig b/lib/std/os/linux/powerpc.zig
index 31c30f2d30..87feba3f0a 100644
--- a/lib/std/os/linux/powerpc.zig
+++ b/lib/std/os/linux/powerpc.zig
@@ -133,8 +133,9 @@ pub extern fn clone(func: CloneFn, stack: usize, flags: usize, arg: usize, ptid:
pub const restore = restore_rt;
-pub fn restore_rt() callconv(.Naked) void {
- return asm volatile ("sc"
+pub fn restore_rt() callconv(.Naked) noreturn {
+ asm volatile (
+ \\ sc
:
: [number] "{r0}" (@intFromEnum(SYS.rt_sigreturn)),
: "memory", "cr0", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12"
diff --git a/lib/std/os/linux/powerpc64.zig b/lib/std/os/linux/powerpc64.zig
index 722bd64687..dc142abc4f 100644
--- a/lib/std/os/linux/powerpc64.zig
+++ b/lib/std/os/linux/powerpc64.zig
@@ -133,8 +133,9 @@ pub extern fn clone(func: CloneFn, stack: usize, flags: usize, arg: usize, ptid:
pub const restore = restore_rt;
-pub fn restore_rt() callconv(.Naked) void {
- return asm volatile ("sc"
+pub fn restore_rt() callconv(.Naked) noreturn {
+ asm volatile (
+ \\ sc
:
: [number] "{r0}" (@intFromEnum(SYS.rt_sigreturn)),
: "memory", "cr0", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12"
diff --git a/lib/std/os/linux/riscv64.zig b/lib/std/os/linux/riscv64.zig
index cbdaa76282..473cab7b31 100644
--- a/lib/std/os/linux/riscv64.zig
+++ b/lib/std/os/linux/riscv64.zig
@@ -101,8 +101,9 @@ pub extern fn clone(func: CloneFn, stack: usize, flags: u32, arg: usize, ptid: *
pub const restore = restore_rt;
-pub fn restore_rt() callconv(.Naked) void {
- return asm volatile ("ecall"
+pub fn restore_rt() callconv(.Naked) noreturn {
+ asm volatile (
+ \\ ecall
:
: [number] "{x17}" (@intFromEnum(SYS.rt_sigreturn)),
: "memory"
diff --git a/lib/std/os/linux/thumb.zig b/lib/std/os/linux/thumb.zig
index 2241d79bde..7c7cfde50a 100644
--- a/lib/std/os/linux/thumb.zig
+++ b/lib/std/os/linux/thumb.zig
@@ -141,8 +141,8 @@ pub fn syscall6(
);
}
-pub fn restore() callconv(.Naked) void {
- return asm volatile (
+pub fn restore() callconv(.Naked) noreturn {
+ asm volatile (
\\ mov r7, %[number]
\\ svc #0
:
@@ -150,8 +150,8 @@ pub fn restore() callconv(.Naked) void {
);
}
-pub fn restore_rt() callconv(.Naked) void {
- return asm volatile (
+pub fn restore_rt() callconv(.Naked) noreturn {
+ asm volatile (
\\ mov r7, %[number]
\\ svc #0
:
diff --git a/lib/std/os/linux/tls.zig b/lib/std/os/linux/tls.zig
index 94fa0d1a09..dfd5200d45 100644
--- a/lib/std/os/linux/tls.zig
+++ b/lib/std/os/linux/tls.zig
@@ -48,7 +48,7 @@ const TLSVariant = enum {
};
const tls_variant = switch (native_arch) {
- .arm, .armeb, .thumb, .aarch64, .aarch64_be, .riscv32, .riscv64, .mips, .mipsel, .mips64, .mips64el, .powerpc, .powerpc64, .powerpc64le => TLSVariant.VariantI,
+ .arm, .armeb, .thumb, .aarch64, .aarch64_be, .riscv32, .riscv64, .mips, .mipsel, .mips64, .mips64el, .powerpc, .powerpcle, .powerpc64, .powerpc64le => TLSVariant.VariantI,
.x86_64, .x86, .sparc64 => TLSVariant.VariantII,
else => @compileError("undefined tls_variant for this architecture"),
};
@@ -115,12 +115,14 @@ pub fn setThreadPointer(addr: usize) void {
.entry_number = tls_image.gdt_entry_number,
.base_addr = addr,
.limit = 0xfffff,
- .seg_32bit = 1,
- .contents = 0, // Data
- .read_exec_only = 0,
- .limit_in_pages = 1,
- .seg_not_present = 0,
- .useable = 1,
+ .flags = .{
+ .seg_32bit = 1,
+ .contents = 0, // Data
+ .read_exec_only = 0,
+ .limit_in_pages = 1,
+ .seg_not_present = 0,
+ .useable = 1,
+ },
};
const rc = std.os.linux.syscall1(.set_thread_area, @intFromPtr(&user_desc));
assert(rc == 0);
@@ -138,7 +140,7 @@ pub fn setThreadPointer(addr: usize) void {
const rc = std.os.linux.syscall2(.arch_prctl, std.os.linux.ARCH.SET_FS, addr);
assert(rc == 0);
},
- .aarch64 => {
+ .aarch64, .aarch64_be => {
asm volatile (
\\ msr tpidr_el0, %[addr]
:
@@ -160,7 +162,7 @@ pub fn setThreadPointer(addr: usize) void {
const rc = std.os.linux.syscall1(.set_thread_area, addr);
assert(rc == 0);
},
- .powerpc => {
+ .powerpc, .powerpcle => {
asm volatile (
\\ mr 2, %[addr]
:
diff --git a/lib/std/os/linux/x86.zig b/lib/std/os/linux/x86.zig
index e5d75c1831..721fdecb82 100644
--- a/lib/std/os/linux/x86.zig
+++ b/lib/std/os/linux/x86.zig
@@ -123,46 +123,40 @@ const CloneFn = *const fn (arg: usize) callconv(.C) u8;
/// This matches the libc clone function.
pub extern fn clone(func: CloneFn, stack: usize, flags: u32, arg: usize, ptid: *i32, tls: usize, ctid: *i32) usize;
-pub fn restore() callconv(.Naked) void {
+pub fn restore() callconv(.Naked) noreturn {
switch (@import("builtin").zig_backend) {
.stage2_c => asm volatile (
\\ movl %[number], %%eax
\\ int $0x80
- \\ ret
:
: [number] "i" (@intFromEnum(SYS.sigreturn)),
: "memory"
),
else => asm volatile (
\\ int $0x80
- \\ ret
:
: [number] "{eax}" (@intFromEnum(SYS.sigreturn)),
: "memory"
),
}
- unreachable;
}
-pub fn restore_rt() callconv(.Naked) void {
+pub fn restore_rt() callconv(.Naked) noreturn {
switch (@import("builtin").zig_backend) {
.stage2_c => asm volatile (
\\ movl %[number], %%eax
\\ int $0x80
- \\ ret
:
: [number] "i" (@intFromEnum(SYS.rt_sigreturn)),
: "memory"
),
else => asm volatile (
\\ int $0x80
- \\ ret
:
: [number] "{eax}" (@intFromEnum(SYS.rt_sigreturn)),
: "memory"
),
}
- unreachable;
}
pub const O = struct {
@@ -354,16 +348,19 @@ pub const ucontext_t = extern struct {
pub const Elf_Symndx = u32;
-pub const user_desc = packed struct {
+pub const user_desc = extern struct {
entry_number: u32,
base_addr: u32,
limit: u32,
- seg_32bit: u1,
- contents: u2,
- read_exec_only: u1,
- limit_in_pages: u1,
- seg_not_present: u1,
- useable: u1,
+ flags: packed struct(u32) {
+ seg_32bit: u1,
+ contents: u2,
+ read_exec_only: u1,
+ limit_in_pages: u1,
+ seg_not_present: u1,
+ useable: u1,
+ _: u25 = undefined,
+ },
};
/// socketcall() call numbers
@@ -398,77 +395,80 @@ noinline fn getContextReturnAddress() usize {
return @returnAddress();
}
-pub fn getContextInternal() callconv(.Naked) void {
+pub fn getContextInternal() callconv(.Naked) usize {
asm volatile (
- \\ movl $0, (%[flags_offset])(%%edx)
- \\ movl $0, (%[link_offset])(%%edx)
- \\ movl %%edi, (%[edi_offset])(%%edx)
- \\ movl %%esi, (%[esi_offset])(%%edx)
- \\ movl %%ebp, (%[ebp_offset])(%%edx)
- \\ movl %%ebx, (%[ebx_offset])(%%edx)
- \\ movl %%edx, (%[edx_offset])(%%edx)
- \\ movl %%ecx, (%[ecx_offset])(%%edx)
- \\ movl %%eax, (%[eax_offset])(%%edx)
+ \\ movl $0, %[flags_offset:c](%%edx)
+ \\ movl $0, %[link_offset:c](%%edx)
+ \\ movl %%edi, %[edi_offset:c](%%edx)
+ \\ movl %%esi, %[esi_offset:c](%%edx)
+ \\ movl %%ebp, %[ebp_offset:c](%%edx)
+ \\ movl %%ebx, %[ebx_offset:c](%%edx)
+ \\ movl %%edx, %[edx_offset:c](%%edx)
+ \\ movl %%ecx, %[ecx_offset:c](%%edx)
+ \\ movl %%eax, %[eax_offset:c](%%edx)
\\ movl (%%esp), %%ecx
- \\ movl %%ecx, (%[eip_offset])(%%edx)
+ \\ movl %%ecx, %[eip_offset:c](%%edx)
\\ leal 4(%%esp), %%ecx
- \\ movl %%ecx, (%[esp_offset])(%%edx)
+ \\ movl %%ecx, %[esp_offset:c](%%edx)
\\ xorl %%ecx, %%ecx
\\ movw %%fs, %%cx
- \\ movl %%ecx, (%[fs_offset])(%%edx)
- \\ leal (%[regspace_offset])(%%edx), %%ecx
- \\ movl %%ecx, (%[fpregs_offset])(%%edx)
+ \\ movl %%ecx, %[fs_offset:c](%%edx)
+ \\ leal %[regspace_offset:c](%%edx), %%ecx
+ \\ movl %%ecx, %[fpregs_offset:c](%%edx)
\\ fnstenv (%%ecx)
\\ fldenv (%%ecx)
\\ pushl %%ebx
\\ pushl %%esi
\\ xorl %%ebx, %%ebx
\\ movl %[sigaltstack], %%eax
- \\ leal (%[stack_offset])(%%edx), %%ecx
+ \\ leal %[stack_offset:c](%%edx), %%ecx
\\ int $0x80
- \\ cmpl $0, %%eax
- \\ jne return
+ \\ testl %%eax, %%eax
+ \\ jnz 0f
\\ movl %[sigprocmask], %%eax
\\ xorl %%ecx, %%ecx
- \\ leal (%[sigmask_offset])(%%edx), %%edx
+ \\ leal %[sigmask_offset:c](%%edx), %%edx
\\ movl %[sigset_size], %%esi
\\ int $0x80
- \\ return:
+ \\0:
\\ popl %%esi
\\ popl %%ebx
+ \\ retl
:
- : [flags_offset] "p" (@offsetOf(ucontext_t, "flags")),
- [link_offset] "p" (@offsetOf(ucontext_t, "link")),
- [edi_offset] "p" (comptime gpRegisterOffset(REG.EDI)),
- [esi_offset] "p" (comptime gpRegisterOffset(REG.ESI)),
- [ebp_offset] "p" (comptime gpRegisterOffset(REG.EBP)),
- [esp_offset] "p" (comptime gpRegisterOffset(REG.ESP)),
- [ebx_offset] "p" (comptime gpRegisterOffset(REG.EBX)),
- [edx_offset] "p" (comptime gpRegisterOffset(REG.EDX)),
- [ecx_offset] "p" (comptime gpRegisterOffset(REG.ECX)),
- [eax_offset] "p" (comptime gpRegisterOffset(REG.EAX)),
- [eip_offset] "p" (comptime gpRegisterOffset(REG.EIP)),
- [fs_offset] "p" (comptime gpRegisterOffset(REG.FS)),
- [fpregs_offset] "p" (@offsetOf(ucontext_t, "mcontext") + @offsetOf(mcontext_t, "fpregs")),
- [regspace_offset] "p" (@offsetOf(ucontext_t, "regspace")),
+ : [flags_offset] "i" (@offsetOf(ucontext_t, "flags")),
+ [link_offset] "i" (@offsetOf(ucontext_t, "link")),
+ [edi_offset] "i" (comptime gpRegisterOffset(REG.EDI)),
+ [esi_offset] "i" (comptime gpRegisterOffset(REG.ESI)),
+ [ebp_offset] "i" (comptime gpRegisterOffset(REG.EBP)),
+ [esp_offset] "i" (comptime gpRegisterOffset(REG.ESP)),
+ [ebx_offset] "i" (comptime gpRegisterOffset(REG.EBX)),
+ [edx_offset] "i" (comptime gpRegisterOffset(REG.EDX)),
+ [ecx_offset] "i" (comptime gpRegisterOffset(REG.ECX)),
+ [eax_offset] "i" (comptime gpRegisterOffset(REG.EAX)),
+ [eip_offset] "i" (comptime gpRegisterOffset(REG.EIP)),
+ [fs_offset] "i" (comptime gpRegisterOffset(REG.FS)),
+ [fpregs_offset] "i" (@offsetOf(ucontext_t, "mcontext") + @offsetOf(mcontext_t, "fpregs")),
+ [regspace_offset] "i" (@offsetOf(ucontext_t, "regspace")),
[sigaltstack] "i" (@intFromEnum(linux.SYS.sigaltstack)),
- [stack_offset] "p" (@offsetOf(ucontext_t, "stack")),
+ [stack_offset] "i" (@offsetOf(ucontext_t, "stack")),
[sigprocmask] "i" (@intFromEnum(linux.SYS.rt_sigprocmask)),
- [sigmask_offset] "p" (@offsetOf(ucontext_t, "sigmask")),
+ [sigmask_offset] "i" (@offsetOf(ucontext_t, "sigmask")),
[sigset_size] "i" (linux.NSIG / 8),
- : "memory", "eax", "ecx", "edx"
+ : "cc", "memory", "eax", "ecx", "edx"
);
}
pub inline fn getcontext(context: *ucontext_t) usize {
// This method is used so that getContextInternal can control
// its prologue in order to read ESP from a constant offset.
- // The unused &getContextInternal input is required so the function is included in the binary.
+ // An aligned stack is not needed for getContextInternal.
+ var clobber_edx: usize = undefined;
return asm volatile (
- \\ call os.linux.x86.getContextInternal
- : [ret] "={eax}" (-> usize),
- : [context] "{edx}" (context),
+ \\ calll %[getContextInternal:P]
+ : [_] "={eax}" (-> usize),
+ [_] "={edx}" (clobber_edx),
+ : [_] "{edx}" (context),
[getContextInternal] "X" (&getContextInternal),
- : "memory", "ecx"
+ : "cc", "memory", "ecx"
);
}
diff --git a/lib/std/os/linux/x86_64.zig b/lib/std/os/linux/x86_64.zig
index e5febce14d..14f9aed51b 100644
--- a/lib/std/os/linux/x86_64.zig
+++ b/lib/std/os/linux/x86_64.zig
@@ -107,25 +107,22 @@ pub extern fn clone(func: CloneFn, stack: usize, flags: usize, arg: usize, ptid:
pub const restore = restore_rt;
-pub fn restore_rt() callconv(.Naked) void {
+pub fn restore_rt() callconv(.Naked) noreturn {
switch (@import("builtin").zig_backend) {
.stage2_c => asm volatile (
\\ movl %[number], %%eax
\\ syscall
- \\ retq
:
: [number] "i" (@intFromEnum(SYS.rt_sigreturn)),
: "rcx", "r11", "memory"
),
else => asm volatile (
\\ syscall
- \\ retq
:
: [number] "{rax}" (@intFromEnum(SYS.rt_sigreturn)),
: "rcx", "r11", "memory"
),
}
- unreachable;
}
pub const mode_t = usize;
@@ -400,92 +397,95 @@ fn gpRegisterOffset(comptime reg_index: comptime_int) usize {
return @offsetOf(ucontext_t, "mcontext") + @offsetOf(mcontext_t, "gregs") + @sizeOf(usize) * reg_index;
}
-fn getContextInternal() callconv(.Naked) void {
+fn getContextInternal() callconv(.Naked) usize {
// TODO: Read GS/FS registers?
asm volatile (
- \\ movq $0, (%[flags_offset])(%%rdi)
- \\ movq $0, (%[link_offset])(%%rdi)
- \\ movq %%r8, (%[r8_offset])(%%rdi)
- \\ movq %%r9, (%[r9_offset])(%%rdi)
- \\ movq %%r10, (%[r10_offset])(%%rdi)
- \\ movq %%r11, (%[r11_offset])(%%rdi)
- \\ movq %%r12, (%[r12_offset])(%%rdi)
- \\ movq %%r13, (%[r13_offset])(%%rdi)
- \\ movq %%r14, (%[r14_offset])(%%rdi)
- \\ movq %%r15, (%[r15_offset])(%%rdi)
- \\ movq %%rdi, (%[rdi_offset])(%%rdi)
- \\ movq %%rsi, (%[rsi_offset])(%%rdi)
- \\ movq %%rbp, (%[rbp_offset])(%%rdi)
- \\ movq %%rbx, (%[rbx_offset])(%%rdi)
- \\ movq %%rdx, (%[rdx_offset])(%%rdi)
- \\ movq %%rax, (%[rax_offset])(%%rdi)
- \\ movq %%rcx, (%[rcx_offset])(%%rdi)
+ \\ movq $0, %[flags_offset:c](%%rdi)
+ \\ movq $0, %[link_offset:c](%%rdi)
+ \\ movq %%r8, %[r8_offset:c](%%rdi)
+ \\ movq %%r9, %[r9_offset:c](%%rdi)
+ \\ movq %%r10, %[r10_offset:c](%%rdi)
+ \\ movq %%r11, %[r11_offset:c](%%rdi)
+ \\ movq %%r12, %[r12_offset:c](%%rdi)
+ \\ movq %%r13, %[r13_offset:c](%%rdi)
+ \\ movq %%r14, %[r14_offset:c](%%rdi)
+ \\ movq %%r15, %[r15_offset:c](%%rdi)
+ \\ movq %%rdi, %[rdi_offset:c](%%rdi)
+ \\ movq %%rsi, %[rsi_offset:c](%%rdi)
+ \\ movq %%rbp, %[rbp_offset:c](%%rdi)
+ \\ movq %%rbx, %[rbx_offset:c](%%rdi)
+ \\ movq %%rdx, %[rdx_offset:c](%%rdi)
+ \\ movq %%rax, %[rax_offset:c](%%rdi)
+ \\ movq %%rcx, %[rcx_offset:c](%%rdi)
\\ movq (%%rsp), %%rcx
- \\ movq %%rcx, (%[rip_offset])(%%rdi)
+ \\ movq %%rcx, %[rip_offset:c](%%rdi)
\\ leaq 8(%%rsp), %%rcx
- \\ movq %%rcx, (%[rsp_offset])(%%rdi)
+ \\ movq %%rcx, %[rsp_offset:c](%%rdi)
\\ pushfq
- \\ popq (%[efl_offset])(%%rdi)
- \\ leaq (%[fpmem_offset])(%%rdi), %%rcx
- \\ movq %%rcx, (%[fpstate_offset])(%%rdi)
+ \\ popq %[efl_offset:c](%%rdi)
+ \\ leaq %[fpmem_offset:c](%%rdi), %%rcx
+ \\ movq %%rcx, %[fpstate_offset:c](%%rdi)
\\ fnstenv (%%rcx)
\\ fldenv (%%rcx)
- \\ stmxcsr (%[mxcsr_offset])(%%rdi)
- \\ leaq (%[stack_offset])(%%rdi), %%rsi
+ \\ stmxcsr %[mxcsr_offset:c](%%rdi)
+ \\ leaq %[stack_offset:c](%%rdi), %%rsi
\\ movq %%rdi, %%r8
- \\ xorq %%rdi, %%rdi
+ \\ xorl %%edi, %%edi
\\ movq %[sigaltstack], %%rax
\\ syscall
- \\ cmpq $0, %%rax
- \\ jne return
+ \\ testq %%rax, %%rax
+ \\ jnz 0f
\\ movq %[sigprocmask], %%rax
- \\ xorq %%rsi, %%rsi
- \\ leaq (%[sigmask_offset])(%%r8), %%rdx
- \\ movq %[sigset_size], %%r10
+ \\ xorl %%esi, %%esi
+ \\ leaq %[sigmask_offset:c](%%r8), %%rdx
+ \\ movl %[sigset_size], %%r10d
\\ syscall
- \\ return:
+ \\0:
+ \\ retq
:
- : [flags_offset] "p" (@offsetOf(ucontext_t, "flags")),
- [link_offset] "p" (@offsetOf(ucontext_t, "link")),
- [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")),
+ : [flags_offset] "i" (@offsetOf(ucontext_t, "flags")),
+ [link_offset] "i" (@offsetOf(ucontext_t, "link")),
+ [r8_offset] "i" (comptime gpRegisterOffset(REG.R8)),
+ [r9_offset] "i" (comptime gpRegisterOffset(REG.R9)),
+ [r10_offset] "i" (comptime gpRegisterOffset(REG.R10)),
+ [r11_offset] "i" (comptime gpRegisterOffset(REG.R11)),
+ [r12_offset] "i" (comptime gpRegisterOffset(REG.R12)),
+ [r13_offset] "i" (comptime gpRegisterOffset(REG.R13)),
+ [r14_offset] "i" (comptime gpRegisterOffset(REG.R14)),
+ [r15_offset] "i" (comptime gpRegisterOffset(REG.R15)),
+ [rdi_offset] "i" (comptime gpRegisterOffset(REG.RDI)),
+ [rsi_offset] "i" (comptime gpRegisterOffset(REG.RSI)),
+ [rbp_offset] "i" (comptime gpRegisterOffset(REG.RBP)),
+ [rbx_offset] "i" (comptime gpRegisterOffset(REG.RBX)),
+ [rdx_offset] "i" (comptime gpRegisterOffset(REG.RDX)),
+ [rax_offset] "i" (comptime gpRegisterOffset(REG.RAX)),
+ [rcx_offset] "i" (comptime gpRegisterOffset(REG.RCX)),
+ [rsp_offset] "i" (comptime gpRegisterOffset(REG.RSP)),
+ [rip_offset] "i" (comptime gpRegisterOffset(REG.RIP)),
+ [efl_offset] "i" (comptime gpRegisterOffset(REG.EFL)),
+ [fpstate_offset] "i" (@offsetOf(ucontext_t, "mcontext") + @offsetOf(mcontext_t, "fpregs")),
+ [fpmem_offset] "i" (@offsetOf(ucontext_t, "fpregs_mem")),
+ [mxcsr_offset] "i" (@offsetOf(ucontext_t, "fpregs_mem") + @offsetOf(fpstate, "mxcsr")),
[sigaltstack] "i" (@intFromEnum(linux.SYS.sigaltstack)),
- [stack_offset] "p" (@offsetOf(ucontext_t, "stack")),
+ [stack_offset] "i" (@offsetOf(ucontext_t, "stack")),
[sigprocmask] "i" (@intFromEnum(linux.SYS.rt_sigprocmask)),
- [sigmask_offset] "p" (@offsetOf(ucontext_t, "sigmask")),
+ [sigmask_offset] "i" (@offsetOf(ucontext_t, "sigmask")),
[sigset_size] "i" (linux.NSIG / 8),
- : "memory", "rcx", "rdx", "rdi", "rsi", "r8", "r10", "r11"
+ : "cc", "memory", "rax", "rcx", "rdx", "rdi", "rsi", "r8", "r10", "r11"
);
}
pub inline fn getcontext(context: *ucontext_t) usize {
// This method is used so that getContextInternal can control
// its prologue in order to read RSP from a constant offset
- // The unused &getContextInternal input is required so the function is included in the binary.
+ // An aligned stack is not needed for getContextInternal.
+ var clobber_rdi: usize = undefined;
return asm volatile (
- \\ call os.linux.x86_64.getContextInternal
- : [ret] "={rax}" (-> usize),
- : [context] "{rdi}" (context),
+ \\ callq %[getContextInternal:P]
+ : [_] "={rax}" (-> usize),
+ [_] "={rdi}" (clobber_rdi),
+ : [_] "{rdi}" (context),
[getContextInternal] "X" (&getContextInternal),
- : "memory", "rcx", "rdx", "rdi", "rsi", "r8", "r10", "r11"
+ : "cc", "memory", "rcx", "rdx", "rsi", "r8", "r10", "r11"
);
}