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
signature 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 {
4040 },
4141 .pc = @truncate(uc.mcontext.pc),
4242 };
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 };
4363 }
4464
4565 // Only unified conversions from here.
......@@ -1370,9 +1390,32 @@ const signal_ucontext_t = switch (native_os) {
13701390 lr: u32,
13711391 },
13721392 },
1373 // https://github.com/torvalds/linux/blob/cd5a0afbdf8033dc83786315d63f8b325bdba2fd/arch/sparc/include/uapi/asm/uctx.h
1374 .sparc => @compileError("sparc-linux ucontext_t missing"),
1375 .sparc64 => @compileError("sparc64-linux ucontext_t missing"),
1393 // https://github.com/torvalds/linux/blob/cd5a0afbdf8033dc83786315d63f8b325bdba2fd/arch/sparc/kernel/signal_32.c#L48-L49
1394 .sparc => extern struct {
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 },
13761419 else => unreachable,
13771420 },
13781421 // https://github.com/freebsd/freebsd-src/blob/55c28005f544282b984ae0e15dacd0c108d8ab12/sys/sys/_ucontext.h
......@@ -1497,14 +1540,14 @@ const signal_ucontext_t = switch (native_os) {
14971540 },
14981541 },
14991542 // This needs to be audited by someone with access to the Solaris headers.
1500 .solaris => extern struct {
1501 _flags: u64,
1502 _link: ?*signal_ucontext_t,
1503 _sigmask: std.c.sigset_t,
1504 _stack: std.c.stack_t,
1505 mcontext: switch (native_arch) {
1506 .sparc64 => @compileError("sparc64-solaris mcontext_t missing"),
1507 .x86_64 => extern struct {
1543 .solaris => switch (native_arch) {
1544 .sparc64 => @compileError("sparc64-solaris ucontext_t missing"),
1545 .x86_64 => extern struct {
1546 _flags: u64,
1547 _link: ?*signal_ucontext_t,
1548 _sigmask: std.c.sigset_t,
1549 _stack: std.c.stack_t,
1550 mcontext: extern struct {
15081551 r15: u64,
15091552 r14: u64,
15101553 r13: u64,
......@@ -1524,8 +1567,8 @@ const signal_ucontext_t = switch (native_os) {
15241567 _err: i64,
15251568 rip: u64,
15261569 },
1527 else => unreachable,
15281570 },
1571 else => unreachable,
15291572 },
15301573 // https://github.com/illumos/illumos-gate/blob/d4ce137bba3bd16823db6374d9e9a643264ce245/usr/src/uts/intel/sys/ucontext.h
15311574 .illumos => extern struct {
......@@ -1637,7 +1680,7 @@ const signal_ucontext_t = switch (native_os) {
16371680 },
16381681 },
16391682 // 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"),
16411684 // https://github.com/openbsd/src/blob/42468faed8369d07ae49ae02dd71ec34f59b66cd/sys/arch/i386/include/signal.h
16421685 .x86 => extern struct {
16431686 mcontext: extern struct {