| author | |
| committer | |
| log | 8a6de78e0787015153707361a58659834d4c39c2 |
| tree | 18fb97ac91195813754f80506807db4a22923baa |
| parent | e13a182990c638bb69cd04e253ad6e0ecd734407 |
| parent | 24b1a0027fc663cbb648c265ba19067b108d0dcb |
| signature |
Dwarf on windows4 files changed, 156 insertions(+), 51 deletions(-)
lib/std/Progress.zig+15-5| ... | ... | @@ -22,6 +22,10 @@ const Progress = @This(); |
| 22 | 22 | /// not print on update() |
| 23 | 23 | terminal: ?std.fs.File = undefined, |
| 24 | 24 | |
| 25 | /// Is this a windows API terminal (note: this is not the same as being run on windows | |
| 26 | /// because other terminals exist like MSYS/git-bash) | |
| 27 | is_windows_terminal: bool = false, | |
| 28 | ||
| 25 | 29 | /// Whether the terminal supports ANSI escape codes. |
| 26 | 30 | supports_ansi_escape_codes: bool = false, |
| 27 | 31 | |
| ... | ... | @@ -143,6 +147,7 @@ pub fn start(self: *Progress, name: []const u8, estimated_total_items: usize) !* |
| 143 | 147 | self.terminal = stderr; |
| 144 | 148 | self.supports_ansi_escape_codes = true; |
| 145 | 149 | } else if (std.builtin.os.tag == .windows and stderr.isTty()) { |
| 150 | self.is_windows_terminal = true; | |
| 146 | 151 | self.terminal = stderr; |
| 147 | 152 | } else if (std.builtin.os.tag != .windows) { |
| 148 | 153 | // we are in a "dumb" terminal like in acme or writing to a file |
| ... | ... | @@ -192,8 +197,9 @@ const DECRC = "\x1b8"; |
| 192 | 197 | // supported by some terminals (eg. Terminal.app). |
| 193 | 198 | |
| 194 | 199 | fn refreshWithHeldLock(self: *Progress) void { |
| 195 | const is_dumb = !self.supports_ansi_escape_codes and !(std.builtin.os.tag == .windows); | |
| 200 | const is_dumb = !self.supports_ansi_escape_codes and !self.is_windows_terminal; | |
| 196 | 201 | if (is_dumb and self.dont_print_on_dumb) return; |
| 202 | ||
| 197 | 203 | const file = self.terminal orelse return; |
| 198 | 204 | |
| 199 | 205 | var end: usize = 0; |
| ... | ... | @@ -206,6 +212,8 @@ fn refreshWithHeldLock(self: *Progress) void { |
| 206 | 212 | std.mem.copy(u8, self.output_buffer[end..], seq_before); |
| 207 | 213 | end += seq_before.len; |
| 208 | 214 | } else if (std.builtin.os.tag == .windows) winapi: { |
| 215 | std.debug.assert(self.is_windows_terminal); | |
| 216 | ||
| 209 | 217 | var info: windows.CONSOLE_SCREEN_BUFFER_INFO = undefined; |
| 210 | 218 | if (windows.kernel32.GetConsoleScreenBufferInfo(file.handle, &info) != windows.TRUE) |
| 211 | 219 | unreachable; |
| ... | ... | @@ -282,7 +290,7 @@ fn refreshWithHeldLock(self: *Progress) void { |
| 282 | 290 | const seq_after = DECRC; |
| 283 | 291 | std.mem.copy(u8, self.output_buffer[end..], seq_after); |
| 284 | 292 | end += seq_after.len; |
| 285 | } else if (std.builtin.os.tag != .windows) { | |
| 293 | } else if (!self.is_windows_terminal) { | |
| 286 | 294 | self.output_buffer[end] = '\n'; |
| 287 | 295 | end += 1; |
| 288 | 296 | } |
| ... | ... | @@ -293,8 +301,10 @@ fn refreshWithHeldLock(self: *Progress) void { |
| 293 | 301 | }; |
| 294 | 302 | |
| 295 | 303 | if (std.builtin.os.tag == .windows) { |
| 296 | if (windows.kernel32.SetConsoleCursorPosition(file.handle, saved_cursor_pos) != windows.TRUE) | |
| 297 | unreachable; | |
| 304 | if (self.is_windows_terminal) { | |
| 305 | const res = windows.kernel32.SetConsoleCursorPosition(file.handle, saved_cursor_pos); | |
| 306 | std.debug.assert(res == windows.TRUE); | |
| 307 | } | |
| 298 | 308 | } |
| 299 | 309 | |
| 300 | 310 | self.prev_refresh_timestamp = self.timer.read(); |
| ... | ... | @@ -318,7 +328,7 @@ fn bufWrite(self: *Progress, end: *usize, comptime format: []const u8, args: any |
| 318 | 328 | end.* = self.output_buffer.len; |
| 319 | 329 | }, |
| 320 | 330 | } |
| 321 | const bytes_needed_for_esc_codes_at_end = if (std.builtin.os.tag == .windows) 0 else 11; | |
| 331 | const bytes_needed_for_esc_codes_at_end: u8 = if (self.is_windows_terminal) 0 else 11; | |
| 322 | 332 | const max_end = self.output_buffer.len - bytes_needed_for_esc_codes_at_end; |
| 323 | 333 | if (end.* > max_end) { |
| 324 | 334 | const suffix = "... "; |
lib/std/coff.zig+67-10| ... | ... | @@ -98,6 +98,7 @@ pub const CoffError = error{ |
| 98 | 98 | InvalidPEHeader, |
| 99 | 99 | InvalidMachine, |
| 100 | 100 | MissingCoffSection, |
| 101 | MissingStringTable, | |
| 101 | 102 | }; |
| 102 | 103 | |
| 103 | 104 | // Official documentation of the format: https://docs.microsoft.com/en-us/windows/win32/debug/pe-format |
| ... | ... | @@ -162,20 +163,47 @@ pub const Coff = struct { |
| 162 | 163 | try self.loadOptionalHeader(); |
| 163 | 164 | } |
| 164 | 165 | |
| 166 | fn readStringFromTable(self: *Coff, offset: usize, buf: []u8) ![]const u8 { | |
| 167 | if (self.coff_header.pointer_to_symbol_table == 0) { | |
| 168 | // No symbol table therefore no string table | |
| 169 | return error.MissingStringTable; | |
| 170 | } | |
| 171 | // The string table is at the end of the symbol table and symbols are 18 bytes long | |
| 172 | const string_table_offset = self.coff_header.pointer_to_symbol_table + (self.coff_header.number_of_symbols * 18) + offset; | |
| 173 | const in = self.in_file.reader(); | |
| 174 | const old_pos = try self.in_file.getPos(); | |
| 175 | ||
| 176 | try self.in_file.seekTo(string_table_offset); | |
| 177 | defer { | |
| 178 | self.in_file.seekTo(old_pos) catch unreachable; | |
| 179 | } | |
| 180 | ||
| 181 | const str = try in.readUntilDelimiterOrEof(buf, 0); | |
| 182 | return str orelse ""; | |
| 183 | } | |
| 184 | ||
| 165 | 185 | fn loadOptionalHeader(self: *Coff) !void { |
| 166 | 186 | const in = self.in_file.reader(); |
| 187 | const opt_header_pos = try self.in_file.getPos(); | |
| 188 | ||
| 167 | 189 | self.pe_header.magic = try in.readIntLittle(u16); |
| 168 | // For now we're only interested in finding the reference to the .pdb, | |
| 169 | // so we'll skip most of this header, which size is different in 32 | |
| 170 | // 64 bits by the way. | |
| 171 | var skip_size: u16 = undefined; | |
| 190 | // All we care about is the image base value and PDB info | |
| 191 | // The header structure is different for 32 or 64 bit | |
| 192 | var num_rva_pos: u64 = undefined; | |
| 172 | 193 | if (self.pe_header.magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC) { |
| 173 | skip_size = 2 * @sizeOf(u8) + 8 * @sizeOf(u16) + 18 * @sizeOf(u32); | |
| 194 | num_rva_pos = opt_header_pos + 92; | |
| 195 | ||
| 196 | try self.in_file.seekTo(opt_header_pos + 28); | |
| 197 | const image_base32 = try in.readIntLittle(u32); | |
| 198 | self.pe_header.image_base = image_base32; | |
| 174 | 199 | } else if (self.pe_header.magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC) { |
| 175 | skip_size = 2 * @sizeOf(u8) + 8 * @sizeOf(u16) + 12 * @sizeOf(u32) + 5 * @sizeOf(u64); | |
| 200 | num_rva_pos = opt_header_pos + 108; | |
| 201 | ||
| 202 | try self.in_file.seekTo(opt_header_pos + 24); | |
| 203 | self.pe_header.image_base = try in.readIntLittle(u64); | |
| 176 | 204 | } else return error.InvalidPEMagic; |
| 177 | 205 | |
| 178 | try self.in_file.seekBy(skip_size); | |
| 206 | try self.in_file.seekTo(num_rva_pos); | |
| 179 | 207 | |
| 180 | 208 | const number_of_rva_and_sizes = try in.readIntLittle(u32); |
| 181 | 209 | if (number_of_rva_and_sizes != IMAGE_NUMBEROF_DIRECTORY_ENTRIES) |
| ... | ... | @@ -258,11 +286,23 @@ pub const Coff = struct { |
| 258 | 286 | |
| 259 | 287 | const in = self.in_file.reader(); |
| 260 | 288 | |
| 261 | var name: [8]u8 = undefined; | |
| 289 | var name: [32]u8 = undefined; | |
| 262 | 290 | |
| 263 | 291 | var i: u16 = 0; |
| 264 | 292 | while (i < self.coff_header.number_of_sections) : (i += 1) { |
| 265 | try in.readNoEof(name[0..]); | |
| 293 | try in.readNoEof(name[0..8]); | |
| 294 | ||
| 295 | if (name[0] == '/') { | |
| 296 | // This is a long name and stored in the string table | |
| 297 | const offset_len = mem.indexOfScalar(u8, name[1..], 0) orelse 7; | |
| 298 | ||
| 299 | const str_offset = try std.fmt.parseInt(u32, name[1 .. offset_len + 1], 10); | |
| 300 | const str = try self.readStringFromTable(str_offset, &name); | |
| 301 | std.mem.set(u8, name[str.len..], 0); | |
| 302 | } else { | |
| 303 | std.mem.set(u8, name[8..], 0); | |
| 304 | } | |
| 305 | ||
| 266 | 306 | try self.sections.append(Section{ |
| 267 | 307 | .header = SectionHeader{ |
| 268 | 308 | .name = name, |
| ... | ... | @@ -288,6 +328,22 @@ pub const Coff = struct { |
| 288 | 328 | } |
| 289 | 329 | return null; |
| 290 | 330 | } |
| 331 | ||
| 332 | // Return an owned slice full of the section data | |
| 333 | pub fn getSectionData(self: *Coff, comptime name: []const u8, allocator: *mem.Allocator) ![]u8 { | |
| 334 | const sec = for (self.sections.items) |*sec| { | |
| 335 | if (mem.eql(u8, sec.header.name[0..name.len], name)) { | |
| 336 | break sec; | |
| 337 | } | |
| 338 | } else { | |
| 339 | return error.MissingCoffSection; | |
| 340 | }; | |
| 341 | const in = self.in_file.reader(); | |
| 342 | try self.in_file.seekTo(sec.header.pointer_to_raw_data); | |
| 343 | const out_buff = try allocator.alloc(u8, sec.header.misc.virtual_size); | |
| 344 | try in.readNoEof(out_buff); | |
| 345 | return out_buff; | |
| 346 | } | |
| 291 | 347 | }; |
| 292 | 348 | |
| 293 | 349 | const CoffHeader = struct { |
| ... | ... | @@ -308,6 +364,7 @@ const OptionalHeader = struct { |
| 308 | 364 | |
| 309 | 365 | magic: u16, |
| 310 | 366 | data_directory: [IMAGE_NUMBEROF_DIRECTORY_ENTRIES]DataDirectory, |
| 367 | image_base: u64, | |
| 311 | 368 | }; |
| 312 | 369 | |
| 313 | 370 | const DebugDirectoryEntry = packed struct { |
| ... | ... | @@ -331,7 +388,7 @@ const SectionHeader = struct { |
| 331 | 388 | virtual_size: u32, |
| 332 | 389 | }; |
| 333 | 390 | |
| 334 | name: [8]u8, | |
| 391 | name: [32]u8, | |
| 335 | 392 | misc: Misc, |
| 336 | 393 | virtual_address: u32, |
| 337 | 394 | size_of_raw_data: u32, |
lib/std/debug.zig+69-31| ... | ... | @@ -53,6 +53,10 @@ pub const SymbolInfo = struct { |
| 53 | 53 | } |
| 54 | 54 | } |
| 55 | 55 | }; |
| 56 | const PdbOrDwarf = union(enum) { | |
| 57 | pdb: pdb.Pdb, | |
| 58 | dwarf: DW.DwarfInfo, | |
| 59 | }; | |
| 56 | 60 | |
| 57 | 61 | var stderr_mutex = std.Thread.Mutex{}; |
| 58 | 62 | |
| ... | ... | @@ -669,10 +673,32 @@ fn readCoffDebugInfo(allocator: *mem.Allocator, coff_file: File) !ModuleDebugInf |
| 669 | 673 | var di = ModuleDebugInfo{ |
| 670 | 674 | .base_address = undefined, |
| 671 | 675 | .coff = coff_obj, |
| 672 | .pdb = undefined, | |
| 676 | .debug_data = undefined, | |
| 673 | 677 | }; |
| 674 | 678 | |
| 675 | 679 | try di.coff.loadHeader(); |
| 680 | try di.coff.loadSections(); | |
| 681 | if (di.coff.getSection(".debug_info")) |sec| { | |
| 682 | // This coff file has embedded DWARF debug info | |
| 683 | // TODO: free the section data slices | |
| 684 | const debug_info_data = di.coff.getSectionData(".debug_info", allocator) catch null; | |
| 685 | const debug_abbrev_data = di.coff.getSectionData(".debug_abbrev", allocator) catch null; | |
| 686 | const debug_str_data = di.coff.getSectionData(".debug_str", allocator) catch null; | |
| 687 | const debug_line_data = di.coff.getSectionData(".debug_line", allocator) catch null; | |
| 688 | const debug_ranges_data = di.coff.getSectionData(".debug_ranges", allocator) catch null; | |
| 689 | ||
| 690 | var dwarf = DW.DwarfInfo{ | |
| 691 | .endian = native_endian, | |
| 692 | .debug_info = debug_info_data orelse return error.MissingDebugInfo, | |
| 693 | .debug_abbrev = debug_abbrev_data orelse return error.MissingDebugInfo, | |
| 694 | .debug_str = debug_str_data orelse return error.MissingDebugInfo, | |
| 695 | .debug_line = debug_line_data orelse return error.MissingDebugInfo, | |
| 696 | .debug_ranges = debug_ranges_data, | |
| 697 | }; | |
| 698 | try DW.openDwarfDebugInfo(&dwarf, allocator); | |
| 699 | di.debug_data = PdbOrDwarf{ .dwarf = dwarf }; | |
| 700 | return di; | |
| 701 | } | |
| 676 | 702 | |
| 677 | 703 | var path_buf: [windows.MAX_PATH]u8 = undefined; |
| 678 | 704 | const len = try di.coff.getPdbPath(path_buf[0..]); |
| ... | ... | @@ -681,11 +707,12 @@ fn readCoffDebugInfo(allocator: *mem.Allocator, coff_file: File) !ModuleDebugInf |
| 681 | 707 | const path = try fs.path.resolve(allocator, &[_][]const u8{raw_path}); |
| 682 | 708 | defer allocator.free(path); |
| 683 | 709 | |
| 684 | di.pdb = try pdb.Pdb.init(allocator, path); | |
| 685 | try di.pdb.parseInfoStream(); | |
| 686 | try di.pdb.parseDbiStream(); | |
| 710 | di.debug_data = PdbOrDwarf{ .pdb = undefined }; | |
| 711 | di.debug_data.pdb = try pdb.Pdb.init(allocator, path); | |
| 712 | try di.debug_data.pdb.parseInfoStream(); | |
| 713 | try di.debug_data.pdb.parseDbiStream(); | |
| 687 | 714 | |
| 688 | if (!mem.eql(u8, &di.coff.guid, &di.pdb.guid) or di.coff.age != di.pdb.age) | |
| 715 | if (!mem.eql(u8, &di.coff.guid, &di.debug_data.pdb.guid) or di.coff.age != di.debug_data.pdb.age) | |
| 689 | 716 | return error.InvalidDebugInfo; |
| 690 | 717 | |
| 691 | 718 | return di; |
| ... | ... | @@ -1331,7 +1358,7 @@ pub const ModuleDebugInfo = switch (native_os) { |
| 1331 | 1358 | }, |
| 1332 | 1359 | .uefi, .windows => struct { |
| 1333 | 1360 | base_address: usize, |
| 1334 | pdb: pdb.Pdb, | |
| 1361 | debug_data: PdbOrDwarf, | |
| 1335 | 1362 | coff: *coff.Coff, |
| 1336 | 1363 | |
| 1337 | 1364 | pub fn allocator(self: @This()) *mem.Allocator { |
| ... | ... | @@ -1342,8 +1369,18 @@ pub const ModuleDebugInfo = switch (native_os) { |
| 1342 | 1369 | // Translate the VA into an address into this object |
| 1343 | 1370 | const relocated_address = address - self.base_address; |
| 1344 | 1371 | |
| 1372 | switch (self.debug_data) { | |
| 1373 | .dwarf => |*dwarf| { | |
| 1374 | const dwarf_address = relocated_address + self.coff.pe_header.image_base; | |
| 1375 | return getSymbolFromDwarf(dwarf_address, dwarf); | |
| 1376 | }, | |
| 1377 | .pdb => { | |
| 1378 | // fallthrough to pdb handling | |
| 1379 | }, | |
| 1380 | } | |
| 1381 | ||
| 1345 | 1382 | var coff_section: *coff.Section = undefined; |
| 1346 | const mod_index = for (self.pdb.sect_contribs) |sect_contrib| { | |
| 1383 | const mod_index = for (self.debug_data.pdb.sect_contribs) |sect_contrib| { | |
| 1347 | 1384 | if (sect_contrib.Section > self.coff.sections.items.len) continue; |
| 1348 | 1385 | // Remember that SectionContribEntry.Section is 1-based. |
| 1349 | 1386 | coff_section = &self.coff.sections.items[sect_contrib.Section - 1]; |
| ... | ... | @@ -1358,15 +1395,15 @@ pub const ModuleDebugInfo = switch (native_os) { |
| 1358 | 1395 | return SymbolInfo{}; |
| 1359 | 1396 | }; |
| 1360 | 1397 | |
| 1361 | const module = (try self.pdb.getModule(mod_index)) orelse | |
| 1398 | const module = (try self.debug_data.pdb.getModule(mod_index)) orelse | |
| 1362 | 1399 | return error.InvalidDebugInfo; |
| 1363 | 1400 | const obj_basename = fs.path.basename(module.obj_file_name); |
| 1364 | 1401 | |
| 1365 | const symbol_name = self.pdb.getSymbolName( | |
| 1402 | const symbol_name = self.debug_data.pdb.getSymbolName( | |
| 1366 | 1403 | module, |
| 1367 | 1404 | relocated_address - coff_section.header.virtual_address, |
| 1368 | 1405 | ) orelse "???"; |
| 1369 | const opt_line_info = try self.pdb.getLineNumberInfo( | |
| 1406 | const opt_line_info = try self.debug_data.pdb.getLineNumberInfo( | |
| 1370 | 1407 | module, |
| 1371 | 1408 | relocated_address - coff_section.header.virtual_address, |
| 1372 | 1409 | ); |
| ... | ... | @@ -1386,32 +1423,33 @@ pub const ModuleDebugInfo = switch (native_os) { |
| 1386 | 1423 | pub fn getSymbolAtAddress(self: *@This(), address: usize) !SymbolInfo { |
| 1387 | 1424 | // Translate the VA into an address into this object |
| 1388 | 1425 | const relocated_address = address - self.base_address; |
| 1389 | ||
| 1390 | if (nosuspend self.dwarf.findCompileUnit(relocated_address)) |compile_unit| { | |
| 1391 | return SymbolInfo{ | |
| 1392 | .symbol_name = nosuspend self.dwarf.getSymbolName(relocated_address) orelse "???", | |
| 1393 | .compile_unit_name = compile_unit.die.getAttrString(&self.dwarf, DW.AT_name) catch |err| switch (err) { | |
| 1394 | error.MissingDebugInfo, error.InvalidDebugInfo => "???", | |
| 1395 | else => return err, | |
| 1396 | }, | |
| 1397 | .line_info = nosuspend self.dwarf.getLineNumberInfo(compile_unit.*, relocated_address) catch |err| switch (err) { | |
| 1398 | error.MissingDebugInfo, error.InvalidDebugInfo => null, | |
| 1399 | else => return err, | |
| 1400 | }, | |
| 1401 | }; | |
| 1402 | } else |err| switch (err) { | |
| 1403 | error.MissingDebugInfo, error.InvalidDebugInfo => { | |
| 1404 | return SymbolInfo{}; | |
| 1405 | }, | |
| 1406 | else => return err, | |
| 1407 | } | |
| 1408 | ||
| 1409 | unreachable; | |
| 1426 | return getSymbolFromDwarf(relocated_address, &self.dwarf); | |
| 1410 | 1427 | } |
| 1411 | 1428 | }, |
| 1412 | 1429 | else => DW.DwarfInfo, |
| 1413 | 1430 | }; |
| 1414 | 1431 | |
| 1432 | fn getSymbolFromDwarf(address: u64, di: *DW.DwarfInfo) !SymbolInfo { | |
| 1433 | if (nosuspend di.findCompileUnit(address)) |compile_unit| { | |
| 1434 | return SymbolInfo{ | |
| 1435 | .symbol_name = nosuspend di.getSymbolName(address) orelse "???", | |
| 1436 | .compile_unit_name = compile_unit.die.getAttrString(di, DW.AT_name) catch |err| switch (err) { | |
| 1437 | error.MissingDebugInfo, error.InvalidDebugInfo => "???", | |
| 1438 | else => return err, | |
| 1439 | }, | |
| 1440 | .line_info = nosuspend di.getLineNumberInfo(compile_unit.*, address) catch |err| switch (err) { | |
| 1441 | error.MissingDebugInfo, error.InvalidDebugInfo => null, | |
| 1442 | else => return err, | |
| 1443 | }, | |
| 1444 | }; | |
| 1445 | } else |err| switch (err) { | |
| 1446 | error.MissingDebugInfo, error.InvalidDebugInfo => { | |
| 1447 | return SymbolInfo{}; | |
| 1448 | }, | |
| 1449 | else => return err, | |
| 1450 | } | |
| 1451 | } | |
| 1452 | ||
| 1415 | 1453 | /// TODO multithreaded awareness |
| 1416 | 1454 | var debug_info_allocator: ?*mem.Allocator = null; |
| 1417 | 1455 | var debug_info_arena_allocator: std.heap.ArenaAllocator = undefined; |
lib/std/dwarf.zig+5-5| ... | ... | @@ -144,7 +144,7 @@ const FileEntry = struct { |
| 144 | 144 | }; |
| 145 | 145 | |
| 146 | 146 | const LineNumberProgram = struct { |
| 147 | address: usize, | |
| 147 | address: u64, | |
| 148 | 148 | file: usize, |
| 149 | 149 | line: i64, |
| 150 | 150 | column: u64, |
| ... | ... | @@ -153,12 +153,12 @@ const LineNumberProgram = struct { |
| 153 | 153 | end_sequence: bool, |
| 154 | 154 | |
| 155 | 155 | default_is_stmt: bool, |
| 156 | target_address: usize, | |
| 156 | target_address: u64, | |
| 157 | 157 | include_dirs: []const []const u8, |
| 158 | 158 | file_entries: *ArrayList(FileEntry), |
| 159 | 159 | |
| 160 | 160 | prev_valid: bool, |
| 161 | prev_address: usize, | |
| 161 | prev_address: u64, | |
| 162 | 162 | prev_file: usize, |
| 163 | 163 | prev_line: i64, |
| 164 | 164 | prev_column: u64, |
| ... | ... | @@ -186,7 +186,7 @@ const LineNumberProgram = struct { |
| 186 | 186 | self.prev_end_sequence = undefined; |
| 187 | 187 | } |
| 188 | 188 | |
| 189 | pub fn init(is_stmt: bool, include_dirs: []const []const u8, file_entries: *ArrayList(FileEntry), target_address: usize) LineNumberProgram { | |
| 189 | pub fn init(is_stmt: bool, include_dirs: []const []const u8, file_entries: *ArrayList(FileEntry), target_address: u64) LineNumberProgram { | |
| 190 | 190 | return LineNumberProgram{ |
| 191 | 191 | .address = 0, |
| 192 | 192 | .file = 1, |
| ... | ... | @@ -691,7 +691,7 @@ pub const DwarfInfo = struct { |
| 691 | 691 | return result; |
| 692 | 692 | } |
| 693 | 693 | |
| 694 | pub fn getLineNumberInfo(di: *DwarfInfo, compile_unit: CompileUnit, target_address: usize) !debug.LineInfo { | |
| 694 | pub fn getLineNumberInfo(di: *DwarfInfo, compile_unit: CompileUnit, target_address: u64) !debug.LineInfo { | |
| 695 | 695 | var stream = io.fixedBufferStream(di.debug_line); |
| 696 | 696 | const in = &stream.reader(); |
| 697 | 697 | const seekable = &stream.seekableStream(); |