| ... | @@ -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 inline | 171 | 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 HACKHACK | 174 | _ = 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? |
| 180 | | 183 | |
| 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; |
| 183 | | 186 | |
| 184 | // Take the symbol name from the N_FUN STAB entry, we're going to | 187 | // Take the symbol name from the N_FUN STAB entry, we're going to |
| 185 | // use it if we fail to find the DWARF infos | 188 | // 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); |
| 188 | | 191 | |
| 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: inline | 241 | // 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 | }, |
| 254 | | 264 | |
| 255 | // Backed by the in-memory sections mapped by the loader | 265 | // 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, | | |
| 259 | | 267 | |
| 260 | // MLUGG TODO HACKHACK: this is awful | 268 | // 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 | }; |
| 268 | | 276 | |
| 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 | } |
| 278 | | 286 | |
| 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); |
| 861 | | 869 | |
| 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, |