| ... | @@ -968,24 +968,20 @@ fn readMachODebugInfo(allocator: mem.Allocator, macho_file: File) !ModuleDebugIn | ... | @@ -968,24 +968,20 @@ fn readMachODebugInfo(allocator: mem.Allocator, macho_file: File) !ModuleDebugIn |
| 968 | if (hdr.magic != macho.MH_MAGIC_64) | 968 | if (hdr.magic != macho.MH_MAGIC_64) |
| 969 | return error.InvalidDebugInfo; | 969 | return error.InvalidDebugInfo; |
| 970 | | 970 | |
| 971 | const hdr_base = @ptrCast([*]const u8, hdr); | 971 | var it = macho.LoadCommandIterator{ |
| 972 | var ptr = hdr_base + @sizeOf(macho.mach_header_64); | 972 | .ncmds = hdr.ncmds, |
| 973 | var ncmd: u32 = hdr.ncmds; | 973 | .buffer = mapped_mem[@sizeOf(macho.mach_header_64)..][0..hdr.sizeofcmds], |
| 974 | const symtab = while (ncmd != 0) : (ncmd -= 1) { | | |
| 975 | const lc = @ptrCast(*const std.macho.load_command, ptr); | | |
| 976 | switch (lc.cmd) { | | |
| 977 | .SYMTAB => break @ptrCast(*const std.macho.symtab_command, ptr), | | |
| 978 | else => {}, | | |
| 979 | } | | |
| 980 | ptr = @alignCast(@alignOf(std.macho.load_command), ptr + lc.cmdsize); | | |
| 981 | } else { | | |
| 982 | return error.MissingDebugInfo; | | |
| 983 | }; | 974 | }; |
| | 975 | const symtab = while (it.next()) |cmd| switch (cmd.cmd()) { |
| | 976 | .SYMTAB => break cmd.cast(macho.symtab_command).?, |
| | 977 | else => {}, |
| | 978 | } else return error.MissingDebugInfo; |
| | 979 | |
| 984 | const syms = @ptrCast( | 980 | const syms = @ptrCast( |
| 985 | [*]const macho.nlist_64, | 981 | [*]const macho.nlist_64, |
| 986 | @alignCast(@alignOf(macho.nlist_64), hdr_base + symtab.symoff), | 982 | @alignCast(@alignOf(macho.nlist_64), &mapped_mem[symtab.symoff]), |
| 987 | )[0..symtab.nsyms]; | 983 | )[0..symtab.nsyms]; |
| 988 | const strings = @ptrCast([*]const u8, hdr_base + symtab.stroff)[0 .. symtab.strsize - 1 :0]; | 984 | const strings = mapped_mem[symtab.stroff..][0 .. symtab.strsize - 1 :0]; |
| 989 | | 985 | |
| 990 | const symbols_buf = try allocator.alloc(MachoSymbol, syms.len); | 986 | const symbols_buf = try allocator.alloc(MachoSymbol, syms.len); |
| 991 | | 987 | |
| ... | @@ -1200,48 +1196,46 @@ pub const DebugInfo = struct { | ... | @@ -1200,48 +1196,46 @@ pub const DebugInfo = struct { |
| 1200 | if (address < base_address) continue; | 1196 | if (address < base_address) continue; |
| 1201 | | 1197 | |
| 1202 | const header = std.c._dyld_get_image_header(i) orelse continue; | 1198 | const header = std.c._dyld_get_image_header(i) orelse continue; |
| 1203 | // The array of load commands is right after the header | | |
| 1204 | var cmd_ptr = @intToPtr([*]u8, @ptrToInt(header) + @sizeOf(macho.mach_header_64)); | | |
| 1205 | | | |
| 1206 | var cmds = header.ncmds; | | |
| 1207 | while (cmds != 0) : (cmds -= 1) { | | |
| 1208 | const lc = @ptrCast( | | |
| 1209 | *macho.load_command, | | |
| 1210 | @alignCast(@alignOf(macho.load_command), cmd_ptr), | | |
| 1211 | ); | | |
| 1212 | cmd_ptr += lc.cmdsize; | | |
| 1213 | if (lc.cmd != .SEGMENT_64) continue; | | |
| 1214 | | 1199 | |
| 1215 | const segment_cmd = @ptrCast( | 1200 | var it = macho.LoadCommandIterator{ |
| 1216 | *const std.macho.segment_command_64, | 1201 | .ncmds = header.ncmds, |
| 1217 | @alignCast(@alignOf(std.macho.segment_command_64), lc), | 1202 | .buffer = @alignCast(@alignOf(u64), @intToPtr( |
| 1218 | ); | 1203 | [*]u8, |
| | 1204 | @ptrToInt(header) + @sizeOf(macho.mach_header_64), |
| | 1205 | ))[0..header.sizeofcmds], |
| | 1206 | }; |
| | 1207 | while (it.next()) |cmd| switch (cmd.cmd()) { |
| | 1208 | .SEGMENT_64 => { |
| | 1209 | const segment_cmd = cmd.cast(macho.segment_command_64).?; |
| | 1210 | const rebased_address = address - base_address; |
| | 1211 | const seg_start = segment_cmd.vmaddr; |
| | 1212 | const seg_end = seg_start + segment_cmd.vmsize; |
| | 1213 | |
| | 1214 | if (rebased_address >= seg_start and rebased_address < seg_end) { |
| | 1215 | if (self.address_map.get(base_address)) |obj_di| { |
| | 1216 | return obj_di; |
| | 1217 | } |
| | 1218 | |
| | 1219 | const obj_di = try self.allocator.create(ModuleDebugInfo); |
| | 1220 | errdefer self.allocator.destroy(obj_di); |
| | 1221 | |
| | 1222 | const macho_path = mem.sliceTo(std.c._dyld_get_image_name(i), 0); |
| | 1223 | const macho_file = fs.cwd().openFile(macho_path, .{ |
| | 1224 | .intended_io_mode = .blocking, |
| | 1225 | }) catch |err| switch (err) { |
| | 1226 | error.FileNotFound => return error.MissingDebugInfo, |
| | 1227 | else => return err, |
| | 1228 | }; |
| | 1229 | obj_di.* = try readMachODebugInfo(self.allocator, macho_file); |
| | 1230 | obj_di.base_address = base_address; |
| 1219 | | 1231 | |
| 1220 | const rebased_address = address - base_address; | 1232 | try self.address_map.putNoClobber(base_address, obj_di); |
| 1221 | const seg_start = segment_cmd.vmaddr; | | |
| 1222 | const seg_end = seg_start + segment_cmd.vmsize; | | |
| 1223 | | 1233 | |
| 1224 | if (rebased_address >= seg_start and rebased_address < seg_end) { | | |
| 1225 | if (self.address_map.get(base_address)) |obj_di| { | | |
| 1226 | return obj_di; | 1234 | return obj_di; |
| 1227 | } | 1235 | } |
| 1228 | | 1236 | }, |
| 1229 | const obj_di = try self.allocator.create(ModuleDebugInfo); | 1237 | else => {}, |
| 1230 | errdefer self.allocator.destroy(obj_di); | 1238 | }; |
| 1231 | | | |
| 1232 | const macho_path = mem.sliceTo(std.c._dyld_get_image_name(i), 0); | | |
| 1233 | const macho_file = fs.cwd().openFile(macho_path, .{ .intended_io_mode = .blocking }) catch |err| switch (err) { | | |
| 1234 | error.FileNotFound => return error.MissingDebugInfo, | | |
| 1235 | else => return err, | | |
| 1236 | }; | | |
| 1237 | obj_di.* = try readMachODebugInfo(self.allocator, macho_file); | | |
| 1238 | obj_di.base_address = base_address; | | |
| 1239 | | | |
| 1240 | try self.address_map.putNoClobber(base_address, obj_di); | | |
| 1241 | | | |
| 1242 | return obj_di; | | |
| 1243 | } | | |
| 1244 | } | | |
| 1245 | } | 1239 | } |
| 1246 | | 1240 | |
| 1247 | return error.MissingDebugInfo; | 1241 | return error.MissingDebugInfo; |
| ... | @@ -1445,44 +1439,31 @@ pub const ModuleDebugInfo = switch (native_os) { | ... | @@ -1445,44 +1439,31 @@ pub const ModuleDebugInfo = switch (native_os) { |
| 1445 | if (hdr.magic != std.macho.MH_MAGIC_64) | 1439 | if (hdr.magic != std.macho.MH_MAGIC_64) |
| 1446 | return error.InvalidDebugInfo; | 1440 | return error.InvalidDebugInfo; |
| 1447 | | 1441 | |
| 1448 | const hdr_base = @ptrCast([*]const u8, hdr); | 1442 | var segcmd: ?macho.LoadCommandIterator.LoadCommand = null; |
| 1449 | var ptr = hdr_base + @sizeOf(macho.mach_header_64); | 1443 | var symtabcmd: ?macho.symtab_command = null; |
| 1450 | var segptr = ptr; | 1444 | var it = macho.LoadCommandIterator{ |
| 1451 | var ncmd: u32 = hdr.ncmds; | 1445 | .ncmds = hdr.ncmds, |
| 1452 | var segcmd: ?*const macho.segment_command_64 = null; | 1446 | .buffer = mapped_mem[@sizeOf(macho.mach_header_64)..][0..hdr.sizeofcmds], |
| 1453 | var symtabcmd: ?*const macho.symtab_command = null; | 1447 | }; |
| 1454 | | 1448 | while (it.next()) |cmd| switch (cmd.cmd()) { |
| 1455 | while (ncmd != 0) : (ncmd -= 1) { | 1449 | .SEGMENT_64 => segcmd = cmd, |
| 1456 | const lc = @ptrCast(*const std.macho.load_command, ptr); | 1450 | .SYMTAB => symtabcmd = cmd.cast(macho.symtab_command).?, |
| 1457 | switch (lc.cmd) { | 1451 | else => {}, |
| 1458 | .SEGMENT_64 => { | 1452 | }; |
| 1459 | segcmd = @ptrCast( | | |
| 1460 | *const std.macho.segment_command_64, | | |
| 1461 | @alignCast(@alignOf(std.macho.segment_command_64), ptr), | | |
| 1462 | ); | | |
| 1463 | segptr = ptr; | | |
| 1464 | }, | | |
| 1465 | .SYMTAB => { | | |
| 1466 | symtabcmd = @ptrCast( | | |
| 1467 | *const std.macho.symtab_command, | | |
| 1468 | @alignCast(@alignOf(std.macho.symtab_command), ptr), | | |
| 1469 | ); | | |
| 1470 | }, | | |
| 1471 | else => {}, | | |
| 1472 | } | | |
| 1473 | ptr = @alignCast(@alignOf(std.macho.load_command), ptr + lc.cmdsize); | | |
| 1474 | } | | |
| 1475 | | 1453 | |
| 1476 | if (segcmd == null or symtabcmd == null) return error.MissingDebugInfo; | 1454 | if (segcmd == null or symtabcmd == null) return error.MissingDebugInfo; |
| 1477 | | 1455 | |
| 1478 | // Parse symbols | 1456 | // Parse symbols |
| 1479 | const strtab = @ptrCast( | 1457 | const strtab = @ptrCast( |
| 1480 | [*]const u8, | 1458 | [*]const u8, |
| 1481 | hdr_base + symtabcmd.?.stroff, | 1459 | &mapped_mem[symtabcmd.?.stroff], |
| 1482 | )[0 .. symtabcmd.?.strsize - 1 :0]; | 1460 | )[0 .. symtabcmd.?.strsize - 1 :0]; |
| 1483 | const symtab = @ptrCast( | 1461 | const symtab = @ptrCast( |
| 1484 | [*]const macho.nlist_64, | 1462 | [*]const macho.nlist_64, |
| 1485 | @alignCast(@alignOf(macho.nlist_64), hdr_base + symtabcmd.?.symoff), | 1463 | @alignCast( |
| | 1464 | @alignOf(macho.nlist_64), |
| | 1465 | &mapped_mem[symtabcmd.?.symoff], |
| | 1466 | ), |
| 1486 | )[0..symtabcmd.?.nsyms]; | 1467 | )[0..symtabcmd.?.nsyms]; |
| 1487 | | 1468 | |
| 1488 | // TODO handle tentative (common) symbols | 1469 | // TODO handle tentative (common) symbols |
| ... | @@ -1496,25 +1477,15 @@ pub const ModuleDebugInfo = switch (native_os) { | ... | @@ -1496,25 +1477,15 @@ pub const ModuleDebugInfo = switch (native_os) { |
| 1496 | addr_table.putAssumeCapacityNoClobber(sym_name, sym.n_value); | 1477 | addr_table.putAssumeCapacityNoClobber(sym_name, sym.n_value); |
| 1497 | } | 1478 | } |
| 1498 | | 1479 | |
| 1499 | var opt_debug_line: ?*const macho.section_64 = null; | 1480 | var opt_debug_line: ?macho.section_64 = null; |
| 1500 | var opt_debug_info: ?*const macho.section_64 = null; | 1481 | var opt_debug_info: ?macho.section_64 = null; |
| 1501 | var opt_debug_abbrev: ?*const macho.section_64 = null; | 1482 | var opt_debug_abbrev: ?macho.section_64 = null; |
| 1502 | var opt_debug_str: ?*const macho.section_64 = null; | 1483 | var opt_debug_str: ?macho.section_64 = null; |
| 1503 | var opt_debug_line_str: ?*const macho.section_64 = null; | 1484 | var opt_debug_line_str: ?macho.section_64 = null; |
| 1504 | var opt_debug_ranges: ?*const macho.section_64 = null; | 1485 | var opt_debug_ranges: ?macho.section_64 = null; |
| 1505 | | | |
| 1506 | const sections = @ptrCast( | | |
| 1507 | [*]const macho.section_64, | | |
| 1508 | @alignCast(@alignOf(macho.section_64), segptr + @sizeOf(std.macho.segment_command_64)), | | |
| 1509 | )[0..segcmd.?.nsects]; | | |
| 1510 | for (sections) |*sect| { | | |
| 1511 | // The section name may not exceed 16 chars and a trailing null may | | |
| 1512 | // not be present | | |
| 1513 | const name = if (mem.indexOfScalar(u8, sect.sectname[0..], 0)) |last| | | |
| 1514 | sect.sectname[0..last] | | |
| 1515 | else | | |
| 1516 | sect.sectname[0..]; | | |
| 1517 | | 1486 | |
| | 1487 | for (segcmd.?.getSections()) |sect| { |
| | 1488 | const name = sect.sectName(); |
| 1518 | if (mem.eql(u8, name, "__debug_line")) { | 1489 | if (mem.eql(u8, name, "__debug_line")) { |
| 1519 | opt_debug_line = sect; | 1490 | opt_debug_line = sect; |
| 1520 | } else if (mem.eql(u8, name, "__debug_info")) { | 1491 | } else if (mem.eql(u8, name, "__debug_info")) { |