| ... | @@ -997,7 +997,6 @@ fn readCoffDebugInfo(allocator: mem.Allocator, coff_obj: *coff.Coff) !ModuleDebu | ... | @@ -997,7 +997,6 @@ fn readCoffDebugInfo(allocator: mem.Allocator, coff_obj: *coff.Coff) !ModuleDebu |
| 997 | .base_address = undefined, | 997 | .base_address = undefined, |
| 998 | .coff_image_base = coff_obj.getImageBase(), | 998 | .coff_image_base = coff_obj.getImageBase(), |
| 999 | .coff_section_headers = undefined, | 999 | .coff_section_headers = undefined, |
| 1000 | .debug_data = undefined, | | |
| 1001 | }; | 1000 | }; |
| 1002 | | 1001 | |
| 1003 | if (coff_obj.getSectionByName(".debug_info")) |_| { | 1002 | if (coff_obj.getSectionByName(".debug_info")) |_| { |
| ... | @@ -1022,11 +1021,10 @@ fn readCoffDebugInfo(allocator: mem.Allocator, coff_obj: *coff.Coff) !ModuleDebu | ... | @@ -1022,11 +1021,10 @@ fn readCoffDebugInfo(allocator: mem.Allocator, coff_obj: *coff.Coff) !ModuleDebu |
| 1022 | }; | 1021 | }; |
| 1023 | | 1022 | |
| 1024 | try DW.openDwarfDebugInfo(&dwarf, allocator); | 1023 | try DW.openDwarfDebugInfo(&dwarf, allocator); |
| 1025 | di.debug_data = PdbOrDwarf{ .dwarf = dwarf }; | 1024 | di.dwarf = dwarf; |
| 1026 | return di; | | |
| 1027 | } | 1025 | } |
| 1028 | | 1026 | |
| 1029 | // Only used by pdb path | 1027 | // Only used by the pdb path |
| 1030 | di.coff_section_headers = try coff_obj.getSectionHeadersAlloc(allocator); | 1028 | di.coff_section_headers = try coff_obj.getSectionHeadersAlloc(allocator); |
| 1031 | errdefer allocator.free(di.coff_section_headers); | 1029 | errdefer allocator.free(di.coff_section_headers); |
| 1032 | | 1030 | |
| ... | @@ -1037,15 +1035,19 @@ fn readCoffDebugInfo(allocator: mem.Allocator, coff_obj: *coff.Coff) !ModuleDebu | ... | @@ -1037,15 +1035,19 @@ fn readCoffDebugInfo(allocator: mem.Allocator, coff_obj: *coff.Coff) !ModuleDebu |
| 1037 | const path = try fs.path.resolve(allocator, &[_][]const u8{raw_path}); | 1035 | const path = try fs.path.resolve(allocator, &[_][]const u8{raw_path}); |
| 1038 | defer allocator.free(path); | 1036 | defer allocator.free(path); |
| 1039 | | 1037 | |
| 1040 | di.debug_data = PdbOrDwarf{ .pdb = undefined }; | 1038 | di.pdb = pdb.Pdb.init(allocator, path) catch |err| switch (err) { |
| 1041 | di.debug_data.pdb = pdb.Pdb.init(allocator, path) catch |err| switch (err) { | 1039 | error.FileNotFound, error.IsDir => { |
| 1042 | error.FileNotFound, error.IsDir => return error.MissingDebugInfo, | 1040 | if (di.dwarf == null) return error.MissingDebugInfo; |
| | 1041 | allocator.free(di.coff_section_headers); |
| | 1042 | di.coff_section_headers = undefined; |
| | 1043 | return di; |
| | 1044 | }, |
| 1043 | else => return err, | 1045 | else => return err, |
| 1044 | }; | 1046 | }; |
| 1045 | try di.debug_data.pdb.parseInfoStream(); | 1047 | try di.pdb.?.parseInfoStream(); |
| 1046 | try di.debug_data.pdb.parseDbiStream(); | 1048 | try di.pdb.?.parseDbiStream(); |
| 1047 | | 1049 | |
| 1048 | if (!mem.eql(u8, &coff_obj.guid, &di.debug_data.pdb.guid) or coff_obj.age != di.debug_data.pdb.age) | 1050 | if (!mem.eql(u8, &coff_obj.guid, &di.pdb.?.guid) or coff_obj.age != di.pdb.?.age) |
| 1049 | return error.InvalidDebugInfo; | 1051 | return error.InvalidDebugInfo; |
| 1050 | | 1052 | |
| 1051 | return di; | 1053 | return di; |
| ... | @@ -1695,7 +1697,7 @@ pub const DebugInfo = struct { | ... | @@ -1695,7 +1697,7 @@ pub const DebugInfo = struct { |
| 1695 | errdefer self.allocator.destroy(obj_di); | 1697 | errdefer self.allocator.destroy(obj_di); |
| 1696 | | 1698 | |
| 1697 | const mapped_module = @as([*]const u8, @ptrFromInt(module.base_address))[0..module.size]; | 1699 | const mapped_module = @as([*]const u8, @ptrFromInt(module.base_address))[0..module.size]; |
| 1698 | var coff_obj = try coff.Coff.init(mapped_module); | 1700 | var coff_obj = try coff.Coff.init(mapped_module, true); |
| 1699 | | 1701 | |
| 1700 | // The string table is not mapped into memory by the loader, so if a section name is in the | 1702 | // The string table is not mapped into memory by the loader, so if a section name is in the |
| 1701 | // string table then we have to map the full image file from disk. This can happen when | 1703 | // string table then we have to map the full image file from disk. This can happen when |
| ... | @@ -1753,7 +1755,7 @@ pub const DebugInfo = struct { | ... | @@ -1753,7 +1755,7 @@ pub const DebugInfo = struct { |
| 1753 | errdefer assert(windows.ntdll.NtUnmapViewOfSection(process_handle, @ptrFromInt(base_ptr)) == .SUCCESS); | 1755 | errdefer assert(windows.ntdll.NtUnmapViewOfSection(process_handle, @ptrFromInt(base_ptr)) == .SUCCESS); |
| 1754 | | 1756 | |
| 1755 | const section_view = @as([*]const u8, @ptrFromInt(base_ptr))[0..coff_len]; | 1757 | const section_view = @as([*]const u8, @ptrFromInt(base_ptr))[0..coff_len]; |
| 1756 | coff_obj = try coff.Coff.init(section_view); | 1758 | coff_obj = try coff.Coff.init(section_view, false); |
| 1757 | | 1759 | |
| 1758 | module.mapped_file = .{ | 1760 | module.mapped_file = .{ |
| 1759 | .file = coff_file, | 1761 | .file = coff_file, |
| ... | @@ -2141,34 +2143,27 @@ pub const ModuleDebugInfo = switch (native_os) { | ... | @@ -2141,34 +2143,27 @@ pub const ModuleDebugInfo = switch (native_os) { |
| 2141 | }, | 2143 | }, |
| 2142 | .uefi, .windows => struct { | 2144 | .uefi, .windows => struct { |
| 2143 | base_address: usize, | 2145 | base_address: usize, |
| 2144 | debug_data: PdbOrDwarf, | 2146 | pdb: ?pdb.Pdb = null, |
| | 2147 | dwarf: ?DW.DwarfInfo = null, |
| 2145 | coff_image_base: u64, | 2148 | coff_image_base: u64, |
| 2146 | /// Only used if debug_data is .pdb | 2149 | |
| | 2150 | /// Only used if pdb is non-null |
| 2147 | coff_section_headers: []coff.SectionHeader, | 2151 | coff_section_headers: []coff.SectionHeader, |
| 2148 | | 2152 | |
| 2149 | pub fn deinit(self: *@This(), allocator: mem.Allocator) void { | 2153 | pub fn deinit(self: *@This(), allocator: mem.Allocator) void { |
| 2150 | self.debug_data.deinit(allocator); | 2154 | if (self.dwarf) |*dwarf| { |
| 2151 | if (self.debug_data == .pdb) { | 2155 | dwarf.deinit(allocator); |
| 2152 | allocator.free(self.coff_section_headers); | | |
| 2153 | } | 2156 | } |
| 2154 | } | | |
| 2155 | | | |
| 2156 | pub fn getSymbolAtAddress(self: *@This(), allocator: mem.Allocator, address: usize) !SymbolInfo { | | |
| 2157 | // Translate the VA into an address into this object | | |
| 2158 | const relocated_address = address - self.base_address; | | |
| 2159 | | 2157 | |
| 2160 | switch (self.debug_data) { | 2158 | if (self.pdb) |*p| { |
| 2161 | .dwarf => |*dwarf| { | 2159 | p.deinit(); |
| 2162 | const dwarf_address = relocated_address + self.coff_image_base; | 2160 | allocator.free(self.coff_section_headers); |
| 2163 | return getSymbolFromDwarf(allocator, dwarf_address, dwarf); | | |
| 2164 | }, | | |
| 2165 | .pdb => { | | |
| 2166 | // fallthrough to pdb handling | | |
| 2167 | }, | | |
| 2168 | } | 2161 | } |
| | 2162 | } |
| 2169 | | 2163 | |
| | 2164 | fn getSymbolFromPdb(self: *@This(), relocated_address: usize) !?SymbolInfo { |
| 2170 | var coff_section: *align(1) const coff.SectionHeader = undefined; | 2165 | var coff_section: *align(1) const coff.SectionHeader = undefined; |
| 2171 | const mod_index = for (self.debug_data.pdb.sect_contribs) |sect_contrib| { | 2166 | const mod_index = for (self.pdb.?.sect_contribs) |sect_contrib| { |
| 2172 | if (sect_contrib.Section > self.coff_section_headers.len) continue; | 2167 | if (sect_contrib.Section > self.coff_section_headers.len) continue; |
| 2173 | // Remember that SectionContribEntry.Section is 1-based. | 2168 | // Remember that SectionContribEntry.Section is 1-based. |
| 2174 | coff_section = &self.coff_section_headers[sect_contrib.Section - 1]; | 2169 | coff_section = &self.coff_section_headers[sect_contrib.Section - 1]; |
| ... | @@ -2180,18 +2175,18 @@ pub const ModuleDebugInfo = switch (native_os) { | ... | @@ -2180,18 +2175,18 @@ pub const ModuleDebugInfo = switch (native_os) { |
| 2180 | } | 2175 | } |
| 2181 | } else { | 2176 | } else { |
| 2182 | // we have no information to add to the address | 2177 | // we have no information to add to the address |
| 2183 | return SymbolInfo{}; | 2178 | return null; |
| 2184 | }; | 2179 | }; |
| 2185 | | 2180 | |
| 2186 | const module = (try self.debug_data.pdb.getModule(mod_index)) orelse | 2181 | const module = (try self.pdb.?.getModule(mod_index)) orelse |
| 2187 | return error.InvalidDebugInfo; | 2182 | return error.InvalidDebugInfo; |
| 2188 | const obj_basename = fs.path.basename(module.obj_file_name); | 2183 | const obj_basename = fs.path.basename(module.obj_file_name); |
| 2189 | | 2184 | |
| 2190 | const symbol_name = self.debug_data.pdb.getSymbolName( | 2185 | const symbol_name = self.pdb.?.getSymbolName( |
| 2191 | module, | 2186 | module, |
| 2192 | relocated_address - coff_section.virtual_address, | 2187 | relocated_address - coff_section.virtual_address, |
| 2193 | ) orelse "???"; | 2188 | ) orelse "???"; |
| 2194 | const opt_line_info = try self.debug_data.pdb.getLineNumberInfo( | 2189 | const opt_line_info = try self.pdb.?.getLineNumberInfo( |
| 2195 | module, | 2190 | module, |
| 2196 | relocated_address - coff_section.virtual_address, | 2191 | relocated_address - coff_section.virtual_address, |
| 2197 | ); | 2192 | ); |
| ... | @@ -2203,6 +2198,22 @@ pub const ModuleDebugInfo = switch (native_os) { | ... | @@ -2203,6 +2198,22 @@ pub const ModuleDebugInfo = switch (native_os) { |
| 2203 | }; | 2198 | }; |
| 2204 | } | 2199 | } |
| 2205 | | 2200 | |
| | 2201 | pub fn getSymbolAtAddress(self: *@This(), allocator: mem.Allocator, address: usize) !SymbolInfo { |
| | 2202 | // Translate the VA into an address into this object |
| | 2203 | const relocated_address = address - self.base_address; |
| | 2204 | |
| | 2205 | if (self.pdb != null) { |
| | 2206 | if (try self.getSymbolFromPdb(relocated_address)) |symbol| return symbol; |
| | 2207 | } |
| | 2208 | |
| | 2209 | if (self.dwarf) |*dwarf| { |
| | 2210 | const dwarf_address = relocated_address + self.coff_image_base; |
| | 2211 | return getSymbolFromDwarf(allocator, dwarf_address, dwarf); |
| | 2212 | } |
| | 2213 | |
| | 2214 | return SymbolInfo{}; |
| | 2215 | } |
| | 2216 | |
| 2206 | pub fn getDwarfInfoForAddress(self: *@This(), allocator: mem.Allocator, address: usize) !?*const DW.DwarfInfo { | 2217 | pub fn getDwarfInfoForAddress(self: *@This(), allocator: mem.Allocator, address: usize) !?*const DW.DwarfInfo { |
| 2207 | _ = allocator; | 2218 | _ = allocator; |
| 2208 | _ = address; | 2219 | _ = address; |