authorgravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2025-10-01 23:24:43+02:00
committergravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2025-10-01 23:47:47+02:00
log8520e9312eed3b3b8d7f95d4844c83105c91ead1
treead03355e6ae4c011458712168f7eec97f5b9d0a7
parentb46867848e4a2e8ba9965d579d4474fba1ab3b10
signaturebadge-check Signed by SSH key SHA256:7B/LJ7bpR1eX8aCXSr4mtd5M45VMPKcx9zY8e95b5QM

std.debug: add loongarch64-linux unwind support


3 files changed, 118 insertions(+), 8 deletions(-)

lib/std/debug/Dwarf.zig+9-6
...@@ -1429,30 +1429,33 @@ pub fn compactUnwindToDwarfRegNumber(unwind_reg_number: u3) !u16 {...@@ -1429,30 +1429,33 @@ pub fn compactUnwindToDwarfRegNumber(unwind_reg_number: u3) !u16 {
1429/// Returns `null` for CPU architectures without an instruction pointer register.1429/// Returns `null` for CPU architectures without an instruction pointer register.
1430pub fn ipRegNum(arch: std.Target.Cpu.Arch) ?u16 {1430pub fn ipRegNum(arch: std.Target.Cpu.Arch) ?u16 {
1431 return switch (arch) {1431 return switch (arch) {
1432 .aarch64, .aarch64_be => 32,
1433 .arm, .armeb, .thumb, .thumbeb => 15,
1434 .loongarch32, .loongarch64 => 32,
1432 .x86 => 8,1435 .x86 => 8,
1433 .x86_64 => 16,1436 .x86_64 => 16,
1434 .arm, .armeb, .thumb, .thumbeb => 15,
1435 .aarch64, .aarch64_be => 32,
1436 else => null,1437 else => null,
1437 };1438 };
1438}1439}
14391440
1440pub fn fpRegNum(arch: std.Target.Cpu.Arch) u16 {1441pub fn fpRegNum(arch: std.Target.Cpu.Arch) u16 {
1441 return switch (arch) {1442 return switch (arch) {
1443 .aarch64, .aarch64_be => 29,
1444 .arm, .armeb, .thumb, .thumbeb => 11,
1445 .loongarch32, .loongarch64 => 22,
1442 .x86 => 5,1446 .x86 => 5,
1443 .x86_64 => 6,1447 .x86_64 => 6,
1444 .arm, .armeb, .thumb, .thumbeb => 11,
1445 .aarch64, .aarch64_be => 29,
1446 else => unreachable,1448 else => unreachable,
1447 };1449 };
1448}1450}
14491451
1450pub fn spRegNum(arch: std.Target.Cpu.Arch) u16 {1452pub fn spRegNum(arch: std.Target.Cpu.Arch) u16 {
1451 return switch (arch) {1453 return switch (arch) {
1454 .aarch64, .aarch64_be => 31,
1455 .arm, .armeb, .thumb, .thumbeb => 13,
1456 .loongarch32, .loongarch64 => 3,
1452 .x86 => 4,1457 .x86 => 4,
1453 .x86_64 => 7,1458 .x86_64 => 7,
1454 .arm, .armeb, .thumb, .thumbeb => 13,
1455 .aarch64, .aarch64_be => 31,
1456 else => unreachable,1459 else => unreachable,
1457 };1460 };
1458}1461}
lib/std/debug/SelfInfo/Elf.zig+1
...@@ -87,6 +87,7 @@ pub const can_unwind: bool = s: {...@@ -87,6 +87,7 @@ pub const can_unwind: bool = s: {
87 .linux => &.{87 .linux => &.{
88 .aarch64,88 .aarch64,
89 .aarch64_be,89 .aarch64_be,
90 .loongarch64,
90 .x86,91 .x86,
91 .x86_64,92 .x86_64,
92 },93 },
lib/std/debug/cpu_context.zig+108-2
...@@ -4,10 +4,11 @@...@@ -4,10 +4,11 @@
4pub const Native = if (@hasDecl(root, "debug") and @hasDecl(root.debug, "CpuContext"))4pub const Native = if (@hasDecl(root, "debug") and @hasDecl(root.debug, "CpuContext"))
5 root.debug.CpuContext5 root.debug.CpuContext
6else switch (native_arch) {6else switch (native_arch) {
7 .aarch64, .aarch64_be => Aarch64,
8 .arm, .armeb, .thumb, .thumbeb => Arm,
9 .loongarch32, .loongarch64 => LoongArch,
7 .x86 => X86,10 .x86 => X86,
8 .x86_64 => X86_64,11 .x86_64 => X86_64,
9 .arm, .armeb, .thumb, .thumbeb => Arm,
10 .aarch64, .aarch64_be => Aarch64,
11 else => noreturn,12 else => noreturn,
12};13};
1314
...@@ -173,6 +174,13 @@ pub fn fromPosixSignalContext(ctx_ptr: ?*const anyopaque) ?Native {...@@ -173,6 +174,13 @@ pub fn fromPosixSignalContext(ctx_ptr: ?*const anyopaque) ?Native {
173 },174 },
174 else => null,175 else => null,
175 },176 },
177 .loongarch64 => switch (builtin.os.tag) {
178 .linux => .{
179 .r = uc.mcontext.regs, // includes r0 (hardwired zero)
180 .pc = uc.mcontext.pc,
181 },
182 else => null,
183 },
176 else => null,184 else => null,
177 };185 };
178}186}
...@@ -465,6 +473,104 @@ pub const Aarch64 = extern struct {...@@ -465,6 +473,104 @@ pub const Aarch64 = extern struct {
465 }473 }
466};474};
467475
476/// This is an `extern struct` so that inline assembly in `current` can use field offsets.
477pub const LoongArch = extern struct {
478 /// The numbered general-purpose registers r0 - r31. r0 must be zero.
479 r: [32]usize,
480 pc: usize,
481
482 pub inline fn current() LoongArch {
483 var ctx: LoongArch = undefined;
484 asm volatile (if (@sizeOf(usize) == 8)
485 \\ st.d $zero, $t0, 0
486 \\ st.d $ra, $t0, 8
487 \\ st.d $tp, $t0, 16
488 \\ st.d $sp, $t0, 24
489 \\ st.d $a0, $t0, 32
490 \\ st.d $a1, $t0, 40
491 \\ st.d $a2, $t0, 48
492 \\ st.d $a3, $t0, 56
493 \\ st.d $a4, $t0, 64
494 \\ st.d $a5, $t0, 72
495 \\ st.d $a6, $t0, 80
496 \\ st.d $a7, $t0, 88
497 \\ st.d $t0, $t0, 96
498 \\ st.d $t1, $t0, 104
499 \\ st.d $t2, $t0, 112
500 \\ st.d $t3, $t0, 120
501 \\ st.d $t4, $t0, 128
502 \\ st.d $t5, $t0, 136
503 \\ st.d $t6, $t0, 144
504 \\ st.d $t7, $t0, 152
505 \\ st.d $t8, $t0, 160
506 \\ st.d $r21, $t0, 168
507 \\ st.d $fp, $t0, 176
508 \\ st.d $s0, $t0, 184
509 \\ st.d $s1, $t0, 192
510 \\ st.d $s2, $t0, 200
511 \\ st.d $s3, $t0, 208
512 \\ st.d $s4, $t0, 216
513 \\ st.d $s5, $t0, 224
514 \\ st.d $s6, $t0, 232
515 \\ st.d $s7, $t0, 240
516 \\ st.d $s8, $t0, 248
517 \\ bl 1f
518 \\1:
519 \\ st.d $ra, $t0, 256
520 \\ ld.d $ra, $t0, 8
521 else
522 \\ st.w $zero, $t0, 0
523 \\ st.w $ra, $t0, 4
524 \\ st.w $tp, $t0, 8
525 \\ st.w $sp, $t0, 12
526 \\ st.w $a0, $t0, 16
527 \\ st.w $a1, $t0, 20
528 \\ st.w $a2, $t0, 24
529 \\ st.w $a3, $t0, 28
530 \\ st.w $a4, $t0, 32
531 \\ st.w $a5, $t0, 36
532 \\ st.w $a6, $t0, 40
533 \\ st.w $a7, $t0, 44
534 \\ st.w $t0, $t0, 48
535 \\ st.w $t1, $t0, 52
536 \\ st.w $t2, $t0, 56
537 \\ st.w $t3, $t0, 60
538 \\ st.w $t4, $t0, 64
539 \\ st.w $t5, $t0, 68
540 \\ st.w $t6, $t0, 72
541 \\ st.w $t7, $t0, 76
542 \\ st.w $t8, $t0, 80
543 \\ st.w $r21, $t0, 84
544 \\ st.w $fp, $t0, 88
545 \\ st.w $s0, $t0, 92
546 \\ st.w $s1, $t0, 96
547 \\ st.w $s2, $t0, 100
548 \\ st.w $s3, $t0, 104
549 \\ st.w $s4, $t0, 108
550 \\ st.w $s5, $t0, 112
551 \\ st.w $s6, $t0, 116
552 \\ st.w $s7, $t0, 120
553 \\ st.w $s8, $t0, 124
554 \\ bl 1f
555 \\1:
556 \\ st.w $ra, $t0, 128
557 \\ ld.w $ra, $t0, 4
558 :
559 : [gprs] "{$r12}" (&ctx),
560 : .{ .memory = true });
561 return ctx;
562 }
563
564 pub fn dwarfRegisterBytes(ctx: *LoongArch, register_num: u16) DwarfRegisterError![]u8 {
565 switch (register_num) {
566 0...31 => return @ptrCast(&ctx.r[register_num]),
567 32 => return @ptrCast(&ctx.pc),
568
569 else => return error.InvalidRegister,
570 }
571 }
572};
573
468const signal_ucontext_t = switch (native_os) {574const signal_ucontext_t = switch (native_os) {
469 .linux => std.os.linux.ucontext_t,575 .linux => std.os.linux.ucontext_t,
470 .emscripten => std.os.emscripten.ucontext_t,576 .emscripten => std.os.emscripten.ucontext_t,