authorgravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2025-10-16 17:31:55+02:00
committergravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2025-10-18 00:36:52+02:00
log4c81a496e7c979755d9fc74734ab740a828c4491
tree9026126ecf1f3af6960de1e6aaa546895d1df75b
parentba9ab3fb6720ff5894ac07741eccaaca44122eb0
signaturebadge-check Signed by SSH key SHA256:7B/LJ7bpR1eX8aCXSr4mtd5M45VMPKcx9zY8e95b5QM

std.debug: add CPU context and DWARF mappings for arc


3 files changed, 83 insertions(+), 3 deletions(-)

lib/std/debug/Dwarf.zig+3
......@@ -1430,6 +1430,7 @@ pub fn compactUnwindToDwarfRegNumber(unwind_reg_number: u3) !u16 {
14301430pub fn ipRegNum(arch: std.Target.Cpu.Arch) ?u16 {
14311431 return switch (arch) {
14321432 .aarch64, .aarch64_be => 32,
1433 .arc => 160,
14331434 .arm, .armeb, .thumb, .thumbeb => 15,
14341435 .csky => 64,
14351436 .hexagon => 76,
......@@ -1452,6 +1453,7 @@ pub fn ipRegNum(arch: std.Target.Cpu.Arch) ?u16 {
14521453pub fn fpRegNum(arch: std.Target.Cpu.Arch) u16 {
14531454 return switch (arch) {
14541455 .aarch64, .aarch64_be => 29,
1456 .arc => 27,
14551457 .arm, .armeb, .thumb, .thumbeb => 11,
14561458 .csky => 14,
14571459 .hexagon => 30,
......@@ -1474,6 +1476,7 @@ pub fn fpRegNum(arch: std.Target.Cpu.Arch) u16 {
14741476pub fn spRegNum(arch: std.Target.Cpu.Arch) u16 {
14751477 return switch (arch) {
14761478 .aarch64, .aarch64_be => 31,
1479 .arc => 28,
14771480 .arm, .armeb, .thumb, .thumbeb => 13,
14781481 .csky => 14,
14791482 .hexagon => 29,
lib/std/debug/SelfInfo/Elf.zig+2-1
......@@ -102,10 +102,11 @@ pub const can_unwind: bool = s: {
102102 .x86,
103103 .x86_64,
104104 },
105 // Not supported yet: arc, arm/armeb/thumb/thumbeb, xtensa
105 // Not supported yet: arm/armeb/thumb/thumbeb, xtensa
106106 .linux => &.{
107107 .aarch64,
108108 .aarch64_be,
109 .arc,
109110 .csky,
110111 .loongarch64,
111112 .m68k,
lib/std/debug/cpu_context.zig+78-2
......@@ -5,6 +5,7 @@ pub const Native = if (@hasDecl(root, "debug") and @hasDecl(root.debug, "CpuCont
55 root.debug.CpuContext
66else switch (native_arch) {
77 .aarch64, .aarch64_be => Aarch64,
8 .arc => Arc,
89 .arm, .armeb, .thumb, .thumbeb => Arm,
910 .csky => Csky,
1011 .hexagon => Hexagon,
......@@ -35,7 +36,20 @@ pub fn fromPosixSignalContext(ctx_ptr: ?*const anyopaque) ?Native {
3536 const uc: *const signal_ucontext_t = @ptrCast(@alignCast(ctx_ptr));
3637
3738 // Deal with some special cases first.
38 if (native_arch.isMIPS32() and native_os == .linux) {
39 if (native_arch == .arc and native_os == .linux) {
40 var native: Native = .{
41 .r = [_]u32{ uc.mcontext.r31, uc.mcontext.r30, 0, uc.mcontext.r28 } ++
42 uc.mcontext.r27_26 ++
43 uc.mcontext.r25_13 ++
44 uc.mcontext.r12_0,
45 .pcl = uc.mcontext.pcl,
46 };
47
48 // I have no idea why the kernel is storing these registers in such a bizarre order...
49 std.mem.reverse(native.r[0..]);
50
51 return native;
52 } else if (native_arch.isMIPS32() and native_os == .linux) {
3953 // The O32 kABI uses 64-bit fields for some reason.
4054 return .{
4155 .r = s: {
......@@ -327,6 +341,68 @@ const X86_64 = struct {
327341 }
328342};
329343
344/// This is an `extern struct` so that inline assembly in `current` can use field offsets.
345const Arc = extern struct {
346 /// The numbered general-purpose registers r0 - r31.
347 r: [32]u32,
348 pcl: u32,
349
350 pub inline fn current() Arc {
351 var ctx: Arc = undefined;
352 asm volatile (
353 \\ st r0, [r8, 0]
354 \\ st r1, [r8, 4]
355 \\ st r2, [r8, 8]
356 \\ st r3, [r8, 12]
357 \\ st r4, [r8, 16]
358 \\ st r5, [r8, 20]
359 \\ st r6, [r8, 24]
360 \\ st r7, [r8, 28]
361 \\ st r8, [r8, 32]
362 \\ st r9, [r8, 36]
363 \\ st r10, [r8, 40]
364 \\ st r11, [r8, 44]
365 \\ st r12, [r8, 48]
366 \\ st r13, [r8, 52]
367 \\ st r14, [r8, 56]
368 \\ st r15, [r8, 60]
369 \\ st r16, [r8, 64]
370 \\ st r17, [r8, 68]
371 \\ st r18, [r8, 72]
372 \\ st r19, [r8, 76]
373 \\ st r20, [r8, 80]
374 \\ st r21, [r8, 84]
375 \\ st r22, [r8, 88]
376 \\ st r23, [r8, 92]
377 \\ st r24, [r8, 96]
378 \\ st r25, [r8, 100]
379 \\ st r26, [r8, 104]
380 \\ st r27, [r8, 108]
381 \\ st r28, [r8, 112]
382 \\ st r29, [r8, 116]
383 \\ st r30, [r8, 120]
384 \\ st r31, [r8, 124]
385 \\ st pcl, [r8, 128]
386 :
387 : [ctx] "{r8}" (&ctx),
388 : .{ .memory = true });
389 return ctx;
390 }
391
392 pub fn dwarfRegisterBytes(ctx: *Arc, register_num: u16) DwarfRegisterError![]u8 {
393 switch (register_num) {
394 0...31 => return @ptrCast(&ctx.r[register_num]),
395 160 => return @ptrCast(&ctx.pcl),
396
397 32...57 => return error.UnsupportedRegister, // Extension Core Registers
398 58...127 => return error.UnsupportedRegister, // Reserved
399 128...159 => return error.UnsupportedRegister, // f0 - f31
400
401 else => return error.InvalidRegister,
402 }
403 }
404};
405
330406const Arm = struct {
331407 /// The numbered general-purpose registers R0 - R15.
332408 r: [16]u32,
......@@ -1517,7 +1593,7 @@ const signal_ucontext_t = switch (native_os) {
15171593 _count: u32,
15181594 },
15191595 _status32: u32,
1520 pc: u32,
1596 pcl: u32,
15211597 r31: u32,
15221598 r27_26: [2]u32,
15231599 r12_0: [13]u32,