| ... | ... | @@ -171,26 +171,29 @@ const Module = switch (native_os) { |
| 171 | 171 | try loadMachODebugInfo(gpa, module, di); // MLUGG TODO inline |
| 172 | 172 | } |
| 173 | 173 | 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 | }; |
| 176 | 179 | } |
| 177 | 180 | fn getSymbolAtAddress(module: *const Module, gpa: Allocator, di: *DebugInfo, address: usize) !std.debug.Symbol { |
| 178 | 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? |
| 180 | 183 | |
| 181 | 184 | // offset of `address` from start of `symbol` |
| 182 | 185 | const address_symbol_offset = vaddr - symbol.addr; |
| 183 | 186 | |
| 184 | 187 | // Take the symbol name from the N_FUN STAB entry, we're going to |
| 185 | 188 | // 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); |
| 188 | 191 | |
| 189 | 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 | 194 | if (!gop.found_existing) { |
| 192 | 195 | gop.value_ptr.* = DebugInfo.loadOFile(gpa, o_file_path) catch |err| { |
| 193 | | defer _ = di.ofiles.pop().?; |
| 196 | defer _ = di.full.ofiles.pop().?; |
| 194 | 197 | switch (err) { |
| 195 | 198 | error.FileNotFound, |
| 196 | 199 | error.MissingDebugInfo, |
| ... | ... | @@ -234,28 +237,33 @@ const Module = switch (native_os) { |
| 234 | 237 | } |
| 235 | 238 | fn unwindFrame(module: *const Module, gpa: Allocator, di: *DebugInfo, context: *UnwindContext) !usize { |
| 236 | 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 | 241 | // MLUGG TODO: inline |
| 239 | 242 | return unwindFrameMachO( |
| 240 | 243 | module.text_base, |
| 241 | 244 | module.load_offset, |
| 242 | 245 | context, |
| 243 | 246 | unwind_info, |
| 244 | | di.eh_frame, |
| 247 | di.unwind.eh_frame, |
| 245 | 248 | ); |
| 246 | 249 | } |
| 247 | 250 | const LookupCache = void; |
| 248 | 251 | 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 | }, |
| 254 | 264 | |
| 255 | 265 | // Backed by the in-memory sections mapped by the loader |
| 256 | 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, |
| 259 | 267 | |
| 260 | 268 | // MLUGG TODO HACKHACK: this is awful |
| 261 | 269 | const init: DebugInfo = undefined; |
| ... | ... | @@ -267,13 +275,13 @@ const Module = switch (native_os) { |
| 267 | 275 | }; |
| 268 | 276 | |
| 269 | 277 | fn deinit(di: *DebugInfo, gpa: Allocator) void { |
| 270 | | for (di.ofiles.values()) |*ofile| { |
| 278 | for (di.full.ofiles.values()) |*ofile| { |
| 271 | 279 | ofile.dwarf.deinit(gpa); |
| 272 | 280 | ofile.addr_table.deinit(gpa); |
| 273 | 281 | } |
| 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); |
| 277 | 285 | } |
| 278 | 286 | |
| 279 | 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 | 867 | // This sort is so that we can binary search later. |
| 860 | 868 | mem.sort(MachoSymbol, symbols_slice, {}, MachoSymbol.addressLessThan); |
| 861 | 869 | |
| 862 | | di.* = .{ |
| 863 | | .unwind_info = module.unwind_info, |
| 864 | | .eh_frame = module.eh_frame, |
| 870 | di.full = .{ |
| 865 | 871 | .mapped_memory = mapped_mem, |
| 866 | 872 | .symbols = symbols_slice, |
| 867 | 873 | .strings = strings, |