| ... | ... | @@ -1754,7 +1754,7 @@ pub const ModuleDebugInfo = switch (native_os) { |
| 1754 | 1754 | os.munmap(self.mapped_memory); |
| 1755 | 1755 | } |
| 1756 | 1756 | |
| 1757 | | fn loadOFile(self: *@This(), allocator: mem.Allocator, o_file_path: []const u8) !OFileInfo { |
| 1757 | fn loadOFile(self: *@This(), allocator: mem.Allocator, o_file_path: []const u8) !*OFileInfo { |
| 1758 | 1758 | const o_file = try fs.cwd().openFile(o_file_path, .{ .intended_io_mode = .blocking }); |
| 1759 | 1759 | const mapped_mem = try mapWholeFile(o_file); |
| 1760 | 1760 | |
| ... | ... | @@ -1799,11 +1799,11 @@ pub const ModuleDebugInfo = switch (native_os) { |
| 1799 | 1799 | |
| 1800 | 1800 | var sections: DW.DwarfInfo.SectionArray = DW.DwarfInfo.null_section_array; |
| 1801 | 1801 | for (segcmd.?.getSections()) |sect| { |
| 1802 | | const name = sect.sectName(); |
| 1802 | if (!std.mem.eql(u8, "__DWARF", sect.segName())) continue; |
| 1803 | 1803 | |
| 1804 | 1804 | var section_index: ?usize = null; |
| 1805 | 1805 | inline for (@typeInfo(DW.DwarfSection).Enum.fields, 0..) |section, i| { |
| 1806 | | if (mem.eql(u8, "__" ++ section.name, name)) section_index = i; |
| 1806 | if (mem.eql(u8, "__" ++ section.name, sect.sectName())) section_index = i; |
| 1807 | 1807 | } |
| 1808 | 1808 | if (section_index == null) continue; |
| 1809 | 1809 | |
| ... | ... | @@ -1834,65 +1834,31 @@ pub const ModuleDebugInfo = switch (native_os) { |
| 1834 | 1834 | }; |
| 1835 | 1835 | |
| 1836 | 1836 | // Add the debug info to the cache |
| 1837 | | try self.ofiles.putNoClobber(o_file_path, info); |
| 1837 | const result = try self.ofiles.getOrPut(o_file_path); |
| 1838 | assert(!result.found_existing); |
| 1839 | result.value_ptr.* = info; |
| 1838 | 1840 | |
| 1839 | | return info; |
| 1840 | | } |
| 1841 | | |
| 1842 | | fn getOFileForAddress(self: *@This(), allocator: mem.Allocator, address: usize) !?*OFileInfo { |
| 1843 | | nosuspend { |
| 1844 | | const relocated_address = address - self.base_address; |
| 1845 | | const symbol = machoSearchSymbols(self.symbols, relocated_address) orelse |
| 1846 | | return null; |
| 1847 | | |
| 1848 | | const o_file_path = mem.sliceTo(self.strings[symbol.ofile..], 0); |
| 1849 | | var o_file_info = self.ofiles.get(o_file_path) orelse |
| 1850 | | (self.loadOFile(allocator, o_file_path) catch |err| switch (err) { |
| 1851 | | error.FileNotFound, |
| 1852 | | error.MissingDebugInfo, |
| 1853 | | error.InvalidDebugInfo, |
| 1854 | | => return null, |
| 1855 | | else => return err, |
| 1856 | | }); |
| 1857 | | |
| 1858 | | return &o_file_info.di; |
| 1859 | | } |
| 1841 | return result.value_ptr; |
| 1860 | 1842 | } |
| 1861 | 1843 | |
| 1862 | 1844 | pub fn getSymbolAtAddress(self: *@This(), allocator: mem.Allocator, address: usize) !SymbolInfo { |
| 1863 | 1845 | nosuspend { |
| 1864 | | // Translate the VA into an address into this object |
| 1865 | | const relocated_address = address - self.base_address; |
| 1866 | | |
| 1867 | | // Find the .o file where this symbol is defined |
| 1868 | | const symbol = machoSearchSymbols(self.symbols, relocated_address) orelse |
| 1869 | | return SymbolInfo{}; |
| 1870 | | const addr_off = relocated_address - symbol.addr; |
| 1846 | const result = try self.getOFileInfoForAddress(allocator, address); |
| 1847 | if (result.symbol == null) return .{}; |
| 1871 | 1848 | |
| 1872 | 1849 | // Take the symbol name from the N_FUN STAB entry, we're going to |
| 1873 | 1850 | // use it if we fail to find the DWARF infos |
| 1874 | | const stab_symbol = mem.sliceTo(self.strings[symbol.strx..], 0); |
| 1875 | | const o_file_path = mem.sliceTo(self.strings[symbol.ofile..], 0); |
| 1876 | | |
| 1877 | | // Check if its debug infos are already in the cache |
| 1878 | | var o_file_info = self.ofiles.get(o_file_path) orelse |
| 1879 | | (self.loadOFile(allocator, o_file_path) catch |err| switch (err) { |
| 1880 | | error.FileNotFound, |
| 1881 | | error.MissingDebugInfo, |
| 1882 | | error.InvalidDebugInfo, |
| 1883 | | => { |
| 1884 | | return SymbolInfo{ .symbol_name = stab_symbol }; |
| 1885 | | }, |
| 1886 | | else => return err, |
| 1887 | | }); |
| 1888 | | const o_file_di = &o_file_info.di; |
| 1851 | const stab_symbol = mem.sliceTo(self.strings[result.symbol.?.strx..], 0); |
| 1852 | if (result.o_file_info == null) return .{ .symbol_name = stab_symbol }; |
| 1889 | 1853 | |
| 1890 | 1854 | // Translate again the address, this time into an address inside the |
| 1891 | 1855 | // .o file |
| 1892 | | const relocated_address_o = o_file_info.addr_table.get(stab_symbol) orelse return SymbolInfo{ |
| 1856 | const relocated_address_o = result.o_file_info.?.addr_table.get(stab_symbol) orelse return .{ |
| 1893 | 1857 | .symbol_name = "???", |
| 1894 | 1858 | }; |
| 1895 | 1859 | |
| 1860 | const addr_off = result.relocated_address - result.symbol.?.addr; |
| 1861 | const o_file_di = &result.o_file_info.?.di; |
| 1896 | 1862 | if (o_file_di.findCompileUnit(relocated_address_o)) |compile_unit| { |
| 1897 | 1863 | return SymbolInfo{ |
| 1898 | 1864 | .symbol_name = o_file_di.getSymbolName(relocated_address_o) orelse "???", |
| ... | ... | @@ -1919,30 +1885,48 @@ pub const ModuleDebugInfo = switch (native_os) { |
| 1919 | 1885 | }, |
| 1920 | 1886 | else => return err, |
| 1921 | 1887 | } |
| 1922 | | |
| 1923 | | unreachable; |
| 1924 | 1888 | } |
| 1925 | 1889 | } |
| 1926 | 1890 | |
| 1927 | | pub fn getDwarfInfoForAddress(self: *@This(), allocator: mem.Allocator, address: usize) !?*const DW.DwarfInfo { |
| 1891 | fn getOFileInfoForAddress(self: *@This(), allocator: mem.Allocator, address: usize) !struct { |
| 1892 | relocated_address: usize, |
| 1893 | symbol: ?*const MachoSymbol = null, |
| 1894 | o_file_info: ?*OFileInfo = null, |
| 1895 | } { |
| 1928 | 1896 | nosuspend { |
| 1897 | // Translate the VA into an address into this object |
| 1929 | 1898 | const relocated_address = address - self.base_address; |
| 1930 | | const symbol = machoSearchSymbols(self.symbols, relocated_address) orelse |
| 1931 | | return null; |
| 1932 | 1899 | |
| 1900 | // Find the .o file where this symbol is defined |
| 1901 | const symbol = machoSearchSymbols(self.symbols, relocated_address) orelse return .{ |
| 1902 | .relocated_address = relocated_address, |
| 1903 | }; |
| 1904 | |
| 1905 | // Check if its debug infos are already in the cache |
| 1933 | 1906 | const o_file_path = mem.sliceTo(self.strings[symbol.ofile..], 0); |
| 1934 | | var o_file_info = self.ofiles.get(o_file_path) orelse |
| 1907 | var o_file_info = self.ofiles.getPtr(o_file_path) orelse |
| 1935 | 1908 | (self.loadOFile(allocator, o_file_path) catch |err| switch (err) { |
| 1936 | 1909 | error.FileNotFound, |
| 1937 | 1910 | error.MissingDebugInfo, |
| 1938 | 1911 | error.InvalidDebugInfo, |
| 1939 | | => return null, |
| 1912 | => return .{ |
| 1913 | .relocated_address = relocated_address, |
| 1914 | .symbol = symbol, |
| 1915 | }, |
| 1940 | 1916 | else => return err, |
| 1941 | 1917 | }); |
| 1942 | 1918 | |
| 1943 | | return &o_file_info.di; |
| 1919 | return .{ |
| 1920 | .relocated_address = relocated_address, |
| 1921 | .symbol = symbol, |
| 1922 | .o_file_info = o_file_info, |
| 1923 | }; |
| 1944 | 1924 | } |
| 1945 | 1925 | } |
| 1926 | |
| 1927 | pub fn getDwarfInfoForAddress(self: *@This(), allocator: mem.Allocator, address: usize) !?*const DW.DwarfInfo { |
| 1928 | return if ((try self.getOFileInfoForAddress(allocator, address)).o_file_info) |o_file_info| &o_file_info.di else null; |
| 1929 | } |
| 1946 | 1930 | }, |
| 1947 | 1931 | .uefi, .windows => struct { |
| 1948 | 1932 | base_address: usize, |