| ... | @@ -411,7 +411,7 @@ fn printSourceAtAddressWindows(di: *DebugInfo, out_stream: var, relocated_addres | ... | @@ -411,7 +411,7 @@ fn printSourceAtAddressWindows(di: *DebugInfo, out_stream: var, relocated_addres |
| 411 | | 411 | |
| 412 | if (opt_line_info) |line_info| { | 412 | if (opt_line_info) |line_info| { |
| 413 | try out_stream.print("\n"); | 413 | try out_stream.print("\n"); |
| 414 | if (printLineFromFile(out_stream, line_info)) { | 414 | if (printLineFromFileAnyOs(out_stream, line_info)) { |
| 415 | if (line_info.column == 0) { | 415 | if (line_info.column == 0) { |
| 416 | try out_stream.write("\n"); | 416 | try out_stream.write("\n"); |
| 417 | } else { | 417 | } else { |
| ... | @@ -595,7 +595,16 @@ fn printSourceAtAddressMacOs(di: *DebugInfo, out_stream: var, address: usize, tt | ... | @@ -595,7 +595,16 @@ fn printSourceAtAddressMacOs(di: *DebugInfo, out_stream: var, address: usize, tt |
| 595 | } else "???"; | 595 | } else "???"; |
| 596 | if (getLineNumberInfoMacOs(di, symbol.*, adjusted_addr)) |line_info| { | 596 | if (getLineNumberInfoMacOs(di, symbol.*, adjusted_addr)) |line_info| { |
| 597 | defer line_info.deinit(); | 597 | defer line_info.deinit(); |
| 598 | try printLineInfo(di, out_stream, line_info, address, symbol_name, compile_unit_name, tty_color); | 598 | try printLineInfo( |
| | 599 | di, |
| | 600 | out_stream, |
| | 601 | line_info, |
| | 602 | address, |
| | 603 | symbol_name, |
| | 604 | compile_unit_name, |
| | 605 | tty_color, |
| | 606 | printLineFromFileAnyOs, |
| | 607 | ); |
| 599 | } else |err| switch (err) { | 608 | } else |err| switch (err) { |
| 600 | error.MissingDebugInfo, error.InvalidDebugInfo => { | 609 | error.MissingDebugInfo, error.InvalidDebugInfo => { |
| 601 | if (tty_color) { | 610 | if (tty_color) { |
| ... | @@ -608,7 +617,15 @@ fn printSourceAtAddressMacOs(di: *DebugInfo, out_stream: var, address: usize, tt | ... | @@ -608,7 +617,15 @@ fn printSourceAtAddressMacOs(di: *DebugInfo, out_stream: var, address: usize, tt |
| 608 | } | 617 | } |
| 609 | } | 618 | } |
| 610 | | 619 | |
| 611 | pub fn printSourceAtAddressLinux(debug_info: *DebugInfo, out_stream: var, address: usize, tty_color: bool) !void { | 620 | /// This function works in freestanding mode. |
| | 621 | /// fn printLineFromFile(out_stream: var, line_info: LineInfo) !void |
| | 622 | pub fn printSourceAtAddressDwarf( |
| | 623 | debug_info: *DebugInfo, |
| | 624 | out_stream: var, |
| | 625 | address: usize, |
| | 626 | tty_color: bool, |
| | 627 | comptime printLineFromFile: var, |
| | 628 | ) !void { |
| 612 | const compile_unit = findCompileUnit(debug_info, address) catch { | 629 | const compile_unit = findCompileUnit(debug_info, address) catch { |
| 613 | if (tty_color) { | 630 | if (tty_color) { |
| 614 | try out_stream.print("???:?:?: " ++ DIM ++ "0x{x} in ??? (???)" ++ RESET ++ "\n\n\n", address); | 631 | try out_stream.print("???:?:?: " ++ DIM ++ "0x{x} in ??? (???)" ++ RESET ++ "\n\n\n", address); |
| ... | @@ -618,10 +635,19 @@ pub fn printSourceAtAddressLinux(debug_info: *DebugInfo, out_stream: var, addres | ... | @@ -618,10 +635,19 @@ pub fn printSourceAtAddressLinux(debug_info: *DebugInfo, out_stream: var, addres |
| 618 | return; | 635 | return; |
| 619 | }; | 636 | }; |
| 620 | const compile_unit_name = try compile_unit.die.getAttrString(debug_info, DW.AT_name); | 637 | const compile_unit_name = try compile_unit.die.getAttrString(debug_info, DW.AT_name); |
| 621 | if (getLineNumberInfoLinux(debug_info, compile_unit, address - 1)) |line_info| { | 638 | if (getLineNumberInfoDwarf(debug_info, compile_unit.*, address - 1)) |line_info| { |
| 622 | defer line_info.deinit(); | 639 | defer line_info.deinit(); |
| 623 | const symbol_name = "???"; | 640 | const symbol_name = "???"; |
| 624 | try printLineInfo(debug_info, out_stream, line_info, address, symbol_name, compile_unit_name, tty_color); | 641 | try printLineInfo( |
| | 642 | debug_info, |
| | 643 | out_stream, |
| | 644 | line_info, |
| | 645 | address, |
| | 646 | symbol_name, |
| | 647 | compile_unit_name, |
| | 648 | tty_color, |
| | 649 | printLineFromFile, |
| | 650 | ); |
| 625 | } else |err| switch (err) { | 651 | } else |err| switch (err) { |
| 626 | error.MissingDebugInfo, error.InvalidDebugInfo => { | 652 | error.MissingDebugInfo, error.InvalidDebugInfo => { |
| 627 | if (tty_color) { | 653 | if (tty_color) { |
| ... | @@ -634,6 +660,10 @@ pub fn printSourceAtAddressLinux(debug_info: *DebugInfo, out_stream: var, addres | ... | @@ -634,6 +660,10 @@ pub fn printSourceAtAddressLinux(debug_info: *DebugInfo, out_stream: var, addres |
| 634 | } | 660 | } |
| 635 | } | 661 | } |
| 636 | | 662 | |
| | 663 | pub fn printSourceAtAddressLinux(debug_info: *DebugInfo, out_stream: var, address: usize, tty_color: bool) !void { |
| | 664 | return printSourceAtAddressDwarf(debug_info, out_stream, address, tty_color, printLineFromFileAnyOs); |
| | 665 | } |
| | 666 | |
| 637 | fn printLineInfo( | 667 | fn printLineInfo( |
| 638 | debug_info: *DebugInfo, | 668 | debug_info: *DebugInfo, |
| 639 | out_stream: var, | 669 | out_stream: var, |
| ... | @@ -642,6 +672,7 @@ fn printLineInfo( | ... | @@ -642,6 +672,7 @@ fn printLineInfo( |
| 642 | symbol_name: []const u8, | 672 | symbol_name: []const u8, |
| 643 | compile_unit_name: []const u8, | 673 | compile_unit_name: []const u8, |
| 644 | tty_color: bool, | 674 | tty_color: bool, |
| | 675 | comptime printLineFromFile: var, |
| 645 | ) !void { | 676 | ) !void { |
| 646 | if (tty_color) { | 677 | if (tty_color) { |
| 647 | try out_stream.print( | 678 | try out_stream.print( |
| ... | @@ -1020,7 +1051,7 @@ fn openSelfDebugInfoMacOs(allocator: *mem.Allocator) !DebugInfo { | ... | @@ -1020,7 +1051,7 @@ fn openSelfDebugInfoMacOs(allocator: *mem.Allocator) !DebugInfo { |
| 1020 | }; | 1051 | }; |
| 1021 | } | 1052 | } |
| 1022 | | 1053 | |
| 1023 | fn printLineFromFile(out_stream: var, line_info: LineInfo) !void { | 1054 | fn printLineFromFileAnyOs(out_stream: var, line_info: LineInfo) !void { |
| 1024 | var f = try os.File.openRead(line_info.file_name); | 1055 | var f = try os.File.openRead(line_info.file_name); |
| 1025 | defer f.close(); | 1056 | defer f.close(); |
| 1026 | // TODO fstat and make sure that the file has the correct size | 1057 | // TODO fstat and make sure that the file has the correct size |
| ... | @@ -1247,11 +1278,12 @@ const FileEntry = struct { | ... | @@ -1247,11 +1278,12 @@ const FileEntry = struct { |
| 1247 | const LineInfo = struct { | 1278 | const LineInfo = struct { |
| 1248 | line: usize, | 1279 | line: usize, |
| 1249 | column: usize, | 1280 | column: usize, |
| 1250 | file_name: []u8, | 1281 | file_name: []const u8, |
| 1251 | allocator: *mem.Allocator, | 1282 | allocator: ?*mem.Allocator, |
| 1252 | | 1283 | |
| 1253 | fn deinit(self: *const LineInfo) void { | 1284 | fn deinit(self: LineInfo) void { |
| 1254 | self.allocator.free(self.file_name); | 1285 | const allocator = self.allocator orelse return; |
| | 1286 | allocator.free(self.file_name); |
| 1255 | } | 1287 | } |
| 1256 | }; | 1288 | }; |
| 1257 | | 1289 | |
| ... | @@ -1707,7 +1739,7 @@ fn getLineNumberInfoMacOs(di: *DebugInfo, symbol: MachoSymbol, target_address: u | ... | @@ -1707,7 +1739,7 @@ fn getLineNumberInfoMacOs(di: *DebugInfo, symbol: MachoSymbol, target_address: u |
| 1707 | return error.MissingDebugInfo; | 1739 | return error.MissingDebugInfo; |
| 1708 | } | 1740 | } |
| 1709 | | 1741 | |
| 1710 | fn getLineNumberInfoLinux(di: *DebugInfo, compile_unit: *const CompileUnit, target_address: usize) !LineInfo { | 1742 | fn getLineNumberInfoDwarf(di: *DebugInfo, compile_unit: CompileUnit, target_address: usize) !LineInfo { |
| 1711 | const compile_unit_cwd = try compile_unit.die.getAttrString(di, DW.AT_comp_dir); | 1743 | const compile_unit_cwd = try compile_unit.die.getAttrString(di, DW.AT_comp_dir); |
| 1712 | | 1744 | |
| 1713 | const debug_line_end = di.debug_line.offset + di.debug_line.size; | 1745 | const debug_line_end = di.debug_line.offset + di.debug_line.size; |