authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2025-09-03 13:11:25+01:00
committergravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2025-09-30 13:44:50+01:00
log5e6a1919c730f7c3ad27b9e5c3ddc8938fc2f43f
tree9baf2fcb4e104f0e042e4f0ffb4e8cb8afdef2b1
parent4b47a377175c30ae148bae1191ae49e3ace819db
signaturelock-open Commit is signed but in an unrecognized format.

fix aarch64-macos DWARF unwinding

turns out this isn't technically specific to that target at all; other targets just don't emit mid-function 'ret' instructions as much so certain CFI instruction patterns were only seen on aarch64. thanks to jacob for finding the bug <3

1 files changed, 13 insertions(+), 6 deletions(-)

lib/std/debug/Dwarf/Unwind/VirtualMachine.zig+13-6
...@@ -48,7 +48,10 @@ const ColumnRange = struct {...@@ -48,7 +48,10 @@ const ColumnRange = struct {
48};48};
4949
50columns: std.ArrayList(Column) = .empty,50columns: std.ArrayList(Column) = .empty,
51stack: std.ArrayList(ColumnRange) = .empty,51stack: std.ArrayList(struct {
52 cfa: Column,
53 columns: ColumnRange,
54}) = .empty,
52current_row: Row = .{},55current_row: Row = .{},
5356
54/// The result of executing the CIE's initial_instructions57/// The result of executing the CIE's initial_instructions
...@@ -205,17 +208,21 @@ pub fn step(...@@ -205,17 +208,21 @@ pub fn step(
205 column.rule = .{ .register = i.target_register };208 column.rule = .{ .register = i.target_register };
206 },209 },
207 .remember_state => {210 .remember_state => {
208 try self.stack.append(gpa, self.current_row.columns);211 try self.stack.append(gpa, .{
212 .cfa = self.current_row.cfa,
213 .columns = self.current_row.columns,
214 });
209 self.current_row.copy_on_write = true;215 self.current_row.copy_on_write = true;
210 },216 },
211 .restore_state => {217 .restore_state => {
212 const restored_columns = self.stack.pop() orelse return error.InvalidOperation;218 const restored = self.stack.pop() orelse return error.InvalidOperation;
213 self.columns.shrinkRetainingCapacity(self.columns.items.len - self.current_row.columns.len);219 self.columns.shrinkRetainingCapacity(self.columns.items.len - self.current_row.columns.len);
214 try self.columns.ensureUnusedCapacity(gpa, restored_columns.len);220 try self.columns.ensureUnusedCapacity(gpa, restored.columns.len);
215221
222 self.current_row.cfa = restored.cfa;
216 self.current_row.columns.start = self.columns.items.len;223 self.current_row.columns.start = self.columns.items.len;
217 self.current_row.columns.len = restored_columns.len;224 self.current_row.columns.len = restored.columns.len;
218 self.columns.appendSliceAssumeCapacity(self.columns.items[restored_columns.start..][0..restored_columns.len]);225 self.columns.appendSliceAssumeCapacity(self.columns.items[restored.columns.start..][0..restored.columns.len]);
219 },226 },
220 .def_cfa => |i| {227 .def_cfa => |i| {
221 try self.resolveCopyOnWrite(gpa);228 try self.resolveCopyOnWrite(gpa);