From 83add375c4734a6091dfc31563482b1b7157c1d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Antonin=20D=C3=A9cimo?= Date: Tue, 17 Mar 2026 01:35:27 +0100 Subject: [PATCH] zld: fix null dereference parsing Mach-O non-existing atom or FDE If the unwind record address has not been added to `superposition` (maybe it is not in the current symbol table mapping?) then there's a panic on null dereference. Ensure the entry exists in `superposition`. --- src/link/MachO/Object.zig | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/link/MachO/Object.zig b/src/link/MachO/Object.zig index 24d44b4e3a46262ce59d21b321baa5b9656bf867..e81ef5558b64fd878044322fb82e9882150af970 100644 --- a/src/link/MachO/Object.zig +++ b/src/link/MachO/Object.zig @@ -1295,7 +1295,13 @@ fn parseUnwindRecords(self: *Object, allocator: Allocator, cpu_arch: std.Target. const rec = self.getUnwindRecord(rec_index); const atom = rec.getAtom(macho_file); const addr = atom.getInputAddress(macho_file) + rec.atom_offset; - superposition.getPtr(addr).?.cu = rec_index; + + try superposition.ensureUnusedCapacity(1); + const gop = superposition.getOrPutAssumeCapacity(addr); + if (!gop.found_existing) { + gop.value_ptr.* = .{ .atom = rec.atom, .size = rec.length }; + } + gop.value_ptr.cu = rec_index; } const FdeRange = struct { start: u64, end: u64 }; @@ -1305,7 +1311,13 @@ fn parseUnwindRecords(self: *Object, allocator: Allocator, cpu_arch: std.Target. for (self.fdes.items, 0..) |fde, fde_index| { const atom = fde.getAtom(macho_file); const addr = atom.getInputAddress(macho_file) + fde.atom_offset; - superposition.getPtr(addr).?.fde = @intCast(fde_index); + + try superposition.ensureUnusedCapacity(1); + const gop = superposition.getOrPutAssumeCapacity(addr); + if (!gop.found_existing) { + gop.value_ptr.* = .{ .atom = fde.atom, .size = fde.pc_range }; + } + gop.value_ptr.fde = @intCast(fde_index); // Build FDE range for coverage check const pc_range = fde.pc_range; -- 2.54.0