support rt_sigreturn
This commit is contained in:
13
src/main.zig
13
src/main.zig
@@ -376,6 +376,19 @@ test "nolibc_pie_fork" {
|
||||
// );
|
||||
// }
|
||||
|
||||
test "nolibc_nopie_signal_handler" {
|
||||
try testHelper(
|
||||
&.{ flicker_path, getTestExePath("nolibc_nopie_signal_handler") },
|
||||
"In signal handler\nSignal handled successfully\n",
|
||||
);
|
||||
}
|
||||
test "nolibc_pie_signal_handler" {
|
||||
try testHelper(
|
||||
&.{ flicker_path, getTestExePath("nolibc_pie_signal_handler") },
|
||||
"In signal handler\nSignal handled successfully\n",
|
||||
);
|
||||
}
|
||||
|
||||
fn testPrintArgs(comptime name: []const u8) !void {
|
||||
const exe_path = getTestExePath(name);
|
||||
const loader_argv: []const []const u8 = &.{ flicker_path, exe_path, "foo", "bar", "baz hi" };
|
||||
|
||||
@@ -64,7 +64,23 @@ export fn syscall_handler(ctx: *SavedContext) callconv(.c) void {
|
||||
return;
|
||||
},
|
||||
.rt_sigreturn => {
|
||||
@panic("sigreturn is not supported yet");
|
||||
// The kernel expects the stack pointer to point to the `ucontext` structure. But in our
|
||||
// case `syscallEntry` pushed the `SavedContext` onto the stack.
|
||||
// So we just need to reset the stack pointer to what it was before `syscallEntry` was
|
||||
// called. The `SavedContext` includes the return address pushed by the trampoline, so
|
||||
// the original stack pointer is exactly at the end of `SavedContext`.
|
||||
const rsp_orig = @intFromPtr(ctx) + @sizeOf(SavedContext);
|
||||
|
||||
asm volatile (
|
||||
\\ mov %[rsp], %%rsp
|
||||
\\ syscall
|
||||
\\ ud2
|
||||
:
|
||||
: [rsp] "r" (rsp_orig),
|
||||
[number] "{rax}" (ctx.rax),
|
||||
: .{ .memory = true }
|
||||
);
|
||||
unreachable;
|
||||
},
|
||||
.execve, .execveat => |s| {
|
||||
// TODO: option to persist across new processes
|
||||
|
||||
35
src/test/signal_handler.zig
Normal file
35
src/test/signal_handler.zig
Normal file
@@ -0,0 +1,35 @@
|
||||
const std = @import("std");
|
||||
const linux = std.os.linux;
|
||||
|
||||
var handled = false;
|
||||
|
||||
fn handler(sig: i32, _: *const linux.siginfo_t, _: ?*anyopaque) callconv(.c) void {
|
||||
if (sig == linux.SIG.USR1) {
|
||||
handled = true;
|
||||
const msg = "In signal handler\n";
|
||||
_ = linux.syscall3(.write, 1, @intFromPtr(msg.ptr), msg.len);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn main() !void {
|
||||
const act = linux.Sigaction{
|
||||
.handler = .{ .sigaction = handler },
|
||||
.mask = std.mem.zeroes(linux.sigset_t),
|
||||
.flags = linux.SA.SIGINFO | linux.SA.RESTART,
|
||||
};
|
||||
|
||||
if (linux.sigaction(linux.SIG.USR1, &act, null) != 0) {
|
||||
return error.SigactionFailed;
|
||||
}
|
||||
|
||||
_ = linux.kill(linux.getpid(), linux.SIG.USR1);
|
||||
|
||||
if (handled) {
|
||||
const msg = "Signal handled successfully\n";
|
||||
_ = linux.syscall3(.write, 1, @intFromPtr(msg.ptr), msg.len);
|
||||
} else {
|
||||
const msg = "Signal NOT handled\n";
|
||||
_ = linux.syscall3(.write, 1, @intFromPtr(msg.ptr), msg.len);
|
||||
std.process.exit(1);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user