Skip to content
Snippets Groups Projects
Commit d794dc77 authored by Jeremy Soller's avatar Jeremy Soller
Browse files

Merge branch 'test' into 'master'

Add sigaltstack test

See merge request !518
parents f5c0b8b0 07af4e49
No related branches found
No related tags found
1 merge request!518Add sigaltstack test
Pipeline #16379 passed
use super::{siginfo_t, sigset_t, stack_t};
use crate::platform::types::*;
use core::arch::global_asm; use core::arch::global_asm;
// Needs to be defined in assembly because it can't have a function prologue // Needs to be defined in assembly because it can't have a function prologue
...@@ -79,3 +81,50 @@ pub const SIGSTKSZ: usize = 8096; ...@@ -79,3 +81,50 @@ pub const SIGSTKSZ: usize = 8096;
pub const SI_QUEUE: i32 = -1; pub const SI_QUEUE: i32 = -1;
pub const SI_USER: i32 = 0; 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],
}
...@@ -14,48 +14,6 @@ use crate::{ ...@@ -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 { impl PalSignal for Sys {
unsafe fn getitimer(which: c_int, out: *mut itimerval) -> Result<()> { unsafe fn getitimer(which: c_int, out: *mut itimerval) -> Result<()> {
e_raw(syscall!(GETITIMER, which, out))?; e_raw(syscall!(GETITIMER, which, out))?;
......
...@@ -30,6 +30,7 @@ EXPECT_NAMES=\ ...@@ -30,6 +30,7 @@ EXPECT_NAMES=\
select \ select \
setjmp \ setjmp \
sigaction \ sigaction \
sigaltstack \
signal \ signal \
stdio/all \ stdio/all \
stdio/buffer \ stdio/buffer \
......
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
#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;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment