diff --git a/src/header/signal/linux.rs b/src/header/signal/linux.rs
index 217c1ff076125674945425168f63fbe642da5d03..f30d0c3506731e91783cb187668876875e000456 100644
--- a/src/header/signal/linux.rs
+++ b/src/header/signal/linux.rs
@@ -1,3 +1,5 @@
+use super::{siginfo_t, sigset_t, stack_t};
+use crate::platform::types::*;
 use core::arch::global_asm;
 
 // Needs to be defined in assembly because it can't have a function prologue
@@ -79,3 +81,50 @@ pub const SIGSTKSZ: usize = 8096;
 
 pub const SI_QUEUE: i32 = -1;
 pub const SI_USER: i32 = 0;
+
+// Mirrors the ucontext_t struct from the libc crate on Linux.
+
+pub(crate) type ucontext_t = ucontext;
+pub(crate) type mcontext_t = mcontext;
+
+#[repr(C)]
+pub struct ucontext {
+    pub uc_flags: c_ulong,
+    pub uc_link: *mut ucontext_t,
+    pub uc_stack: stack_t,
+    pub uc_mcontext: mcontext_t,
+    pub uc_sigmask: sigset_t,
+    __private: [u8; 512],
+}
+
+#[repr(C)]
+pub struct _libc_fpstate {
+    pub cwd: u16,
+    pub swd: u16,
+    pub ftw: u16,
+    pub fop: u16,
+    pub rip: u64,
+    pub rdp: u64,
+    pub mxcsr: u32,
+    pub mxcr_mask: u32,
+    pub _st: [_libc_fpxreg; 8],
+    pub _xmm: [_libc_xmmreg; 16],
+    __private: [u64; 12],
+}
+#[repr(C)]
+pub struct _libc_fpxreg {
+    pub significand: [u16; 4],
+    pub exponent: u16,
+    __private: [u16; 3],
+}
+
+#[repr(C)]
+pub struct _libc_xmmreg {
+    pub element: [u32; 4],
+}
+#[repr(C)]
+pub struct mcontext {
+    pub gregs: [i64; 23], // TODO: greg_t?
+    pub fpregs: *mut _libc_fpstate,
+    __private: [u64; 8],
+}
diff --git a/src/platform/linux/signal.rs b/src/platform/linux/signal.rs
index 27e4dcf6309f50267fcf2a20c03679464f1bef52..139af7eff5f1b2d0a0de18d024028e13287d0a07 100644
--- a/src/platform/linux/signal.rs
+++ b/src/platform/linux/signal.rs
@@ -14,48 +14,6 @@ use crate::{
     },
 };
 
-// Mirrors the ucontext_t struct from the libc crate on Linux.
-#[repr(C)]
-pub struct ucontext_t {
-    pub uc_flags: c_ulong,
-    pub uc_link: *mut ucontext_t,
-    pub uc_stack: stack_t,
-    pub uc_mcontext: mcontext_t,
-    pub uc_sigmask: sigset_t,
-    __private: [u8; 512],
-}
-#[repr(C)]
-pub struct _libc_fpstate {
-    pub cwd: u16,
-    pub swd: u16,
-    pub ftw: u16,
-    pub fop: u16,
-    pub rip: u64,
-    pub rdp: u64,
-    pub mxcsr: u32,
-    pub mxcr_mask: u32,
-    pub _st: [_libc_fpxreg; 8],
-    pub _xmm: [_libc_xmmreg; 16],
-    __private: [u64; 12],
-}
-#[repr(C)]
-pub struct _libc_fpxreg {
-    pub significand: [u16; 4],
-    pub exponent: u16,
-    __private: [u16; 3],
-}
-
-#[repr(C)]
-pub struct _libc_xmmreg {
-    pub element: [u32; 4],
-}
-#[repr(C)]
-pub struct mcontext_t {
-    pub gregs: [i64; 23], // TODO: greg_t?
-    pub fpregs: *mut _libc_fpstate,
-    __private: [u64; 8],
-}
-
 impl PalSignal for Sys {
     unsafe fn getitimer(which: c_int, out: *mut itimerval) -> Result<()> {
         e_raw(syscall!(GETITIMER, which, out))?;
diff --git a/tests/Makefile b/tests/Makefile
index 73bb54dc20cd46b48e48957e34f274b166875a8a..8b50abbfe170481288ba95be9fdcab0363cb54f2 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -30,6 +30,7 @@ EXPECT_NAMES=\
 	select \
 	setjmp \
 	sigaction \
+	sigaltstack \
 	signal \
 	stdio/all \
 	stdio/buffer \
diff --git a/tests/expected/bins_static/sigaltstack.stderr b/tests/expected/bins_static/sigaltstack.stderr
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/tests/expected/bins_static/sigaltstack.stdout b/tests/expected/bins_static/sigaltstack.stdout
new file mode 100644
index 0000000000000000000000000000000000000000..be1dfac3422c46ec43f125e72a0476b274656264
--- /dev/null
+++ b/tests/expected/bins_static/sigaltstack.stdout
@@ -0,0 +1,101 @@
+SIGUSR2 handler00
+SIGUSR2 handler01
+SIGUSR2 handler02
+SIGUSR2 handler03
+SIGUSR2 handler04
+SIGUSR2 handler05
+SIGUSR2 handler06
+SIGUSR2 handler07
+SIGUSR2 handler08
+SIGUSR2 handler09
+SIGUSR2 handler10
+SIGUSR2 handler11
+SIGUSR2 handler12
+SIGUSR2 handler13
+SIGUSR2 handler14
+SIGUSR2 handler15
+SIGUSR2 handler16
+SIGUSR2 handler17
+SIGUSR2 handler18
+SIGUSR2 handler19
+SIGUSR2 handler20
+SIGUSR2 handler21
+SIGUSR2 handler22
+SIGUSR2 handler23
+SIGUSR2 handler24
+SIGUSR2 handler25
+SIGUSR2 handler26
+SIGUSR2 handler27
+SIGUSR2 handler28
+SIGUSR2 handler29
+SIGUSR2 handler30
+SIGUSR2 handler31
+SIGUSR2 handler32
+SIGUSR2 handler33
+SIGUSR2 handler34
+SIGUSR2 handler35
+SIGUSR2 handler36
+SIGUSR2 handler37
+SIGUSR2 handler38
+SIGUSR2 handler39
+SIGUSR2 handler40
+SIGUSR2 handler41
+SIGUSR2 handler42
+SIGUSR2 handler43
+SIGUSR2 handler44
+SIGUSR2 handler45
+SIGUSR2 handler46
+SIGUSR2 handler47
+SIGUSR2 handler48
+SIGUSR2 handler49
+SIGUSR2 handler50
+SIGUSR2 handler51
+SIGUSR2 handler52
+SIGUSR2 handler53
+SIGUSR2 handler54
+SIGUSR2 handler55
+SIGUSR2 handler56
+SIGUSR2 handler57
+SIGUSR2 handler58
+SIGUSR2 handler59
+SIGUSR2 handler60
+SIGUSR2 handler61
+SIGUSR2 handler62
+SIGUSR2 handler63
+SIGUSR2 handler64
+SIGUSR2 handler65
+SIGUSR2 handler66
+SIGUSR2 handler67
+SIGUSR2 handler68
+SIGUSR2 handler69
+SIGUSR2 handler70
+SIGUSR2 handler71
+SIGUSR2 handler72
+SIGUSR2 handler73
+SIGUSR2 handler74
+SIGUSR2 handler75
+SIGUSR2 handler76
+SIGUSR2 handler77
+SIGUSR2 handler78
+SIGUSR2 handler79
+SIGUSR2 handler80
+SIGUSR2 handler81
+SIGUSR2 handler82
+SIGUSR2 handler83
+SIGUSR2 handler84
+SIGUSR2 handler85
+SIGUSR2 handler86
+SIGUSR2 handler87
+SIGUSR2 handler88
+SIGUSR2 handler89
+SIGUSR2 handler90
+SIGUSR2 handler91
+SIGUSR2 handler92
+SIGUSR2 handler93
+SIGUSR2 handler94
+SIGUSR2 handler95
+SIGUSR2 handler96
+SIGUSR2 handler97
+SIGUSR2 handler98
+SIGUSR2 handler99
+SIGUSR2 handler00
diff --git a/tests/sigaltstack.c b/tests/sigaltstack.c
new file mode 100644
index 0000000000000000000000000000000000000000..22f575c9913da07654c7c9f1219f6b326a6aa37c
--- /dev/null
+++ b/tests/sigaltstack.c
@@ -0,0 +1,83 @@
+#include <assert.h>
+#include <signal.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/mman.h>
+
+#include "test_helpers.h"
+
+size_t stack_size;
+void *stack_base;
+
+volatile sig_atomic_t counter = 0;
+
+void action(int sig, siginfo_t *info, void *context_raw) {
+    assert(sig == SIGUSR2);
+
+    ucontext_t *context = context_raw;
+    assert(context->uc_stack.ss_sp == stack_base);
+    assert(context->uc_stack.ss_size == stack_size);
+
+    // TODO: Technically an implementation detail, but safe to check here.
+    assert((size_t)info >= (size_t)stack_base);
+    assert((size_t)info <= ((size_t)stack_base + stack_size));
+
+    int c = counter++;
+
+    char str[] = "SIGUSR2 handlerXX\n";
+    size_t len = strlen(str);
+    str[len - 2] = '0' + (c % 10);
+    str[len - 3] = '0' + ((c / 10) % 10);
+    write(STDOUT_FILENO, str, len);
+
+    if (c < 100) {
+        raise(SIGUSR2);
+    }
+}
+
+int main(void) {
+    int status;
+
+    stack_size = 1024 * 1024; // TODO?
+    assert(stack_size >= MINSIGSTKSZ * 100);
+    stack_base = mmap(NULL, stack_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+    ERROR_IF(mmap, stack_base, == MAP_FAILED);
+
+    stack_t old_stack;
+    stack_t stack = (stack_t) { .ss_sp = stack_base, .ss_size = stack_size, .ss_flags = 0 };
+
+    status = sigaltstack(&stack, &old_stack);
+    ERROR_IF(sigaltstack, status, == -1);
+
+    assert((old_stack.ss_flags & SS_ONSTACK) == 0);
+
+    stack_t same;
+
+    status = sigaltstack(&old_stack, &same);
+    ERROR_IF(sigaltstack, status, == -1);
+    assert(same.ss_sp == stack.ss_sp);
+    assert(same.ss_size == stack.ss_size);
+    assert((same.ss_flags & SS_ONSTACK) == 0);
+
+    status = sigaltstack(&stack, NULL);
+    ERROR_IF(sigaltstack, status, == -1);
+
+    status = sigaltstack(NULL, &same);
+    ERROR_IF(sigaltstack, status, == -1);
+    assert(same.ss_sp == stack.ss_sp);
+    assert(same.ss_size == stack.ss_size);
+    assert((same.ss_flags & SS_ONSTACK) == 0);
+
+    struct sigaction sa;
+    sigemptyset(&sa.sa_mask);
+    sa.sa_flags = SA_ONSTACK | SA_SIGINFO | SA_NODEFER;
+    sa.sa_sigaction = action;
+
+    status = sigaction(SIGUSR2, &sa, NULL);
+    ERROR_IF(sigaction, status, == -1);
+
+    raise(SIGUSR2);
+
+    return 0;
+}