authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2025-09-02 13:44:18+01:00
committergravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2025-09-30 13:44:49+01:00
log25e02bed4cebc7c90f763fae5d57e3d99a08bdfc
tree7fbe97a97e317cad7597b40b7216aefa876b9edc
parent55ae6747e2ad85f9f92919cab174efadc40ea002
signaturelock-open Commit is signed but in an unrecognized format.

less hacky :D


2 files changed, 30 insertions(+), 24 deletions(-)

lib/std/debug/Dwarf/abi.zig+1-1
...@@ -347,5 +347,5 @@ pub fn regValueNative(...@@ -347,5 +347,5 @@ pub fn regValueNative(
347) !*align(1) usize {347) !*align(1) usize {
348 const reg_bytes = try regBytes(thread_context_ptr, reg_number, reg_context);348 const reg_bytes = try regBytes(thread_context_ptr, reg_number, reg_context);
349 if (@sizeOf(usize) != reg_bytes.len) return error.IncompatibleRegisterSize;349 if (@sizeOf(usize) != reg_bytes.len) return error.IncompatibleRegisterSize;
350 return mem.bytesAsValue(usize, reg_bytes[0..@sizeOf(usize)]);350 return @ptrCast(reg_bytes);
351}351}
lib/std/debug/SelfInfo.zig+29-23
...@@ -171,26 +171,29 @@ const Module = switch (native_os) {...@@ -171,26 +171,29 @@ const Module = switch (native_os) {
171 try loadMachODebugInfo(gpa, module, di); // MLUGG TODO inline171 try loadMachODebugInfo(gpa, module, di); // MLUGG TODO inline
172 }172 }
173 fn loadUnwindInfo(module: *const Module, gpa: Allocator, di: *Module.DebugInfo) !void {173 fn loadUnwindInfo(module: *const Module, gpa: Allocator, di: *Module.DebugInfo) !void {
174 // MLUGG TODO HACKHACK174 _ = gpa;
175 try loadMachODebugInfo(gpa, module, di);175 di.unwind = .{
176 .unwind_info = module.unwind_info,
177 .eh_frame = module.eh_frame,
178 };
176 }179 }
177 fn getSymbolAtAddress(module: *const Module, gpa: Allocator, di: *DebugInfo, address: usize) !std.debug.Symbol {180 fn getSymbolAtAddress(module: *const Module, gpa: Allocator, di: *DebugInfo, address: usize) !std.debug.Symbol {
178 const vaddr = address - module.load_offset;181 const vaddr = address - module.load_offset;
179 const symbol = MachoSymbol.find(di.symbols, vaddr) orelse return .{}; // MLUGG TODO null?182 const symbol = MachoSymbol.find(di.full.symbols, vaddr) orelse return .{}; // MLUGG TODO null?
180183
181 // offset of `address` from start of `symbol`184 // offset of `address` from start of `symbol`
182 const address_symbol_offset = vaddr - symbol.addr;185 const address_symbol_offset = vaddr - symbol.addr;
183186
184 // Take the symbol name from the N_FUN STAB entry, we're going to187 // Take the symbol name from the N_FUN STAB entry, we're going to
185 // use it if we fail to find the DWARF infos188 // use it if we fail to find the DWARF infos
186 const stab_symbol = mem.sliceTo(di.strings[symbol.strx..], 0);189 const stab_symbol = mem.sliceTo(di.full.strings[symbol.strx..], 0);
187 const o_file_path = mem.sliceTo(di.strings[symbol.ofile..], 0);190 const o_file_path = mem.sliceTo(di.full.strings[symbol.ofile..], 0);
188191
189 const o_file: *DebugInfo.OFile = of: {192 const o_file: *DebugInfo.OFile = of: {
190 const gop = try di.ofiles.getOrPut(gpa, o_file_path);193 const gop = try di.full.ofiles.getOrPut(gpa, o_file_path);
191 if (!gop.found_existing) {194 if (!gop.found_existing) {
192 gop.value_ptr.* = DebugInfo.loadOFile(gpa, o_file_path) catch |err| {195 gop.value_ptr.* = DebugInfo.loadOFile(gpa, o_file_path) catch |err| {
193 defer _ = di.ofiles.pop().?;196 defer _ = di.full.ofiles.pop().?;
194 switch (err) {197 switch (err) {
195 error.FileNotFound,198 error.FileNotFound,
196 error.MissingDebugInfo,199 error.MissingDebugInfo,
...@@ -234,28 +237,33 @@ const Module = switch (native_os) {...@@ -234,28 +237,33 @@ const Module = switch (native_os) {
234 }237 }
235 fn unwindFrame(module: *const Module, gpa: Allocator, di: *DebugInfo, context: *UnwindContext) !usize {238 fn unwindFrame(module: *const Module, gpa: Allocator, di: *DebugInfo, context: *UnwindContext) !usize {
236 _ = gpa;239 _ = gpa;
237 const unwind_info = di.unwind_info orelse return error.MissingUnwindInfo;240 const unwind_info = di.unwind.unwind_info orelse return error.MissingUnwindInfo;
238 // MLUGG TODO: inline241 // MLUGG TODO: inline
239 return unwindFrameMachO(242 return unwindFrameMachO(
240 module.text_base,243 module.text_base,
241 module.load_offset,244 module.load_offset,
242 context,245 context,
243 unwind_info,246 unwind_info,
244 di.eh_frame,247 di.unwind.eh_frame,
245 );248 );
246 }249 }
247 const LookupCache = void;250 const LookupCache = void;
248 const DebugInfo = struct {251 const DebugInfo = struct {
249 mapped_memory: []align(std.heap.page_size_min) const u8,252 unwind: struct {
250 symbols: []const MachoSymbol,253 unwind_info: ?[]const u8,
251 strings: [:0]const u8,254 eh_frame: ?[]const u8,
252 // MLUGG TODO: this could use an adapter to just index straight into `strings`!255 },
253 ofiles: std.StringArrayHashMapUnmanaged(OFile),256 // MLUGG TODO: awful field name
257 full: struct {
258 mapped_memory: []align(std.heap.page_size_min) const u8,
259 symbols: []const MachoSymbol,
260 strings: [:0]const u8,
261 // MLUGG TODO: this could use an adapter to just index straight into `strings`!
262 ofiles: std.StringArrayHashMapUnmanaged(OFile),
263 },
254264
255 // Backed by the in-memory sections mapped by the loader265 // Backed by the in-memory sections mapped by the loader
256 // MLUGG TODO: these are duplicated state. i actually reckon they should be removed from Module, and loadMachODebugInfo should be the one discovering them!266 // MLUGG TODO: these are duplicated state. i actually reckon they should be removed from Module, and loadMachODebugInfo should be the one discovering them!
257 unwind_info: ?[]const u8,
258 eh_frame: ?[]const u8,
259267
260 // MLUGG TODO HACKHACK: this is awful268 // MLUGG TODO HACKHACK: this is awful
261 const init: DebugInfo = undefined;269 const init: DebugInfo = undefined;
...@@ -267,13 +275,13 @@ const Module = switch (native_os) {...@@ -267,13 +275,13 @@ const Module = switch (native_os) {
267 };275 };
268276
269 fn deinit(di: *DebugInfo, gpa: Allocator) void {277 fn deinit(di: *DebugInfo, gpa: Allocator) void {
270 for (di.ofiles.values()) |*ofile| {278 for (di.full.ofiles.values()) |*ofile| {
271 ofile.dwarf.deinit(gpa);279 ofile.dwarf.deinit(gpa);
272 ofile.addr_table.deinit(gpa);280 ofile.addr_table.deinit(gpa);
273 }281 }
274 di.ofiles.deinit();282 di.full.ofiles.deinit();
275 gpa.free(di.symbols);283 gpa.free(di.full.symbols);
276 posix.munmap(di.mapped_memory);284 posix.munmap(di.full.mapped_memory);
277 }285 }
278286
279 fn loadOFile(gpa: Allocator, o_file_path: []const u8) !OFile {287 fn loadOFile(gpa: Allocator, o_file_path: []const u8) !OFile {
...@@ -859,9 +867,7 @@ fn loadMachODebugInfo(gpa: Allocator, module: *const Module, di: *Module.DebugIn...@@ -859,9 +867,7 @@ fn loadMachODebugInfo(gpa: Allocator, module: *const Module, di: *Module.DebugIn
859 // This sort is so that we can binary search later.867 // This sort is so that we can binary search later.
860 mem.sort(MachoSymbol, symbols_slice, {}, MachoSymbol.addressLessThan);868 mem.sort(MachoSymbol, symbols_slice, {}, MachoSymbol.addressLessThan);
861869
862 di.* = .{870 di.full = .{
863 .unwind_info = module.unwind_info,
864 .eh_frame = module.eh_frame,
865 .mapped_memory = mapped_mem,871 .mapped_memory = mapped_mem,
866 .symbols = symbols_slice,872 .symbols = symbols_slice,
867 .strings = strings,873 .strings = strings,