| ... | @@ -40,6 +40,26 @@ pub fn fromPosixSignalContext(ctx_ptr: ?*const anyopaque) ?Native { | ... | @@ -40,6 +40,26 @@ pub fn fromPosixSignalContext(ctx_ptr: ?*const anyopaque) ?Native { |
| 40 | }, | 40 | }, |
| 41 | .pc = @truncate(uc.mcontext.pc), | 41 | .pc = @truncate(uc.mcontext.pc), |
| 42 | }; | 42 | }; |
| | 43 | } else if (native_arch.isSPARC() and native_os == .linux) { |
| | 44 | const SparcStackFrame = extern struct { |
| | 45 | l: [8]usize, |
| | 46 | i: [8]usize, |
| | 47 | _x: [8]usize, |
| | 48 | }; |
| | 49 | |
| | 50 | // When invoking a signal handler, the kernel builds an `rt_signal_frame` structure on the |
| | 51 | // stack and passes a pointer to its `info` field to the signal handler. This implies that |
| | 52 | // prior to said `info` field, we will find the `ss` field which, among other things, |
| | 53 | // contains the incoming and local registers of the interrupted code. |
| | 54 | const frame = @as(*const SparcStackFrame, @ptrFromInt(@as(usize, @intFromPtr(ctx_ptr)) - @sizeOf(SparcStackFrame))); |
| | 55 | |
| | 56 | return .{ |
| | 57 | .g = uc.mcontext.g, |
| | 58 | .o = uc.mcontext.o, |
| | 59 | .l = frame.l, |
| | 60 | .i = frame.i, |
| | 61 | .pc = uc.mcontext.pc, |
| | 62 | }; |
| 43 | } | 63 | } |
| 44 | | 64 | |
| 45 | // Only unified conversions from here. | 65 | // Only unified conversions from here. |
| ... | @@ -1370,9 +1390,32 @@ const signal_ucontext_t = switch (native_os) { | ... | @@ -1370,9 +1390,32 @@ const signal_ucontext_t = switch (native_os) { |
| 1370 | lr: u32, | 1390 | lr: u32, |
| 1371 | }, | 1391 | }, |
| 1372 | }, | 1392 | }, |
| 1373 | // https://github.com/torvalds/linux/blob/cd5a0afbdf8033dc83786315d63f8b325bdba2fd/arch/sparc/include/uapi/asm/uctx.h | 1393 | // https://github.com/torvalds/linux/blob/cd5a0afbdf8033dc83786315d63f8b325bdba2fd/arch/sparc/kernel/signal_32.c#L48-L49 |
| 1374 | .sparc => @compileError("sparc-linux ucontext_t missing"), | 1394 | .sparc => extern struct { |
| 1375 | .sparc64 => @compileError("sparc64-linux ucontext_t missing"), | 1395 | // Not actually a `ucontext_t` at all because, uh, reasons? |
| | 1396 | |
| | 1397 | _info: std.os.linux.siginfo_t, |
| | 1398 | mcontext: extern struct { |
| | 1399 | _psr: u32, |
| | 1400 | pc: u32, |
| | 1401 | _npc: u32, |
| | 1402 | _y: u32, |
| | 1403 | g: [8]u32, |
| | 1404 | o: [8]u32, |
| | 1405 | }, |
| | 1406 | }, |
| | 1407 | // https://github.com/torvalds/linux/blob/cd5a0afbdf8033dc83786315d63f8b325bdba2fd/arch/sparc/kernel/signal_64.c#L247-L248 |
| | 1408 | .sparc64 => extern struct { |
| | 1409 | // Ditto... |
| | 1410 | |
| | 1411 | _info: std.os.linux.siginfo_t, |
| | 1412 | mcontext: extern struct { |
| | 1413 | g: [8]u64, |
| | 1414 | o: [8]u64, |
| | 1415 | _tstate: u64, |
| | 1416 | pc: u64, |
| | 1417 | }, |
| | 1418 | }, |
| 1376 | else => unreachable, | 1419 | else => unreachable, |
| 1377 | }, | 1420 | }, |
| 1378 | // https://github.com/freebsd/freebsd-src/blob/55c28005f544282b984ae0e15dacd0c108d8ab12/sys/sys/_ucontext.h | 1421 | // https://github.com/freebsd/freebsd-src/blob/55c28005f544282b984ae0e15dacd0c108d8ab12/sys/sys/_ucontext.h |
| ... | @@ -1497,14 +1540,14 @@ const signal_ucontext_t = switch (native_os) { | ... | @@ -1497,14 +1540,14 @@ const signal_ucontext_t = switch (native_os) { |
| 1497 | }, | 1540 | }, |
| 1498 | }, | 1541 | }, |
| 1499 | // This needs to be audited by someone with access to the Solaris headers. | 1542 | // This needs to be audited by someone with access to the Solaris headers. |
| 1500 | .solaris => extern struct { | 1543 | .solaris => switch (native_arch) { |
| 1501 | _flags: u64, | 1544 | .sparc64 => @compileError("sparc64-solaris ucontext_t missing"), |
| 1502 | _link: ?*signal_ucontext_t, | 1545 | .x86_64 => extern struct { |
| 1503 | _sigmask: std.c.sigset_t, | 1546 | _flags: u64, |
| 1504 | _stack: std.c.stack_t, | 1547 | _link: ?*signal_ucontext_t, |
| 1505 | mcontext: switch (native_arch) { | 1548 | _sigmask: std.c.sigset_t, |
| 1506 | .sparc64 => @compileError("sparc64-solaris mcontext_t missing"), | 1549 | _stack: std.c.stack_t, |
| 1507 | .x86_64 => extern struct { | 1550 | mcontext: extern struct { |
| 1508 | r15: u64, | 1551 | r15: u64, |
| 1509 | r14: u64, | 1552 | r14: u64, |
| 1510 | r13: u64, | 1553 | r13: u64, |
| ... | @@ -1524,8 +1567,8 @@ const signal_ucontext_t = switch (native_os) { | ... | @@ -1524,8 +1567,8 @@ const signal_ucontext_t = switch (native_os) { |
| 1524 | _err: i64, | 1567 | _err: i64, |
| 1525 | rip: u64, | 1568 | rip: u64, |
| 1526 | }, | 1569 | }, |
| 1527 | else => unreachable, | | |
| 1528 | }, | 1570 | }, |
| | 1571 | else => unreachable, |
| 1529 | }, | 1572 | }, |
| 1530 | // https://github.com/illumos/illumos-gate/blob/d4ce137bba3bd16823db6374d9e9a643264ce245/usr/src/uts/intel/sys/ucontext.h | 1573 | // https://github.com/illumos/illumos-gate/blob/d4ce137bba3bd16823db6374d9e9a643264ce245/usr/src/uts/intel/sys/ucontext.h |
| 1531 | .illumos => extern struct { | 1574 | .illumos => extern struct { |
| ... | @@ -1637,7 +1680,7 @@ const signal_ucontext_t = switch (native_os) { | ... | @@ -1637,7 +1680,7 @@ const signal_ucontext_t = switch (native_os) { |
| 1637 | }, | 1680 | }, |
| 1638 | }, | 1681 | }, |
| 1639 | // https://github.com/openbsd/src/blob/42468faed8369d07ae49ae02dd71ec34f59b66cd/sys/arch/sparc64/include/signal.h | 1682 | // https://github.com/openbsd/src/blob/42468faed8369d07ae49ae02dd71ec34f59b66cd/sys/arch/sparc64/include/signal.h |
| 1640 | .sparc64 => @compileError("sparc64-openbsd mcontext_t missing"), | 1683 | .sparc64 => @compileError("sparc64-openbsd ucontext_t missing"), |
| 1641 | // https://github.com/openbsd/src/blob/42468faed8369d07ae49ae02dd71ec34f59b66cd/sys/arch/i386/include/signal.h | 1684 | // https://github.com/openbsd/src/blob/42468faed8369d07ae49ae02dd71ec34f59b66cd/sys/arch/i386/include/signal.h |
| 1642 | .x86 => extern struct { | 1685 | .x86 => extern struct { |
| 1643 | mcontext: extern struct { | 1686 | mcontext: extern struct { |