authorgravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2025-10-14 09:44:42+02:00
committergravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2025-10-15 13:59:17+02:00
logb2732645b7ffc08d9227bd5d82e1de1a6fbedb8e
tree3c764575097c6cf2f4905502f9cea48a5a3adfed
parentb8dd40fde8aed212ffa8a98b45821ccdf0c2e17d
signaturebadge-check Signed by SSH key SHA256:7B/LJ7bpR1eX8aCXSr4mtd5M45VMPKcx9zY8e95b5QM

std.debug.cpu_context: add sparc*-linux context conversion support

It's not really a ucontext_t at all. Lovely stuff.

1 files changed, 56 insertions(+), 13 deletions(-)

lib/std/debug/cpu_context.zig+56-13
...@@ -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 }
4464
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.h1393 // 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.h1421 // 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.h1573 // 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.h1682 // 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.h1684 // 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 {