| ... | ... | @@ -1771,7 +1771,8 @@ pub fn writeDbgInfoHeader(self: *Dwarf, module: *Module, low_pc: u64, high_pc: u |
| 1771 | 1771 | } |
| 1772 | 1772 | // Write the form for the compile unit, which must match the abbrev table above. |
| 1773 | 1773 | const name_strp = try self.makeString(module.root_pkg.root_src_path); |
| 1774 | | const compile_unit_dir = self.getCompDir(module); |
| 1774 | var compile_unit_dir_buffer: [std.fs.MAX_PATH_BYTES]u8 = undefined; |
| 1775 | const compile_unit_dir = resolveCompilationDir(module, &compile_unit_dir_buffer); |
| 1775 | 1776 | const comp_dir_strp = try self.makeString(compile_unit_dir); |
| 1776 | 1777 | const producer_strp = try self.makeString(link.producer_string); |
| 1777 | 1778 | |
| ... | ... | @@ -1823,19 +1824,15 @@ pub fn writeDbgInfoHeader(self: *Dwarf, module: *Module, low_pc: u64, high_pc: u |
| 1823 | 1824 | } |
| 1824 | 1825 | } |
| 1825 | 1826 | |
| 1826 | | fn getCompDir(self: Dwarf, module: *Module) []const u8 { |
| 1827 | | // For macOS stack traces, we want to avoid having to parse the compilation unit debug |
| 1828 | | // info. As long as each debug info file has a path independent of the compilation unit |
| 1829 | | // directory (DW_AT_comp_dir), then we never have to look at the compilation unit debug |
| 1830 | | // info. If we provide an absolute path to LLVM here for the compilation unit debug |
| 1831 | | // info, LLVM will emit DWARF info that depends on DW_AT_comp_dir. To avoid this, we |
| 1832 | | // pass "." for the compilation unit directory. This forces each debug file to have a |
| 1833 | | // directory rather than be relative to DW_AT_comp_dir. According to DWARF 5, debug |
| 1834 | | // files will no longer reference DW_AT_comp_dir, for the purpose of being able to |
| 1835 | | // support the common practice of stripping all but the line number sections from an |
| 1836 | | // executable. |
| 1837 | | if (self.bin_file.tag == .macho) return "."; |
| 1838 | | return module.root_pkg.root_src_directory.path orelse "."; |
| 1827 | fn resolveCompilationDir(module: *Module, buffer: *[std.fs.MAX_PATH_BYTES]u8) []const u8 { |
| 1828 | // We fully resolve all paths at this point to avoid lack of source line info in stack |
| 1829 | // traces or lack of debugging information which, if relative paths were used, would |
| 1830 | // be very location dependent. |
| 1831 | // TODO: the only concern I have with this is WASI as either host or target, should |
| 1832 | // we leave the paths as relative then? |
| 1833 | const comp_dir_path = module.root_pkg.root_src_directory.path orelse "."; |
| 1834 | if (std.fs.path.isAbsolute(comp_dir_path)) return comp_dir_path; |
| 1835 | return std.os.realpath(comp_dir_path, buffer) catch comp_dir_path; // If realpath fails, fallback to whatever comp_dir_path was |
| 1839 | 1836 | } |
| 1840 | 1837 | |
| 1841 | 1838 | fn writeAddrAssumeCapacity(self: *Dwarf, buf: *std.ArrayList(u8), addr: u64) void { |
| ... | ... | @@ -2149,7 +2146,7 @@ pub fn writeDbgAranges(self: *Dwarf, addr: u64, size: u64) !void { |
| 2149 | 2146 | } |
| 2150 | 2147 | } |
| 2151 | 2148 | |
| 2152 | | pub fn writeDbgLineHeader(self: *Dwarf, module: *Module) !void { |
| 2149 | pub fn writeDbgLineHeader(self: *Dwarf) !void { |
| 2153 | 2150 | const gpa = self.allocator; |
| 2154 | 2151 | |
| 2155 | 2152 | const ptr_width_bytes: u8 = self.ptrWidthBytes(); |
| ... | ... | @@ -2167,7 +2164,7 @@ pub fn writeDbgLineHeader(self: *Dwarf, module: *Module) !void { |
| 2167 | 2164 | // Convert all input DI files into a set of include dirs and file names. |
| 2168 | 2165 | var arena = std.heap.ArenaAllocator.init(gpa); |
| 2169 | 2166 | defer arena.deinit(); |
| 2170 | | const paths = try self.genIncludeDirsAndFileNames(arena.allocator(), module); |
| 2167 | const paths = try self.genIncludeDirsAndFileNames(arena.allocator()); |
| 2171 | 2168 | |
| 2172 | 2169 | // The size of this header is variable, depending on the number of directories, |
| 2173 | 2170 | // files, and padding. We have a function to compute the upper bound size, however, |
| ... | ... | @@ -2551,7 +2548,7 @@ fn addDIFile(self: *Dwarf, mod: *Module, decl_index: Module.Decl.Index) !u28 { |
| 2551 | 2548 | return @intCast(u28, gop.index + 1); |
| 2552 | 2549 | } |
| 2553 | 2550 | |
| 2554 | | fn genIncludeDirsAndFileNames(self: *Dwarf, arena: Allocator, module: *Module) !struct { |
| 2551 | fn genIncludeDirsAndFileNames(self: *Dwarf, arena: Allocator) !struct { |
| 2555 | 2552 | dirs: []const []const u8, |
| 2556 | 2553 | files: []const []const u8, |
| 2557 | 2554 | files_dirs_indexes: []u28, |
| ... | ... | @@ -2565,19 +2562,22 @@ fn genIncludeDirsAndFileNames(self: *Dwarf, arena: Allocator, module: *Module) ! |
| 2565 | 2562 | var files_dir_indexes = std.ArrayList(u28).init(arena); |
| 2566 | 2563 | try files_dir_indexes.ensureTotalCapacity(self.di_files.count()); |
| 2567 | 2564 | |
| 2568 | | const comp_dir = self.getCompDir(module); |
| 2569 | | |
| 2570 | 2565 | for (self.di_files.keys()) |dif| { |
| 2571 | | const full_path = try dif.fullPath(arena); |
| 2572 | | const dir_path = std.fs.path.dirname(full_path) orelse "."; |
| 2573 | | const sub_file_path = std.fs.path.basename(full_path); |
| 2566 | const dir_path = d: { |
| 2567 | var buffer: [std.fs.MAX_PATH_BYTES]u8 = undefined; |
| 2568 | const dir_path = dif.pkg.root_src_directory.path orelse "."; |
| 2569 | const abs_dir_path = if (std.fs.path.isAbsolute(dir_path)) |
| 2570 | dir_path |
| 2571 | else |
| 2572 | std.os.realpath(dir_path, &buffer) catch dir_path; // If realpath fails, fallback to whatever dir_path was |
| 2573 | break :d try std.fs.path.join(arena, &.{ |
| 2574 | abs_dir_path, std.fs.path.dirname(dif.sub_file_path) orelse "", |
| 2575 | }); |
| 2576 | }; |
| 2577 | const sub_file_path = try arena.dupe(u8, std.fs.path.basename(dif.sub_file_path)); |
| 2574 | 2578 | |
| 2575 | 2579 | const dir_index: u28 = blk: { |
| 2576 | | const actual_dir_path = if (mem.indexOf(u8, dir_path, comp_dir)) |_| inner: { |
| 2577 | | if (comp_dir.len == dir_path.len) break :blk 0; |
| 2578 | | break :inner dir_path[comp_dir.len + 1 ..]; |
| 2579 | | } else dir_path; |
| 2580 | | const dirs_gop = dirs.getOrPutAssumeCapacity(actual_dir_path); |
| 2580 | const dirs_gop = dirs.getOrPutAssumeCapacity(dir_path); |
| 2581 | 2581 | break :blk @intCast(u28, dirs_gop.index + 1); |
| 2582 | 2582 | }; |
| 2583 | 2583 | |