mirror of
https://github.com/ziglang/zig.git
synced 2026-02-13 12:59:04 +00:00
Correct signal bits for MIPS
Also enable the segfault handler for all the supported architectures beside MIPS.
This commit is contained in:
parent
bed4bfa69a
commit
17f2af10b5
@ -2336,7 +2336,7 @@ fn getDebugInfoAllocator() *mem.Allocator {
|
||||
}
|
||||
|
||||
/// Whether or not the current target can print useful debug information when a segfault occurs.
|
||||
pub const have_segfault_handling_support = (builtin.arch == builtin.Arch.x86_64 and builtin.os == .linux) or builtin.os == .windows;
|
||||
pub const have_segfault_handling_support = builtin.os == .linux or builtin.os == .windows;
|
||||
pub const enable_segfault_handler: bool = if (@hasDecl(root, "enable_segfault_handler"))
|
||||
root.enable_segfault_handler
|
||||
else
|
||||
@ -2390,12 +2390,31 @@ extern fn handleSegfaultLinux(sig: i32, info: *const os.siginfo_t, ctx_ptr: *con
|
||||
// and the resulting segfault will crash the process rather than continually dump stack traces.
|
||||
resetSegfaultHandler();
|
||||
|
||||
const ctx = @ptrCast(*const os.ucontext_t, @alignCast(@alignOf(os.ucontext_t), ctx_ptr));
|
||||
const ip = @intCast(usize, ctx.mcontext.gregs[os.REG_RIP]);
|
||||
const bp = @intCast(usize, ctx.mcontext.gregs[os.REG_RBP]);
|
||||
const addr = @ptrToInt(info.fields.sigfault.addr);
|
||||
std.debug.warn("Segmentation fault at address 0x{x}\n", addr);
|
||||
dumpStackTraceFromBase(bp, ip);
|
||||
|
||||
switch (builtin.arch) {
|
||||
.x86_64 => {
|
||||
const ctx = @ptrCast(*const os.ucontext_t, @alignCast(@alignOf(os.ucontext_t), ctx_ptr));
|
||||
const ip = @intCast(usize, ctx.mcontext.gregs[os.REG_RIP]);
|
||||
const bp = @intCast(usize, ctx.mcontext.gregs[os.REG_RBP]);
|
||||
dumpStackTraceFromBase(bp, ip);
|
||||
},
|
||||
.arm => {
|
||||
const ctx = @ptrCast(*const os.ucontext_t, @alignCast(@alignOf(os.ucontext_t), ctx_ptr));
|
||||
const ip = @intCast(usize, ctx.mcontext.arm_pc);
|
||||
const bp = @intCast(usize, ctx.mcontext.arm_fp);
|
||||
dumpStackTraceFromBase(bp, ip);
|
||||
},
|
||||
.aarch64 => {
|
||||
const ctx = @ptrCast(*const os.ucontext_t, @alignCast(@alignOf(os.ucontext_t), ctx_ptr));
|
||||
const ip = @intCast(usize, ctx.mcontext.pc);
|
||||
// x29 is the ABI-designated frame pointer
|
||||
const bp = @intCast(usize, ctx.mcontext.regs[29]);
|
||||
dumpStackTraceFromBase(bp, ip);
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
|
||||
// We cannot allow the signal handler to return because when it runs the original instruction
|
||||
// again, the memory may be mapped and undefined behavior would occur rather than repeating
|
||||
|
||||
@ -140,9 +140,27 @@ pub const WEXITED = 4;
|
||||
pub const WCONTINUED = 8;
|
||||
pub const WNOWAIT = 0x1000000;
|
||||
|
||||
pub const SA_NOCLDSTOP = 1;
|
||||
pub const SA_NOCLDWAIT = 2;
|
||||
pub const SA_SIGINFO = 4;
|
||||
pub usingnamespace if (is_mips)
|
||||
struct {
|
||||
pub const SA_NOCLDSTOP = 1;
|
||||
pub const SA_NOCLDWAIT = 0x10000;
|
||||
pub const SA_SIGINFO = 8;
|
||||
|
||||
pub const SIG_BLOCK = 1;
|
||||
pub const SIG_UNBLOCK = 2;
|
||||
pub const SIG_SETMASK = 3;
|
||||
}
|
||||
else
|
||||
struct {
|
||||
pub const SA_NOCLDSTOP = 1;
|
||||
pub const SA_NOCLDWAIT = 2;
|
||||
pub const SA_SIGINFO = 4;
|
||||
|
||||
pub const SIG_BLOCK = 0;
|
||||
pub const SIG_UNBLOCK = 1;
|
||||
pub const SIG_SETMASK = 2;
|
||||
};
|
||||
|
||||
pub const SA_ONSTACK = 0x08000000;
|
||||
pub const SA_RESTART = 0x10000000;
|
||||
pub const SA_NODEFER = 0x40000000;
|
||||
@ -209,10 +227,6 @@ pub const SEEK_SET = 0;
|
||||
pub const SEEK_CUR = 1;
|
||||
pub const SEEK_END = 2;
|
||||
|
||||
pub const SIG_BLOCK = 0;
|
||||
pub const SIG_UNBLOCK = 1;
|
||||
pub const SIG_SETMASK = 2;
|
||||
|
||||
pub const PROTO_ip = 0o000;
|
||||
pub const PROTO_icmp = 0o001;
|
||||
pub const PROTO_igmp = 0o002;
|
||||
@ -786,17 +800,34 @@ pub const winsize = extern struct {
|
||||
ws_ypixel: u16,
|
||||
};
|
||||
|
||||
pub const NSIG = 65;
|
||||
pub const NSIG = if (is_mips) 128 else 65;
|
||||
pub const sigset_t = [128 / @sizeOf(usize)]usize;
|
||||
pub const all_mask = [_]u32{ 0xffffffff, 0xffffffff };
|
||||
pub const app_mask = [_]u32{ 0xfffffffc, 0x7fffffff };
|
||||
|
||||
pub const k_sigaction = extern struct {
|
||||
sigaction: ?extern fn (i32, *siginfo_t, *c_void) void,
|
||||
flags: usize,
|
||||
restorer: extern fn () void,
|
||||
mask: [2]u32,
|
||||
};
|
||||
pub usingnamespace if (NSIG == 65)
|
||||
struct {
|
||||
pub const all_mask = [2]u32{ 0xffffffff, 0xffffffff };
|
||||
pub const app_mask = [2]u32{ 0xfffffffc, 0x7fffffff };
|
||||
}
|
||||
else
|
||||
struct {
|
||||
pub const all_mask = [4]u32{ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff };
|
||||
pub const app_mask = [4]u32{ 0xfffffffc, 0x7fffffff, 0xffffffff, 0xffffffff };
|
||||
};
|
||||
|
||||
pub const k_sigaction = if (is_mips)
|
||||
extern struct {
|
||||
flags: usize,
|
||||
sigaction: ?extern fn (i32, *siginfo_t, *c_void) void,
|
||||
mask: [4]u32,
|
||||
restorer: extern fn () void,
|
||||
}
|
||||
else
|
||||
extern struct {
|
||||
sigaction: ?extern fn (i32, *siginfo_t, *c_void) void,
|
||||
flags: usize,
|
||||
restorer: extern fn () void,
|
||||
mask: [2]u32,
|
||||
};
|
||||
|
||||
/// Renamed from `sigaction` to `Sigaction` to avoid conflict with the syscall.
|
||||
pub const Sigaction = extern struct {
|
||||
@ -1030,12 +1061,12 @@ pub fn CPU_COUNT(set: cpu_set_t) cpu_count_t {
|
||||
//#define CPU_EQUAL(s1,s2) CPU_EQUAL_S(sizeof(cpu_set_t),s1,s2)
|
||||
|
||||
pub const MINSIGSTKSZ = switch (builtin.arch) {
|
||||
.i386, .x86_64, .arm => 2048,
|
||||
.i386, .x86_64, .arm, .mipsel => 2048,
|
||||
.aarch64 => 5120,
|
||||
else => @compileError("MINSIGSTKSZ not defined for this architecture"),
|
||||
};
|
||||
pub const SIGSTKSZ = switch (builtin.arch) {
|
||||
.i386, .x86_64, .arm => 8192,
|
||||
.i386, .x86_64, .arm, .mipsel => 8192,
|
||||
.aarch64 => 16384,
|
||||
else => @compileError("SIGSTKSZ not defined for this architecture"),
|
||||
};
|
||||
@ -1050,6 +1081,70 @@ pub const stack_t = extern struct {
|
||||
ss_size: isize,
|
||||
};
|
||||
|
||||
pub const sigval = extern union {
|
||||
int: i32,
|
||||
ptr: *c_void,
|
||||
};
|
||||
|
||||
const siginfo_fields_union = extern union {
|
||||
pad: [128 - 2 * @sizeOf(c_int) - @sizeOf(c_long)]u8,
|
||||
common: extern struct {
|
||||
first: extern union {
|
||||
piduid: extern struct {
|
||||
pid: pid_t,
|
||||
uid: uid_t,
|
||||
},
|
||||
timer: extern struct {
|
||||
timerid: i32,
|
||||
overrun: i32,
|
||||
},
|
||||
},
|
||||
second: extern union {
|
||||
value: sigval,
|
||||
sigchld: extern struct {
|
||||
status: i32,
|
||||
utime: clock_t,
|
||||
stime: clock_t,
|
||||
},
|
||||
},
|
||||
},
|
||||
sigfault: extern struct {
|
||||
addr: *c_void,
|
||||
addr_lsb: i16,
|
||||
first: extern union {
|
||||
addr_bnd: extern struct {
|
||||
lower: *c_void,
|
||||
upper: *c_void,
|
||||
},
|
||||
pkey: u32,
|
||||
},
|
||||
},
|
||||
sigpoll: extern struct {
|
||||
band: isize,
|
||||
fd: i32,
|
||||
},
|
||||
sigsys: extern struct {
|
||||
call_addr: *c_void,
|
||||
syscall: i32,
|
||||
arch: u32,
|
||||
},
|
||||
};
|
||||
|
||||
pub const siginfo_t = if (is_mips)
|
||||
extern struct {
|
||||
signo: i32,
|
||||
code: i32,
|
||||
errno: i32,
|
||||
fields: siginfo_fields_union,
|
||||
}
|
||||
else
|
||||
extern struct {
|
||||
signo: i32,
|
||||
errno: i32,
|
||||
code: i32,
|
||||
fields: siginfo_fields_union,
|
||||
};
|
||||
|
||||
pub const io_uring_params = extern struct {
|
||||
sq_entries: u32,
|
||||
cq_entries: u32,
|
||||
|
||||
@ -1,10 +1,11 @@
|
||||
// arm-eabi-specific declarations that are intended to be imported into the POSIX namespace.
|
||||
|
||||
const std = @import("../../std.zig");
|
||||
const std = @import("../../../std.zig");
|
||||
const linux = std.os.linux;
|
||||
const socklen_t = linux.socklen_t;
|
||||
const iovec = linux.iovec;
|
||||
const iovec_const = linux.iovec_const;
|
||||
const stack_t = linux.stack_t;
|
||||
const sigset_t = linux.sigset_t;
|
||||
|
||||
pub const SYS_restart_syscall = 0;
|
||||
pub const SYS_exit = 1;
|
||||
@ -565,4 +566,37 @@ pub const timezone = extern struct {
|
||||
tz_dsttime: i32,
|
||||
};
|
||||
|
||||
pub const mcontext_t = extern struct {
|
||||
trap_no: usize,
|
||||
error_code: usize,
|
||||
oldmask: usize,
|
||||
arm_r0: usize,
|
||||
arm_r1: usize,
|
||||
arm_r2: usize,
|
||||
arm_r3: usize,
|
||||
arm_r4: usize,
|
||||
arm_r5: usize,
|
||||
arm_r6: usize,
|
||||
arm_r7: usize,
|
||||
arm_r8: usize,
|
||||
arm_r9: usize,
|
||||
arm_r10: usize,
|
||||
arm_fp: usize,
|
||||
arm_ip: usize,
|
||||
arm_sp: usize,
|
||||
arm_lr: usize,
|
||||
arm_pc: usize,
|
||||
arm_cpsr: usize,
|
||||
fault_address: usize,
|
||||
};
|
||||
|
||||
pub const ucontext_t = extern struct {
|
||||
flags: usize,
|
||||
link: *ucontext_t,
|
||||
stack: stack_t,
|
||||
mcontext: mcontext_t,
|
||||
sigmask: sigset_t,
|
||||
regspace: [64]u64,
|
||||
};
|
||||
|
||||
pub const Elf_Symndx = u32;
|
||||
|
||||
@ -8,6 +8,8 @@ const iovec = linux.iovec;
|
||||
const iovec_const = linux.iovec_const;
|
||||
const uid_t = linux.uid_t;
|
||||
const gid_t = linux.gid_t;
|
||||
const stack_t = linux.stack_t;
|
||||
const sigset_t = linux.sigset_t;
|
||||
|
||||
pub const SYS_io_setup = 0;
|
||||
pub const SYS_io_destroy = 1;
|
||||
@ -445,4 +447,23 @@ pub const timezone = extern struct {
|
||||
tz_dsttime: i32,
|
||||
};
|
||||
|
||||
pub const mcontext_t = extern struct {
|
||||
fault_address: usize,
|
||||
regs: [31]usize,
|
||||
sp: usize,
|
||||
pc: usize,
|
||||
pstate: usize,
|
||||
// Make sure the field is correctly aligned since this area
|
||||
// holds various FP/vector registers
|
||||
reserved1: [256 * 16]u8 align(16),
|
||||
};
|
||||
|
||||
pub const ucontext_t = extern struct {
|
||||
flags: usize,
|
||||
link: *ucontext_t,
|
||||
stack: stack_t,
|
||||
sigmask: sigset_t,
|
||||
mcontext: mcontext_t,
|
||||
};
|
||||
|
||||
pub const Elf_Symndx = u32;
|
||||
|
||||
@ -536,60 +536,6 @@ pub const timezone = extern struct {
|
||||
|
||||
pub const Elf_Symndx = u32;
|
||||
|
||||
pub const sigval = extern union {
|
||||
int: i32,
|
||||
ptr: *c_void,
|
||||
};
|
||||
|
||||
pub const siginfo_t = extern struct {
|
||||
signo: i32,
|
||||
errno: i32,
|
||||
code: i32,
|
||||
fields: extern union {
|
||||
pad: [128 - 2 * @sizeOf(c_int) - @sizeOf(c_long)]u8,
|
||||
common: extern struct {
|
||||
first: extern union {
|
||||
piduid: extern struct {
|
||||
pid: pid_t,
|
||||
uid: uid_t,
|
||||
},
|
||||
timer: extern struct {
|
||||
timerid: i32,
|
||||
overrun: i32,
|
||||
},
|
||||
},
|
||||
second: extern union {
|
||||
value: sigval,
|
||||
sigchld: extern struct {
|
||||
status: i32,
|
||||
utime: clock_t,
|
||||
stime: clock_t,
|
||||
},
|
||||
},
|
||||
},
|
||||
sigfault: extern struct {
|
||||
addr: *c_void,
|
||||
addr_lsb: i16,
|
||||
first: extern union {
|
||||
addr_bnd: extern struct {
|
||||
lower: *c_void,
|
||||
upper: *c_void,
|
||||
},
|
||||
pkey: u32,
|
||||
},
|
||||
},
|
||||
sigpoll: extern struct {
|
||||
band: isize,
|
||||
fd: i32,
|
||||
},
|
||||
sigsys: extern struct {
|
||||
call_addr: *c_void,
|
||||
syscall: i32,
|
||||
arch: u32,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
pub const greg_t = usize;
|
||||
pub const gregset_t = [23]greg_t;
|
||||
pub const fpstate = extern struct {
|
||||
|
||||
@ -673,15 +673,18 @@ pub fn sigaction(sig: u6, noalias act: *const Sigaction, noalias oact: ?*Sigacti
|
||||
assert(sig >= 1);
|
||||
assert(sig != SIGKILL);
|
||||
assert(sig != SIGSTOP);
|
||||
|
||||
const restorer_fn = if ((act.flags & SA_SIGINFO) != 0) restore_rt else restore;
|
||||
var ksa = k_sigaction{
|
||||
.sigaction = act.sigaction,
|
||||
.flags = act.flags | SA_RESTORER,
|
||||
.mask = undefined,
|
||||
.restorer = @ptrCast(extern fn () void, restore_rt),
|
||||
.restorer = @ptrCast(extern fn () void, restorer_fn),
|
||||
};
|
||||
var ksa_old: k_sigaction = undefined;
|
||||
@memcpy(@ptrCast([*]u8, &ksa.mask), @ptrCast([*]const u8, &act.mask), 8);
|
||||
const result = syscall4(SYS_rt_sigaction, sig, @ptrToInt(&ksa), @ptrToInt(&ksa_old), @sizeOf(@typeOf(ksa.mask)));
|
||||
const ksa_mask_size = @sizeOf(@typeOf(ksa_old.mask));
|
||||
@memcpy(@ptrCast([*]u8, &ksa.mask), @ptrCast([*]const u8, &act.mask), ksa_mask_size);
|
||||
const result = syscall4(SYS_rt_sigaction, sig, @ptrToInt(&ksa), @ptrToInt(&ksa_old), ksa_mask_size);
|
||||
const err = getErrno(result);
|
||||
if (err != 0) {
|
||||
return result;
|
||||
@ -689,7 +692,7 @@ pub fn sigaction(sig: u6, noalias act: *const Sigaction, noalias oact: ?*Sigacti
|
||||
if (oact) |old| {
|
||||
old.sigaction = ksa_old.sigaction;
|
||||
old.flags = @truncate(u32, ksa_old.flags);
|
||||
@memcpy(@ptrCast([*]u8, &old.mask), @ptrCast([*]const u8, &ksa_old.mask), @sizeOf(@typeOf(ksa_old.mask)));
|
||||
@memcpy(@ptrCast([*]u8, &old.mask), @ptrCast([*]const u8, &ksa_old.mask), ksa_mask_size);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
usingnamespace @import("../bits.zig");
|
||||
|
||||
pub fn syscall0(number: usize) usize {
|
||||
return asm volatile ("svc #0"
|
||||
: [ret] "={r0}" (-> usize)
|
||||
@ -94,3 +96,19 @@ pub extern fn getThreadPointer() usize {
|
||||
: [ret] "=r" (-> usize)
|
||||
);
|
||||
}
|
||||
|
||||
pub nakedcc fn restore() void {
|
||||
return asm volatile ("svc #0"
|
||||
:
|
||||
: [number] "{r7}" (usize(SYS_sigreturn))
|
||||
: "memory"
|
||||
);
|
||||
}
|
||||
|
||||
pub nakedcc fn restore_rt() void {
|
||||
return asm volatile ("svc #0"
|
||||
:
|
||||
: [number] "{r7}" (usize(SYS_rt_sigreturn))
|
||||
: "memory"
|
||||
);
|
||||
}
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
usingnamespace @import("../bits.zig");
|
||||
|
||||
pub fn syscall0(number: usize) usize {
|
||||
return asm volatile ("svc #0"
|
||||
: [ret] "={x0}" (-> usize)
|
||||
@ -85,3 +87,13 @@ pub fn syscall6(
|
||||
|
||||
/// This matches the libc clone function.
|
||||
pub extern fn clone(func: extern fn (arg: usize) u8, stack: usize, flags: u32, arg: usize, ptid: *i32, tls: usize, ctid: *i32) usize;
|
||||
|
||||
pub const restore = restore_rt;
|
||||
|
||||
pub nakedcc fn restore_rt() void {
|
||||
return asm volatile ("svc #0"
|
||||
:
|
||||
: [number] "{x8}" (usize(SYS_rt_sigreturn))
|
||||
: "memory", "cc"
|
||||
);
|
||||
}
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
usingnamespace @import("../bits.zig");
|
||||
|
||||
pub fn syscall0(number: usize) usize {
|
||||
return asm volatile (
|
||||
\\ syscall
|
||||
@ -122,3 +124,19 @@ pub fn syscall6(
|
||||
|
||||
/// This matches the libc clone function.
|
||||
pub extern fn clone(func: extern fn (arg: usize) u8, stack: usize, flags: u32, arg: usize, ptid: *i32, tls: usize, ctid: *i32) usize;
|
||||
|
||||
pub nakedcc fn restore() void {
|
||||
return asm volatile ("syscall"
|
||||
:
|
||||
: [number] "{$2}" (usize(SYS_sigreturn))
|
||||
: "memory", "cc", "$7"
|
||||
);
|
||||
}
|
||||
|
||||
pub nakedcc fn restore_rt() void {
|
||||
return asm volatile ("syscall"
|
||||
:
|
||||
: [number] "{$2}" (usize(SYS_rt_sigreturn))
|
||||
: "memory", "cc", "$7"
|
||||
);
|
||||
}
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
usingnamespace @import("../bits.zig");
|
||||
|
||||
pub fn syscall0(number: usize) usize {
|
||||
return asm volatile ("ecall"
|
||||
: [ret] "={x10}" (-> usize)
|
||||
@ -84,3 +86,13 @@ pub fn syscall6(
|
||||
}
|
||||
|
||||
pub extern fn clone(func: extern fn (arg: usize) u8, stack: usize, flags: u32, arg: usize, ptid: *i32, tls: usize, ctid: *i32) usize;
|
||||
|
||||
pub const restore = restore_rt;
|
||||
|
||||
pub nakedcc fn restore_rt() void {
|
||||
return asm volatile ("ecall"
|
||||
:
|
||||
: [number] "{x17}" (usize(SYS_rt_sigreturn))
|
||||
: "memory"
|
||||
);
|
||||
}
|
||||
|
||||
@ -88,10 +88,12 @@ pub fn syscall6(
|
||||
/// This matches the libc clone function.
|
||||
pub extern fn clone(func: extern fn (arg: usize) u8, stack: usize, flags: usize, arg: usize, ptid: *i32, tls: usize, ctid: *i32) usize;
|
||||
|
||||
pub const restore = restore_rt;
|
||||
|
||||
pub nakedcc fn restore_rt() void {
|
||||
return asm volatile ("syscall"
|
||||
:
|
||||
: [number] "{rax}" (usize(SYS_rt_sigreturn))
|
||||
: "rcx", "r11"
|
||||
: "rcx", "r11", "memory"
|
||||
);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user