From af71694dd946a88bf0db55e4513223e344bfde40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Mon, 4 Nov 2024 08:29:18 +0100 Subject: [PATCH] std.debug: Add handling for armeb, thumb, thumbeb, and aarch64_be. --- lib/std/debug.zig | 4 ++++ lib/std/debug/Dwarf/abi.zig | 18 +++++++++--------- lib/std/debug/SelfInfo.zig | 10 +++++----- 3 files changed, 18 insertions(+), 14 deletions(-) diff --git a/lib/std/debug.zig b/lib/std/debug.zig index 5b18f37b6a..982e71bc35 100644 --- a/lib/std/debug.zig +++ b/lib/std/debug.zig @@ -1335,7 +1335,11 @@ fn dumpSegfaultInfoPosix(sig: i32, code: i32, addr: usize, ctx_ptr: ?*anyopaque) .x86, .x86_64, .arm, + .armeb, + .thumb, + .thumbeb, .aarch64, + .aarch64_be, => { const ctx: *posix.ucontext_t = @ptrCast(@alignCast(ctx_ptr)); dumpStackTraceFromBase(ctx); diff --git a/lib/std/debug/Dwarf/abi.zig b/lib/std/debug/Dwarf/abi.zig index 60fd10a794..e0a2a4858b 100644 --- a/lib/std/debug/Dwarf/abi.zig +++ b/lib/std/debug/Dwarf/abi.zig @@ -35,8 +35,8 @@ pub fn ipRegNum(arch: Arch) ?u8 { return switch (arch) { .x86 => 8, .x86_64 => 16, - .arm => 15, - .aarch64 => 32, + .arm, .armeb, .thumb, .thumbeb => 15, + .aarch64, .aarch64_be => 32, else => null, }; } @@ -47,8 +47,8 @@ pub fn fpRegNum(arch: Arch, reg_context: RegisterContext) u8 { // (only in .eh_frame), and that is now the convention for MachO .x86 => if (reg_context.eh_frame and reg_context.is_macho) 4 else 5, .x86_64 => 6, - .arm => 11, - .aarch64 => 29, + .arm, .armeb, .thumb, .thumbeb => 11, + .aarch64, .aarch64_be => 29, else => unreachable, }; } @@ -57,8 +57,8 @@ pub fn spRegNum(arch: Arch, reg_context: RegisterContext) u8 { return switch (arch) { .x86 => if (reg_context.eh_frame and reg_context.is_macho) 5 else 4, .x86_64 => 7, - .arm => 13, - .aarch64 => 31, + .arm, .armeb, .thumb, .thumbeb => 13, + .aarch64, .aarch64_be => 31, else => unreachable, }; } @@ -131,7 +131,7 @@ pub fn regBytes( 16 => mem.asBytes(&thread_context_ptr.Rip), else => error.InvalidRegister, }, - .aarch64 => switch (reg_number) { + .aarch64, .aarch64_be => switch (reg_number) { 0...30 => mem.asBytes(&thread_context_ptr.DUMMYUNIONNAME.X[reg_number]), 31 => mem.asBytes(&thread_context_ptr.Sp), 32 => mem.asBytes(&thread_context_ptr.Pc), @@ -269,7 +269,7 @@ pub fn regBytes( }, else => error.UnimplementedOs, }, - .arm => switch (builtin.os.tag) { + .arm, .armeb, .thumb, .thumbeb => switch (builtin.os.tag) { .linux => switch (reg_number) { 0 => mem.asBytes(&ucontext_ptr.mcontext.arm_r0), 1 => mem.asBytes(&ucontext_ptr.mcontext.arm_r1), @@ -292,7 +292,7 @@ pub fn regBytes( }, else => error.UnimplementedOs, }, - .aarch64 => switch (builtin.os.tag) { + .aarch64, .aarch64_be => switch (builtin.os.tag) { .macos, .ios, .watchos => switch (reg_number) { 0...28 => mem.asBytes(&ucontext_ptr.mcontext.ss.regs[reg_number]), 29 => mem.asBytes(&ucontext_ptr.mcontext.ss.fp), diff --git a/lib/std/debug/SelfInfo.zig b/lib/std/debug/SelfInfo.zig index 228458aaef..544cf0ac6f 100644 --- a/lib/std/debug/SelfInfo.zig +++ b/lib/std/debug/SelfInfo.zig @@ -1419,7 +1419,7 @@ pub fn unwindFrameMachO( return unwindFrameMachODwarf(context, ma, eh_frame orelse return error.MissingEhFrame, @intCast(encoding.value.x86_64.dwarf)); }, }, - .aarch64 => switch (encoding.mode.arm64) { + .aarch64, .aarch64_be => switch (encoding.mode.arm64) { .OLD => return error.UnimplementedUnwindEncoding, .FRAMELESS => blk: { const sp = (try regValueNative(context.thread_context, spRegNum(reg_context), reg_context)).*; @@ -1535,7 +1535,7 @@ pub const UnwindContext = struct { /// Some platforms use pointer authentication - the upper bits of instruction pointers contain a signature. /// This function clears these signature bits to make the pointer usable. pub inline fn stripInstructionPtrAuthCode(ptr: usize) usize { - if (native_arch == .aarch64) { + if (native_arch.isAARCH64()) { // `hint 0x07` maps to `xpaclri` (or `nop` if the hardware doesn't support it) // The save / restore is because `xpaclri` operates on x30 (LR) return asm ( @@ -1787,11 +1787,11 @@ pub fn supportsUnwinding(target: std.Target) bool { .linux, .netbsd, .freebsd, .openbsd, .macos, .ios, .solaris, .illumos => true, else => false, }, - .arm => switch (target.os.tag) { + .arm, .armeb, .thumb, .thumbeb => switch (target.os.tag) { .linux => true, else => false, }, - .aarch64 => switch (target.os.tag) { + .aarch64, .aarch64_be => switch (target.os.tag) { .linux, .netbsd, .freebsd, .macos, .ios => true, else => false, }, @@ -2194,7 +2194,7 @@ pub const VirtualMachine = struct { /// the .undefined rule by default, but allows ABI authors to override that. fn getRegDefaultValue(reg_number: u8, context: *UnwindContext, out: []u8) !void { switch (builtin.cpu.arch) { - .aarch64 => { + .aarch64, .aarch64_be => { // Callee-saved registers are initialized as if they had the .same_value rule if (reg_number >= 19 and reg_number <= 28) { const src = try regBytes(context.thread_context, reg_number, context.reg_context);