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(
347347) !*align(1) usize {
348348 const reg_bytes = try regBytes(thread_context_ptr, reg_number, reg_context);
349349 if (@sizeOf(usize) != reg_bytes.len) return error.IncompatibleRegisterSize;
350 return mem.bytesAsValue(usize, reg_bytes[0..@sizeOf(usize)]);
350 return @ptrCast(reg_bytes);
351351}
lib/std/debug/SelfInfo.zig+29-23
......@@ -171,26 +171,29 @@ const Module = switch (native_os) {
171171 try loadMachODebugInfo(gpa, module, di); // MLUGG TODO inline
172172 }
173173 fn loadUnwindInfo(module: *const Module, gpa: Allocator, di: *Module.DebugInfo) !void {
174 // MLUGG TODO HACKHACK
175 try loadMachODebugInfo(gpa, module, di);
174 _ = gpa;
175 di.unwind = .{
176 .unwind_info = module.unwind_info,
177 .eh_frame = module.eh_frame,
178 };
176179 }
177180 fn getSymbolAtAddress(module: *const Module, gpa: Allocator, di: *DebugInfo, address: usize) !std.debug.Symbol {
178181 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
181184 // offset of `address` from start of `symbol`
182185 const address_symbol_offset = vaddr - symbol.addr;
183186
184187 // Take the symbol name from the N_FUN STAB entry, we're going to
185188 // use it if we fail to find the DWARF infos
186 const stab_symbol = mem.sliceTo(di.strings[symbol.strx..], 0);
187 const o_file_path = mem.sliceTo(di.strings[symbol.ofile..], 0);
189 const stab_symbol = mem.sliceTo(di.full.strings[symbol.strx..], 0);
190 const o_file_path = mem.sliceTo(di.full.strings[symbol.ofile..], 0);
188191
189192 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);
191194 if (!gop.found_existing) {
192195 gop.value_ptr.* = DebugInfo.loadOFile(gpa, o_file_path) catch |err| {
193 defer _ = di.ofiles.pop().?;
196 defer _ = di.full.ofiles.pop().?;
194197 switch (err) {
195198 error.FileNotFound,
196199 error.MissingDebugInfo,
......@@ -234,28 +237,33 @@ const Module = switch (native_os) {
234237 }
235238 fn unwindFrame(module: *const Module, gpa: Allocator, di: *DebugInfo, context: *UnwindContext) !usize {
236239 _ = gpa;
237 const unwind_info = di.unwind_info orelse return error.MissingUnwindInfo;
240 const unwind_info = di.unwind.unwind_info orelse return error.MissingUnwindInfo;
238241 // MLUGG TODO: inline
239242 return unwindFrameMachO(
240243 module.text_base,
241244 module.load_offset,
242245 context,
243246 unwind_info,
244 di.eh_frame,
247 di.unwind.eh_frame,
245248 );
246249 }
247250 const LookupCache = void;
248251 const DebugInfo = struct {
249 mapped_memory: []align(std.heap.page_size_min) const u8,
250 symbols: []const MachoSymbol,
251 strings: [:0]const u8,
252 // MLUGG TODO: this could use an adapter to just index straight into `strings`!
253 ofiles: std.StringArrayHashMapUnmanaged(OFile),
252 unwind: struct {
253 unwind_info: ?[]const u8,
254 eh_frame: ?[]const u8,
255 },
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
255265 // Backed by the in-memory sections mapped by the loader
256266 // 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
260268 // MLUGG TODO HACKHACK: this is awful
261269 const init: DebugInfo = undefined;
......@@ -267,13 +275,13 @@ const Module = switch (native_os) {
267275 };
268276
269277 fn deinit(di: *DebugInfo, gpa: Allocator) void {
270 for (di.ofiles.values()) |*ofile| {
278 for (di.full.ofiles.values()) |*ofile| {
271279 ofile.dwarf.deinit(gpa);
272280 ofile.addr_table.deinit(gpa);
273281 }
274 di.ofiles.deinit();
275 gpa.free(di.symbols);
276 posix.munmap(di.mapped_memory);
282 di.full.ofiles.deinit();
283 gpa.free(di.full.symbols);
284 posix.munmap(di.full.mapped_memory);
277285 }
278286
279287 fn loadOFile(gpa: Allocator, o_file_path: []const u8) !OFile {
......@@ -859,9 +867,7 @@ fn loadMachODebugInfo(gpa: Allocator, module: *const Module, di: *Module.DebugIn
859867 // This sort is so that we can binary search later.
860868 mem.sort(MachoSymbol, symbols_slice, {}, MachoSymbol.addressLessThan);
861869
862 di.* = .{
863 .unwind_info = module.unwind_info,
864 .eh_frame = module.eh_frame,
870 di.full = .{
865871 .mapped_memory = mapped_mem,
866872 .symbols = symbols_slice,
867873 .strings = strings,