Skip to content

Commit 8520e93

Browse files
committed
std.debug: add loongarch64-linux unwind support
1 parent b468678 commit 8520e93

File tree

3 files changed

+118
-8
lines changed

3 files changed

+118
-8
lines changed

lib/std/debug/Dwarf.zig

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1429,30 +1429,33 @@ pub fn compactUnwindToDwarfRegNumber(unwind_reg_number: u3) !u16 {
14291429
/// Returns `null` for CPU architectures without an instruction pointer register.
14301430
pub fn ipRegNum(arch: std.Target.Cpu.Arch) ?u16 {
14311431
return switch (arch) {
1432+
.aarch64, .aarch64_be => 32,
1433+
.arm, .armeb, .thumb, .thumbeb => 15,
1434+
.loongarch32, .loongarch64 => 32,
14321435
.x86 => 8,
14331436
.x86_64 => 16,
1434-
.arm, .armeb, .thumb, .thumbeb => 15,
1435-
.aarch64, .aarch64_be => 32,
14361437
else => null,
14371438
};
14381439
}
14391440

14401441
pub fn fpRegNum(arch: std.Target.Cpu.Arch) u16 {
14411442
return switch (arch) {
1443+
.aarch64, .aarch64_be => 29,
1444+
.arm, .armeb, .thumb, .thumbeb => 11,
1445+
.loongarch32, .loongarch64 => 22,
14421446
.x86 => 5,
14431447
.x86_64 => 6,
1444-
.arm, .armeb, .thumb, .thumbeb => 11,
1445-
.aarch64, .aarch64_be => 29,
14461448
else => unreachable,
14471449
};
14481450
}
14491451

14501452
pub fn spRegNum(arch: std.Target.Cpu.Arch) u16 {
14511453
return switch (arch) {
1454+
.aarch64, .aarch64_be => 31,
1455+
.arm, .armeb, .thumb, .thumbeb => 13,
1456+
.loongarch32, .loongarch64 => 3,
14521457
.x86 => 4,
14531458
.x86_64 => 7,
1454-
.arm, .armeb, .thumb, .thumbeb => 13,
1455-
.aarch64, .aarch64_be => 31,
14561459
else => unreachable,
14571460
};
14581461
}

lib/std/debug/SelfInfo/Elf.zig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ pub const can_unwind: bool = s: {
8787
.linux => &.{
8888
.aarch64,
8989
.aarch64_be,
90+
.loongarch64,
9091
.x86,
9192
.x86_64,
9293
},

lib/std/debug/cpu_context.zig

Lines changed: 108 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,11 @@
44
pub const Native = if (@hasDecl(root, "debug") and @hasDecl(root.debug, "CpuContext"))
55
root.debug.CpuContext
66
else switch (native_arch) {
7+
.aarch64, .aarch64_be => Aarch64,
8+
.arm, .armeb, .thumb, .thumbeb => Arm,
9+
.loongarch32, .loongarch64 => LoongArch,
710
.x86 => X86,
811
.x86_64 => X86_64,
9-
.arm, .armeb, .thumb, .thumbeb => Arm,
10-
.aarch64, .aarch64_be => Aarch64,
1112
else => noreturn,
1213
};
1314

@@ -173,6 +174,13 @@ pub fn fromPosixSignalContext(ctx_ptr: ?*const anyopaque) ?Native {
173174
},
174175
else => null,
175176
},
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+
},
176184
else => null,
177185
};
178186
}
@@ -465,6 +473,104 @@ pub const Aarch64 = extern struct {
465473
}
466474
};
467475

476+
/// This is an `extern struct` so that inline assembly in `current` can use field offsets.
477+
pub 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+
468574
const signal_ucontext_t = switch (native_os) {
469575
.linux => std.os.linux.ucontext_t,
470576
.emscripten => std.os.emscripten.ucontext_t,

0 commit comments

Comments
 (0)