| ... | @@ -26,7 +26,6 @@ const cast = std.math.cast; | ... | @@ -26,7 +26,6 @@ const cast = std.math.cast; |
| 26 | const maxInt = std.math.maxInt; | 26 | const maxInt = std.math.maxInt; |
| 27 | const MemoryAccessor = std.debug.MemoryAccessor; | 27 | const MemoryAccessor = std.debug.MemoryAccessor; |
| 28 | const Path = std.Build.Cache.Path; | 28 | const Path = std.Build.Cache.Path; |
| 29 | | | |
| 30 | const FixedBufferReader = std.debug.FixedBufferReader; | 29 | const FixedBufferReader = std.debug.FixedBufferReader; |
| 31 | | 30 | |
| 32 | const Dwarf = @This(); | 31 | const Dwarf = @This(); |
| ... | @@ -35,22 +34,36 @@ pub const expression = @import("Dwarf/expression.zig"); | ... | @@ -35,22 +34,36 @@ pub const expression = @import("Dwarf/expression.zig"); |
| 35 | pub const abi = @import("Dwarf/abi.zig"); | 34 | pub const abi = @import("Dwarf/abi.zig"); |
| 36 | pub const call_frame = @import("Dwarf/call_frame.zig"); | 35 | pub const call_frame = @import("Dwarf/call_frame.zig"); |
| 37 | | 36 | |
| | 37 | /// Useful to temporarily enable while working on this file. |
| | 38 | const debug_debug_mode = false; |
| | 39 | |
| 38 | endian: std.builtin.Endian, | 40 | endian: std.builtin.Endian, |
| 39 | sections: SectionArray = null_section_array, | 41 | sections: SectionArray = null_section_array, |
| 40 | is_macho: bool, | 42 | is_macho: bool, |
| 41 | compile_units_sorted: bool, | | |
| 42 | | 43 | |
| 43 | // Filled later by the initializer | 44 | /// Filled later by the initializer |
| 44 | abbrev_table_list: std.ArrayListUnmanaged(Abbrev.Table) = .{}, | 45 | abbrev_table_list: std.ArrayListUnmanaged(Abbrev.Table) = .{}, |
| | 46 | /// Filled later by the initializer |
| 45 | compile_unit_list: std.ArrayListUnmanaged(CompileUnit) = .{}, | 47 | compile_unit_list: std.ArrayListUnmanaged(CompileUnit) = .{}, |
| | 48 | /// Filled later by the initializer |
| 46 | func_list: std.ArrayListUnmanaged(Func) = .{}, | 49 | func_list: std.ArrayListUnmanaged(Func) = .{}, |
| 47 | | 50 | |
| 48 | eh_frame_hdr: ?ExceptionFrameHeader = null, | 51 | eh_frame_hdr: ?ExceptionFrameHeader = null, |
| 49 | // These lookup tables are only used if `eh_frame_hdr` is null | 52 | /// These lookup tables are only used if `eh_frame_hdr` is null |
| 50 | cie_map: std.AutoArrayHashMapUnmanaged(u64, CommonInformationEntry) = .{}, | 53 | cie_map: std.AutoArrayHashMapUnmanaged(u64, CommonInformationEntry) = .{}, |
| 51 | // Sorted by start_pc | 54 | /// Sorted by start_pc |
| 52 | fde_list: std.ArrayListUnmanaged(FrameDescriptionEntry) = .{}, | 55 | fde_list: std.ArrayListUnmanaged(FrameDescriptionEntry) = .{}, |
| 53 | | 56 | |
| | 57 | /// Populated by `populateRanges`. |
| | 58 | ranges: std.ArrayListUnmanaged(Range) = .{}, |
| | 59 | |
| | 60 | pub const Range = struct { |
| | 61 | start: u64, |
| | 62 | end: u64, |
| | 63 | /// Index into `compile_unit_list`. |
| | 64 | compile_unit_index: usize, |
| | 65 | }; |
| | 66 | |
| 54 | pub const Section = struct { | 67 | pub const Section = struct { |
| 55 | data: []const u8, | 68 | data: []const u8, |
| 56 | // Module-relative virtual address. | 69 | // Module-relative virtual address. |
| ... | @@ -154,6 +167,16 @@ pub const CompileUnit = struct { | ... | @@ -154,6 +167,16 @@ pub const CompileUnit = struct { |
| 154 | column: u32, | 167 | column: u32, |
| 155 | /// Offset by 1 depending on whether Dwarf version is >= 5. | 168 | /// Offset by 1 depending on whether Dwarf version is >= 5. |
| 156 | file: u32, | 169 | file: u32, |
| | 170 | |
| | 171 | pub const invalid: LineEntry = .{ |
| | 172 | .line = undefined, |
| | 173 | .column = undefined, |
| | 174 | .file = std.math.maxInt(u32), |
| | 175 | }; |
| | 176 | |
| | 177 | pub fn isInvalid(le: LineEntry) bool { |
| | 178 | return le.file == invalid.file; |
| | 179 | } |
| 157 | }; | 180 | }; |
| 158 | | 181 | |
| 159 | pub fn findSource(slc: *const SrcLocCache, address: u64) !LineEntry { | 182 | pub fn findSource(slc: *const SrcLocCache, address: u64) !LineEntry { |
| ... | @@ -799,6 +822,7 @@ pub fn deinit(di: *Dwarf, gpa: Allocator) void { | ... | @@ -799,6 +822,7 @@ pub fn deinit(di: *Dwarf, gpa: Allocator) void { |
| 799 | di.func_list.deinit(gpa); | 822 | di.func_list.deinit(gpa); |
| 800 | di.cie_map.deinit(gpa); | 823 | di.cie_map.deinit(gpa); |
| 801 | di.fde_list.deinit(gpa); | 824 | di.fde_list.deinit(gpa); |
| | 825 | di.ranges.deinit(gpa); |
| 802 | di.* = undefined; | 826 | di.* = undefined; |
| 803 | } | 827 | } |
| 804 | | 828 | |
| ... | @@ -985,8 +1009,8 @@ fn scanAllFunctions(di: *Dwarf, allocator: Allocator) ScanError!void { | ... | @@ -985,8 +1009,8 @@ fn scanAllFunctions(di: *Dwarf, allocator: Allocator) ScanError!void { |
| 985 | try di.func_list.append(allocator, .{ | 1009 | try di.func_list.append(allocator, .{ |
| 986 | .name = fn_name, | 1010 | .name = fn_name, |
| 987 | .pc_range = .{ | 1011 | .pc_range = .{ |
| 988 | .start = range.start_addr, | 1012 | .start = range.start, |
| 989 | .end = range.end_addr, | 1013 | .end = range.end, |
| 990 | }, | 1014 | }, |
| 991 | }); | 1015 | }); |
| 992 | } | 1016 | } |
| ... | @@ -1096,37 +1120,38 @@ fn scanAllCompileUnits(di: *Dwarf, allocator: Allocator) ScanError!void { | ... | @@ -1096,37 +1120,38 @@ fn scanAllCompileUnits(di: *Dwarf, allocator: Allocator) ScanError!void { |
| 1096 | } | 1120 | } |
| 1097 | } | 1121 | } |
| 1098 | | 1122 | |
| 1099 | /// Populate missing PC ranges in compilation units, and then sort them by start address. | 1123 | pub fn populateRanges(d: *Dwarf, gpa: Allocator) ScanError!void { |
| 1100 | /// Does not guarantee pc_range to be non-null because there could be missing debug info. | 1124 | assert(d.ranges.items.len == 0); |
| 1101 | pub fn sortCompileUnits(d: *Dwarf) ScanError!void { | | |
| 1102 | assert(!d.compile_units_sorted); | | |
| 1103 | | 1125 | |
| 1104 | for (d.compile_unit_list.items) |*cu| { | 1126 | for (d.compile_unit_list.items, 0..) |*cu, cu_index| { |
| 1105 | if (cu.pc_range != null) continue; | 1127 | if (cu.pc_range) |range| { |
| | 1128 | try d.ranges.append(gpa, .{ |
| | 1129 | .start = range.start, |
| | 1130 | .end = range.end, |
| | 1131 | .compile_unit_index = cu_index, |
| | 1132 | }); |
| | 1133 | continue; |
| | 1134 | } |
| 1106 | const ranges_value = cu.die.getAttr(AT.ranges) orelse continue; | 1135 | const ranges_value = cu.die.getAttr(AT.ranges) orelse continue; |
| 1107 | var iter = DebugRangeIterator.init(ranges_value, d, cu) catch continue; | 1136 | var iter = DebugRangeIterator.init(ranges_value, d, cu) catch continue; |
| 1108 | var start: u64 = maxInt(u64); | | |
| 1109 | var end: u64 = 0; | | |
| 1110 | while (try iter.next()) |range| { | 1137 | while (try iter.next()) |range| { |
| 1111 | start = @min(start, range.start_addr); | 1138 | // Not sure why LLVM thinks it's OK to emit these... |
| 1112 | end = @max(end, range.end_addr); | 1139 | if (range.start == range.end) continue; |
| | 1140 | |
| | 1141 | try d.ranges.append(gpa, .{ |
| | 1142 | .start = range.start, |
| | 1143 | .end = range.end, |
| | 1144 | .compile_unit_index = cu_index, |
| | 1145 | }); |
| 1113 | } | 1146 | } |
| 1114 | if (end != 0) cu.pc_range = .{ | | |
| 1115 | .start = start, | | |
| 1116 | .end = end, | | |
| 1117 | }; | | |
| 1118 | } | 1147 | } |
| 1119 | | 1148 | |
| 1120 | std.mem.sortUnstable(CompileUnit, d.compile_unit_list.items, {}, struct { | 1149 | std.mem.sortUnstable(Range, d.ranges.items, {}, struct { |
| 1121 | pub fn lessThan(ctx: void, a: CompileUnit, b: CompileUnit) bool { | 1150 | pub fn lessThan(ctx: void, a: Range, b: Range) bool { |
| 1122 | _ = ctx; | 1151 | _ = ctx; |
| 1123 | const a_range = a.pc_range orelse return false; | 1152 | return a.start < b.start; |
| 1124 | const b_range = b.pc_range orelse return true; | | |
| 1125 | return a_range.start < b_range.start; | | |
| 1126 | } | 1153 | } |
| 1127 | }.lessThan); | 1154 | }.lessThan); |
| 1128 | | | |
| 1129 | d.compile_units_sorted = true; | | |
| 1130 | } | 1155 | } |
| 1131 | | 1156 | |
| 1132 | const DebugRangeIterator = struct { | 1157 | const DebugRangeIterator = struct { |
| ... | @@ -1184,7 +1209,7 @@ const DebugRangeIterator = struct { | ... | @@ -1184,7 +1209,7 @@ const DebugRangeIterator = struct { |
| 1184 | } | 1209 | } |
| 1185 | | 1210 | |
| 1186 | // Returns the next range in the list, or null if the end was reached. | 1211 | // Returns the next range in the list, or null if the end was reached. |
| 1187 | pub fn next(self: *@This()) !?struct { start_addr: u64, end_addr: u64 } { | 1212 | pub fn next(self: *@This()) !?PcRange { |
| 1188 | switch (self.section_type) { | 1213 | switch (self.section_type) { |
| 1189 | .debug_rnglists => { | 1214 | .debug_rnglists => { |
| 1190 | const kind = try self.fbr.readByte(); | 1215 | const kind = try self.fbr.readByte(); |
| ... | @@ -1203,8 +1228,8 @@ const DebugRangeIterator = struct { | ... | @@ -1203,8 +1228,8 @@ const DebugRangeIterator = struct { |
| 1203 | const end_addr = try self.di.readDebugAddr(self.compile_unit.*, end_index); | 1228 | const end_addr = try self.di.readDebugAddr(self.compile_unit.*, end_index); |
| 1204 | | 1229 | |
| 1205 | return .{ | 1230 | return .{ |
| 1206 | .start_addr = start_addr, | 1231 | .start = start_addr, |
| 1207 | .end_addr = end_addr, | 1232 | .end = end_addr, |
| 1208 | }; | 1233 | }; |
| 1209 | }, | 1234 | }, |
| 1210 | RLE.startx_length => { | 1235 | RLE.startx_length => { |
| ... | @@ -1215,8 +1240,8 @@ const DebugRangeIterator = struct { | ... | @@ -1215,8 +1240,8 @@ const DebugRangeIterator = struct { |
| 1215 | const end_addr = start_addr + len; | 1240 | const end_addr = start_addr + len; |
| 1216 | | 1241 | |
| 1217 | return .{ | 1242 | return .{ |
| 1218 | .start_addr = start_addr, | 1243 | .start = start_addr, |
| 1219 | .end_addr = end_addr, | 1244 | .end = end_addr, |
| 1220 | }; | 1245 | }; |
| 1221 | }, | 1246 | }, |
| 1222 | RLE.offset_pair => { | 1247 | RLE.offset_pair => { |
| ... | @@ -1225,8 +1250,8 @@ const DebugRangeIterator = struct { | ... | @@ -1225,8 +1250,8 @@ const DebugRangeIterator = struct { |
| 1225 | | 1250 | |
| 1226 | // This is the only kind that uses the base address | 1251 | // This is the only kind that uses the base address |
| 1227 | return .{ | 1252 | return .{ |
| 1228 | .start_addr = self.base_address + start_addr, | 1253 | .start = self.base_address + start_addr, |
| 1229 | .end_addr = self.base_address + end_addr, | 1254 | .end = self.base_address + end_addr, |
| 1230 | }; | 1255 | }; |
| 1231 | }, | 1256 | }, |
| 1232 | RLE.base_address => { | 1257 | RLE.base_address => { |
| ... | @@ -1238,8 +1263,8 @@ const DebugRangeIterator = struct { | ... | @@ -1238,8 +1263,8 @@ const DebugRangeIterator = struct { |
| 1238 | const end_addr = try self.fbr.readInt(usize); | 1263 | const end_addr = try self.fbr.readInt(usize); |
| 1239 | | 1264 | |
| 1240 | return .{ | 1265 | return .{ |
| 1241 | .start_addr = start_addr, | 1266 | .start = start_addr, |
| 1242 | .end_addr = end_addr, | 1267 | .end = end_addr, |
| 1243 | }; | 1268 | }; |
| 1244 | }, | 1269 | }, |
| 1245 | RLE.start_length => { | 1270 | RLE.start_length => { |
| ... | @@ -1248,8 +1273,8 @@ const DebugRangeIterator = struct { | ... | @@ -1248,8 +1273,8 @@ const DebugRangeIterator = struct { |
| 1248 | const end_addr = start_addr + len; | 1273 | const end_addr = start_addr + len; |
| 1249 | | 1274 | |
| 1250 | return .{ | 1275 | return .{ |
| 1251 | .start_addr = start_addr, | 1276 | .start = start_addr, |
| 1252 | .end_addr = end_addr, | 1277 | .end = end_addr, |
| 1253 | }; | 1278 | }; |
| 1254 | }, | 1279 | }, |
| 1255 | else => return bad(), | 1280 | else => return bad(), |
| ... | @@ -1267,8 +1292,8 @@ const DebugRangeIterator = struct { | ... | @@ -1267,8 +1292,8 @@ const DebugRangeIterator = struct { |
| 1267 | } | 1292 | } |
| 1268 | | 1293 | |
| 1269 | return .{ | 1294 | return .{ |
| 1270 | .start_addr = self.base_address + start_addr, | 1295 | .start = self.base_address + start_addr, |
| 1271 | .end_addr = self.base_address + end_addr, | 1296 | .end = self.base_address + end_addr, |
| 1272 | }; | 1297 | }; |
| 1273 | }, | 1298 | }, |
| 1274 | else => unreachable, | 1299 | else => unreachable, |
| ... | @@ -1286,7 +1311,7 @@ pub fn findCompileUnit(di: *const Dwarf, target_address: u64) !*CompileUnit { | ... | @@ -1286,7 +1311,7 @@ pub fn findCompileUnit(di: *const Dwarf, target_address: u64) !*CompileUnit { |
| 1286 | const ranges_value = compile_unit.die.getAttr(AT.ranges) orelse continue; | 1311 | const ranges_value = compile_unit.die.getAttr(AT.ranges) orelse continue; |
| 1287 | var iter = DebugRangeIterator.init(ranges_value, di, compile_unit) catch continue; | 1312 | var iter = DebugRangeIterator.init(ranges_value, di, compile_unit) catch continue; |
| 1288 | while (try iter.next()) |range| { | 1313 | while (try iter.next()) |range| { |
| 1289 | if (target_address >= range.start_addr and target_address < range.end_addr) return compile_unit; | 1314 | if (target_address >= range.start and target_address < range.end) return compile_unit; |
| 1290 | } | 1315 | } |
| 1291 | } | 1316 | } |
| 1292 | | 1317 | |
| ... | @@ -1387,6 +1412,7 @@ fn parseDie( | ... | @@ -1387,6 +1412,7 @@ fn parseDie( |
| 1387 | }; | 1412 | }; |
| 1388 | } | 1413 | } |
| 1389 | | 1414 | |
| | 1415 | /// Ensures that addresses in the returned LineTable are monotonically increasing. |
| 1390 | fn runLineNumberProgram(d: *Dwarf, gpa: Allocator, compile_unit: *CompileUnit) !CompileUnit.SrcLocCache { | 1416 | fn runLineNumberProgram(d: *Dwarf, gpa: Allocator, compile_unit: *CompileUnit) !CompileUnit.SrcLocCache { |
| 1391 | const compile_unit_cwd = try compile_unit.die.getAttrString(d, AT.comp_dir, d.section(.debug_line_str), compile_unit.*); | 1417 | const compile_unit_cwd = try compile_unit.die.getAttrString(d, AT.comp_dir, d.section(.debug_line_str), compile_unit.*); |
| 1392 | const line_info_offset = try compile_unit.die.getAttrSecOffset(AT.stmt_list); | 1418 | const line_info_offset = try compile_unit.die.getAttrSecOffset(AT.stmt_list); |
| ... | @@ -1562,8 +1588,19 @@ fn runLineNumberProgram(d: *Dwarf, gpa: Allocator, compile_unit: *CompileUnit) ! | ... | @@ -1562,8 +1588,19 @@ fn runLineNumberProgram(d: *Dwarf, gpa: Allocator, compile_unit: *CompileUnit) ! |
| 1562 | const sub_op = try fbr.readByte(); | 1588 | const sub_op = try fbr.readByte(); |
| 1563 | switch (sub_op) { | 1589 | switch (sub_op) { |
| 1564 | DW.LNE.end_sequence => { | 1590 | DW.LNE.end_sequence => { |
| 1565 | prog.end_sequence = true; | 1591 | // The row being added here is an "end" address, meaning |
| 1566 | try prog.addRow(gpa, &line_table); | 1592 | // that it does not map to the source location here - |
| | 1593 | // rather it marks the previous address as the last address |
| | 1594 | // that maps to this source location. |
| | 1595 | |
| | 1596 | // In this implementation we don't mark end of addresses. |
| | 1597 | // This is a performance optimization based on the fact |
| | 1598 | // that we don't need to know if an address is missing |
| | 1599 | // source location info; we are only interested in being |
| | 1600 | // able to look up source location info for addresses that |
| | 1601 | // are known to have debug info. |
| | 1602 | //if (debug_debug_mode) assert(!line_table.contains(prog.address)); |
| | 1603 | //try line_table.put(gpa, prog.address, CompileUnit.SrcLocCache.LineEntry.invalid); |
| 1567 | prog.reset(); | 1604 | prog.reset(); |
| 1568 | }, | 1605 | }, |
| 1569 | DW.LNE.set_address => { | 1606 | DW.LNE.set_address => { |
| ... | @@ -1638,6 +1675,17 @@ fn runLineNumberProgram(d: *Dwarf, gpa: Allocator, compile_unit: *CompileUnit) ! | ... | @@ -1638,6 +1675,17 @@ fn runLineNumberProgram(d: *Dwarf, gpa: Allocator, compile_unit: *CompileUnit) ! |
| 1638 | } | 1675 | } |
| 1639 | } | 1676 | } |
| 1640 | | 1677 | |
| | 1678 | // Dwarf standard v5, 6.2.5 says |
| | 1679 | // > Within a sequence, addresses and operation pointers may only increase. |
| | 1680 | // However, this is empirically not the case in reality, so we sort here. |
| | 1681 | line_table.sortUnstable(struct { |
| | 1682 | keys: []const u64, |
| | 1683 | |
| | 1684 | pub fn lessThan(ctx: @This(), a_index: usize, b_index: usize) bool { |
| | 1685 | return ctx.keys[a_index] < ctx.keys[b_index]; |
| | 1686 | } |
| | 1687 | }{ .keys = line_table.keys() }); |
| | 1688 | |
| 1641 | return .{ | 1689 | return .{ |
| 1642 | .line_table = line_table, | 1690 | .line_table = line_table, |
| 1643 | .directories = try directories.toOwnedSlice(gpa), | 1691 | .directories = try directories.toOwnedSlice(gpa), |
| ... | @@ -1882,7 +1930,6 @@ const LineNumberProgram = struct { | ... | @@ -1882,7 +1930,6 @@ const LineNumberProgram = struct { |
| 1882 | version: u16, | 1930 | version: u16, |
| 1883 | is_stmt: bool, | 1931 | is_stmt: bool, |
| 1884 | basic_block: bool, | 1932 | basic_block: bool, |
| 1885 | end_sequence: bool, | | |
| 1886 | | 1933 | |
| 1887 | default_is_stmt: bool, | 1934 | default_is_stmt: bool, |
| 1888 | | 1935 | |
| ... | @@ -1894,7 +1941,6 @@ const LineNumberProgram = struct { | ... | @@ -1894,7 +1941,6 @@ const LineNumberProgram = struct { |
| 1894 | self.column = 0; | 1941 | self.column = 0; |
| 1895 | self.is_stmt = self.default_is_stmt; | 1942 | self.is_stmt = self.default_is_stmt; |
| 1896 | self.basic_block = false; | 1943 | self.basic_block = false; |
| 1897 | self.end_sequence = false; | | |
| 1898 | } | 1944 | } |
| 1899 | | 1945 | |
| 1900 | pub fn init(is_stmt: bool, version: u16) LineNumberProgram { | 1946 | pub fn init(is_stmt: bool, version: u16) LineNumberProgram { |
| ... | @@ -1906,13 +1952,16 @@ const LineNumberProgram = struct { | ... | @@ -1906,13 +1952,16 @@ const LineNumberProgram = struct { |
| 1906 | .version = version, | 1952 | .version = version, |
| 1907 | .is_stmt = is_stmt, | 1953 | .is_stmt = is_stmt, |
| 1908 | .basic_block = false, | 1954 | .basic_block = false, |
| 1909 | .end_sequence = false, | | |
| 1910 | .default_is_stmt = is_stmt, | 1955 | .default_is_stmt = is_stmt, |
| 1911 | }; | 1956 | }; |
| 1912 | } | 1957 | } |
| 1913 | | 1958 | |
| 1914 | pub fn addRow(prog: *LineNumberProgram, gpa: Allocator, table: *CompileUnit.SrcLocCache.LineTable) !void { | 1959 | pub fn addRow(prog: *LineNumberProgram, gpa: Allocator, table: *CompileUnit.SrcLocCache.LineTable) !void { |
| 1915 | if (prog.line == 0) return; // garbage data | 1960 | if (prog.line == 0) { |
| | 1961 | //if (debug_debug_mode) @panic("garbage line data"); |
| | 1962 | return; |
| | 1963 | } |
| | 1964 | if (debug_debug_mode) assert(!table.contains(prog.address)); |
| 1916 | try table.put(gpa, prog.address, .{ | 1965 | try table.put(gpa, prog.address, .{ |
| 1917 | .line = cast(u32, prog.line) orelse maxInt(u32), | 1966 | .line = cast(u32, prog.line) orelse maxInt(u32), |
| 1918 | .column = cast(u32, prog.column) orelse maxInt(u32), | 1967 | .column = cast(u32, prog.column) orelse maxInt(u32), |
| ... | @@ -1959,12 +2008,12 @@ pub fn compactUnwindToDwarfRegNumber(unwind_reg_number: u3) !u8 { | ... | @@ -1959,12 +2008,12 @@ pub fn compactUnwindToDwarfRegNumber(unwind_reg_number: u3) !u8 { |
| 1959 | /// This function is to make it handy to comment out the return and make it | 2008 | /// This function is to make it handy to comment out the return and make it |
| 1960 | /// into a crash when working on this file. | 2009 | /// into a crash when working on this file. |
| 1961 | pub fn bad() error{InvalidDebugInfo} { | 2010 | pub fn bad() error{InvalidDebugInfo} { |
| 1962 | //if (true) @panic("bad dwarf"); // can be handy to uncomment when working on this file | 2011 | if (debug_debug_mode) @panic("bad dwarf"); |
| 1963 | return error.InvalidDebugInfo; | 2012 | return error.InvalidDebugInfo; |
| 1964 | } | 2013 | } |
| 1965 | | 2014 | |
| 1966 | fn missing() error{MissingDebugInfo} { | 2015 | fn missing() error{MissingDebugInfo} { |
| 1967 | //if (true) @panic("missing dwarf"); // can be handy to uncomment when working on this file | 2016 | if (debug_debug_mode) @panic("missing dwarf"); |
| 1968 | return error.MissingDebugInfo; | 2017 | return error.MissingDebugInfo; |
| 1969 | } | 2018 | } |
| 1970 | | 2019 | |
| ... | @@ -2345,7 +2394,6 @@ pub const ElfModule = struct { | ... | @@ -2345,7 +2394,6 @@ pub const ElfModule = struct { |
| 2345 | .endian = endian, | 2394 | .endian = endian, |
| 2346 | .sections = sections, | 2395 | .sections = sections, |
| 2347 | .is_macho = false, | 2396 | .is_macho = false, |
| 2348 | .compile_units_sorted = false, | | |
| 2349 | }; | 2397 | }; |
| 2350 | | 2398 | |
| 2351 | try Dwarf.open(&di, gpa); | 2399 | try Dwarf.open(&di, gpa); |