authorgravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2026-06-16 12:10:37+02:00
committergravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2026-06-16 12:12:05+02:00
log42618257666727aaf51957966ec88ef54242f840
tree3faff1eee48091297303b70f831764634d067043
parentcf13ecab29a2aa3b8616e03e4ec50f4b89f73c7b
signaturebadge-check Signed by SSH key SHA256:7B/LJ7bpR1eX8aCXSr4mtd5M45VMPKcx9zY8e95b5QM

std.debug.Dwarf: fix unwinding when address size is smaller than register size


2 files changed, 10 insertions(+), 15 deletions(-)

lib/std/debug/Dwarf/SelfUnwinder.zig+8-13
......@@ -168,7 +168,7 @@ fn nextInner(unwinder: *SelfUnwinder, gpa: Allocator, cache_entry: *const CacheE
168168 .none => return error.InvalidDebugInfo,
169169 .reg_off => |ro| cfa: {
170170 const ptr = try regNative(&unwinder.cpu_state, ro.register);
171 break :cfa try applyOffset(ptr.*, ro.offset);
171 break :cfa try applyOffset(@intCast(ptr.*), ro.offset);
172172 },
173173 .expression => |expr| cfa: {
174174 // On most implemented architectures, the CFA is defined to be the previous frame's SP.
......@@ -181,7 +181,7 @@ fn nextInner(unwinder: *SelfUnwinder, gpa: Allocator, cache_entry: *const CacheE
181181 const value = try unwinder.expr_vm.run(expr, gpa, .{
182182 .format = format,
183183 .cpu_context = &unwinder.cpu_state,
184 }, prev_cfa_val) orelse return error.InvalidDebugInfo;
184 }, @intCast(prev_cfa_val)) orelse return error.InvalidDebugInfo;
185185 switch (value) {
186186 .generic => |g| break :cfa g,
187187 else => return error.InvalidDebugInfo,
......@@ -203,7 +203,7 @@ fn nextInner(unwinder: *SelfUnwinder, gpa: Allocator, cache_entry: *const CacheE
203203 const new_val: union(enum) {
204204 same,
205205 undefined,
206 val: usize,
206 val: std.debug.cpu_context.Native.Gpr,
207207 bytes: []const u8,
208208 } = switch (rule) {
209209 .default => val: {
......@@ -219,7 +219,7 @@ fn nextInner(unwinder: *SelfUnwinder, gpa: Allocator, cache_entry: *const CacheE
219219 .undefined => .undefined,
220220 .same_value => .same,
221221 .offset => |offset| val: {
222 const ptr: *const usize = @ptrFromInt(try applyOffset(cfa, offset));
222 const ptr: *const std.debug.cpu_context.Native.Gpr = @ptrFromInt(try applyOffset(cfa, offset));
223223 break :val .{ .val = ptr.* };
224224 },
225225 .val_offset => |offset| .{ .val = try applyOffset(cfa, offset) },
......@@ -260,12 +260,7 @@ fn nextInner(unwinder: *SelfUnwinder, gpa: Allocator, cache_entry: *const CacheE
260260 has_return_address = false;
261261 }
262262 },
263 .val => |val| {
264 const dest = try new_cpu_state.dwarfRegisterBytes(@intCast(register));
265 if (dest.len != @sizeOf(usize)) return error.InvalidDebugInfo;
266 const dest_ptr: *align(1) usize = @ptrCast(dest);
267 dest_ptr.* = val;
268 },
263 .val => |val| (try regNative(&new_cpu_state, register)).* = val,
269264 .bytes => |src| {
270265 const dest = try new_cpu_state.dwarfRegisterBytes(@intCast(register));
271266 if (dest.len != src.len) return error.InvalidDebugInfo;
......@@ -275,7 +270,7 @@ fn nextInner(unwinder: *SelfUnwinder, gpa: Allocator, cache_entry: *const CacheE
275270 }
276271
277272 const return_address = if (has_return_address)
278 stripInstructionPtrAuthCode((try regNative(&new_cpu_state, return_address_register)).*)
273 stripInstructionPtrAuthCode(@intCast((try regNative(&new_cpu_state, return_address_register)).*))
279274 else
280275 0;
281276
......@@ -303,9 +298,9 @@ pub fn regNative(ctx: *std.debug.cpu_context.Native, num: u16) error{
303298 InvalidRegister,
304299 UnsupportedRegister,
305300 IncompatibleRegisterSize,
306}!*align(1) usize {
301}!*align(1) std.debug.cpu_context.Native.Gpr {
307302 const bytes = try ctx.dwarfRegisterBytes(num);
308 if (bytes.len != @sizeOf(usize)) return error.IncompatibleRegisterSize;
303 if (bytes.len != @sizeOf(std.debug.cpu_context.Native.Gpr)) return error.IncompatibleRegisterSize;
309304 return @ptrCast(bytes);
310305}
311306
lib/std/debug/Dwarf/expression.zig+2-2
......@@ -387,7 +387,7 @@ pub fn StackMachine(comptime options: Options) type {
387387 .regval_type = .{
388388 .type_offset = rt.type_offset,
389389 .type_size = @sizeOf(addr_type),
390 .value = (try regNative(cpu_context, rt.register)).*,
390 .value = @intCast((try regNative(cpu_context, rt.register)).*),
391391 },
392392 });
393393 },
......@@ -738,7 +738,7 @@ pub fn StackMachine(comptime options: Options) type {
738738 var block_stream: std.Io.Reader = .fixed(block);
739739 const register = (try readOperand(&block_stream, block[0], context)).?.register;
740740 const value = (try regNative(cpu_context, register)).*;
741 try self.stack.append(allocator, .{ .generic = value });
741 try self.stack.append(allocator, .{ .generic = @intCast(value) });
742742 } else {
743743 var stack_machine: Self = .{};
744744 defer stack_machine.deinit(allocator);