authorgravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2025-10-05 20:09:05+02:00
committergravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2025-10-05 20:09:26+02:00
loga5ff376b8ff6caa857ec2e4da27e5debb716d920
treec562952492650cd0687f58f721a8ddd9657d26d4
parent26403fe3f95063646a3030c2c4216632de2fff11
signaturebadge-check Signed by SSH key SHA256:7B/LJ7bpR1eX8aCXSr4mtd5M45VMPKcx9zY8e95b5QM

std.debug: add unwind support for hexagon-linux


3 files changed, 80 insertions(+), 0 deletions(-)

lib/std/debug/Dwarf.zig+3
...@@ -1431,6 +1431,7 @@ pub fn ipRegNum(arch: std.Target.Cpu.Arch) ?u16 {...@@ -1431,6 +1431,7 @@ pub fn ipRegNum(arch: std.Target.Cpu.Arch) ?u16 {
1431 return switch (arch) {1431 return switch (arch) {
1432 .aarch64, .aarch64_be => 32,1432 .aarch64, .aarch64_be => 32,
1433 .arm, .armeb, .thumb, .thumbeb => 15,1433 .arm, .armeb, .thumb, .thumbeb => 15,
1434 .hexagon => 76,
1434 .loongarch32, .loongarch64 => 32,1435 .loongarch32, .loongarch64 => 32,
1435 .riscv32, .riscv32be, .riscv64, .riscv64be => 32,1436 .riscv32, .riscv32be, .riscv64, .riscv64be => 32,
1436 .s390x => 65,1437 .s390x => 65,
...@@ -1444,6 +1445,7 @@ pub fn fpRegNum(arch: std.Target.Cpu.Arch) u16 {...@@ -1444,6 +1445,7 @@ pub fn fpRegNum(arch: std.Target.Cpu.Arch) u16 {
1444 return switch (arch) {1445 return switch (arch) {
1445 .aarch64, .aarch64_be => 29,1446 .aarch64, .aarch64_be => 29,
1446 .arm, .armeb, .thumb, .thumbeb => 11,1447 .arm, .armeb, .thumb, .thumbeb => 11,
1448 .hexagon => 30,
1447 .loongarch32, .loongarch64 => 22,1449 .loongarch32, .loongarch64 => 22,
1448 .riscv32, .riscv32be, .riscv64, .riscv64be => 8,1450 .riscv32, .riscv32be, .riscv64, .riscv64be => 8,
1449 .s390x => 11,1451 .s390x => 11,
...@@ -1457,6 +1459,7 @@ pub fn spRegNum(arch: std.Target.Cpu.Arch) u16 {...@@ -1457,6 +1459,7 @@ pub fn spRegNum(arch: std.Target.Cpu.Arch) u16 {
1457 return switch (arch) {1459 return switch (arch) {
1458 .aarch64, .aarch64_be => 31,1460 .aarch64, .aarch64_be => 31,
1459 .arm, .armeb, .thumb, .thumbeb => 13,1461 .arm, .armeb, .thumb, .thumbeb => 13,
1462 .hexagon => 29,
1460 .loongarch32, .loongarch64 => 3,1463 .loongarch32, .loongarch64 => 3,
1461 .riscv32, .riscv32be, .riscv64, .riscv64be => 2,1464 .riscv32, .riscv32be, .riscv64, .riscv64be => 2,
1462 .s390x => 15,1465 .s390x => 15,
lib/std/debug/SelfInfo/Elf.zig+1
...@@ -97,6 +97,7 @@ pub const can_unwind: bool = s: {...@@ -97,6 +97,7 @@ pub const can_unwind: bool = s: {
97 .linux => &.{97 .linux => &.{
98 .aarch64,98 .aarch64,
99 .aarch64_be,99 .aarch64_be,
100 .hexagon,
100 .loongarch64,101 .loongarch64,
101 .riscv32,102 .riscv32,
102 .riscv64,103 .riscv64,
lib/std/debug/cpu_context.zig+76
...@@ -6,6 +6,7 @@ pub const Native = if (@hasDecl(root, "debug") and @hasDecl(root.debug, "CpuCont...@@ -6,6 +6,7 @@ pub const Native = if (@hasDecl(root, "debug") and @hasDecl(root.debug, "CpuCont
6else switch (native_arch) {6else switch (native_arch) {
7 .aarch64, .aarch64_be => Aarch64,7 .aarch64, .aarch64_be => Aarch64,
8 .arm, .armeb, .thumb, .thumbeb => Arm,8 .arm, .armeb, .thumb, .thumbeb => Arm,
9 .hexagon => Hexagon,
9 .loongarch32, .loongarch64 => LoongArch,10 .loongarch32, .loongarch64 => LoongArch,
10 .riscv32, .riscv32be, .riscv64, .riscv64be => Riscv,11 .riscv32, .riscv32be, .riscv64, .riscv64be => Riscv,
11 .s390x => S390x,12 .s390x => S390x,
...@@ -181,6 +182,13 @@ pub fn fromPosixSignalContext(ctx_ptr: ?*const anyopaque) ?Native {...@@ -181,6 +182,13 @@ pub fn fromPosixSignalContext(ctx_ptr: ?*const anyopaque) ?Native {
181 },182 },
182 else => null,183 else => null,
183 },184 },
185 .hexagon => switch (builtin.os.tag) {
186 .linux => .{
187 .r = uc.mcontext.gregs,
188 .pc = uc.mcontext.pc,
189 },
190 else => null,
191 },
184 .loongarch64 => switch (builtin.os.tag) {192 .loongarch64 => switch (builtin.os.tag) {
185 .linux => .{193 .linux => .{
186 .r = uc.mcontext.regs, // includes r0 (hardwired zero)194 .r = uc.mcontext.regs, // includes r0 (hardwired zero)
...@@ -502,6 +510,74 @@ pub const Aarch64 = extern struct {...@@ -502,6 +510,74 @@ pub const Aarch64 = extern struct {
502 }510 }
503};511};
504512
513/// This is an `extern struct` so that inline assembly in `current` can use field offsets.
514pub const Hexagon = extern struct {
515 /// The numbered general-purpose registers r0 - r31.
516 r: [32]u32,
517 pc: u32,
518
519 pub inline fn current() Hexagon {
520 var ctx: Hexagon = undefined;
521 asm volatile (
522 \\ memw(r0 + #0) = r0
523 \\ memw(r0 + #4) = r1
524 \\ memw(r0 + #8) = r2
525 \\ memw(r0 + #12) = r3
526 \\ memw(r0 + #16) = r4
527 \\ memw(r0 + #20) = r5
528 \\ memw(r0 + #24) = r6
529 \\ memw(r0 + #28) = r7
530 \\ memw(r0 + #32) = r8
531 \\ memw(r0 + #36) = r9
532 \\ memw(r0 + #40) = r10
533 \\ memw(r0 + #44) = r11
534 \\ memw(r0 + #48) = r12
535 \\ memw(r0 + #52) = r13
536 \\ memw(r0 + #56) = r14
537 \\ memw(r0 + #60) = r15
538 \\ memw(r0 + #64) = r16
539 \\ memw(r0 + #68) = r17
540 \\ memw(r0 + #72) = r18
541 \\ memw(r0 + #76) = r19
542 \\ memw(r0 + #80) = r20
543 \\ memw(r0 + #84) = r21
544 \\ memw(r0 + #88) = r22
545 \\ memw(r0 + #92) = r23
546 \\ memw(r0 + #96) = r24
547 \\ memw(r0 + #100) = r25
548 \\ memw(r0 + #104) = r26
549 \\ memw(r0 + #108) = r27
550 \\ memw(r0 + #112) = r28
551 \\ memw(r0 + #116) = r29
552 \\ memw(r0 + #120) = r30
553 \\ memw(r0 + #124) = r31
554 \\ r1 = pc
555 \\ memw(r0 + #128) = r1
556 \\ r1 = memw(r0 + #4)
557 :
558 : [gprs] "{r0}" (&ctx),
559 : .{ .memory = true });
560 return ctx;
561 }
562
563 pub fn dwarfRegisterBytes(ctx: *Hexagon, register_num: u16) DwarfRegisterError![]u8 {
564 // Sourced from LLVM's HexagonRegisterInfo.td, which disagrees with LLDB...
565 switch (register_num) {
566 0...31 => return @ptrCast(&ctx.r[register_num]),
567 76 => return @ptrCast(&ctx.pc),
568
569 // This is probably covering some numbers that aren't actually mapped, but seriously,
570 // look at that file. I really can't be bothered to make it more precise.
571 32...75 => return error.UnsupportedRegister,
572 77...259 => return error.UnsupportedRegister,
573 // 999999...1000030 => return error.UnsupportedRegister,
574 // 9999999...10000030 => return error.UnsupportedRegister,
575
576 else => return error.InvalidRegister,
577 }
578 }
579};
580
505/// This is an `extern struct` so that inline assembly in `current` can use field offsets.581/// This is an `extern struct` so that inline assembly in `current` can use field offsets.
506pub const LoongArch = extern struct {582pub const LoongArch = extern struct {
507 /// The numbered general-purpose registers r0 - r31. r0 must be zero.583 /// The numbered general-purpose registers r0 - r31. r0 must be zero.