authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-12-09 12:43:06+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-12-09 14:16:44+01:00
log4d640f9bb98d334f7fab8d3037a36cfd95dc174a
tree3800c31dcd1bb85003d2679cd516612f2071f366
parentbda5180b2ccfed22da04dd0b7a48d60beda03538

dwarf: resolve all relative paths when generating include_dirs and file_names lists


4 files changed, 30 insertions(+), 30 deletions(-)

src/link/Dwarf.zig+27-27
...@@ -1771,7 +1771,8 @@ pub fn writeDbgInfoHeader(self: *Dwarf, module: *Module, low_pc: u64, high_pc: u...@@ -1771,7 +1771,8 @@ pub fn writeDbgInfoHeader(self: *Dwarf, module: *Module, low_pc: u64, high_pc: u
1771 }1771 }
1772 // Write the form for the compile unit, which must match the abbrev table above.1772 // Write the form for the compile unit, which must match the abbrev table above.
1773 const name_strp = try self.makeString(module.root_pkg.root_src_path);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 const comp_dir_strp = try self.makeString(compile_unit_dir);1776 const comp_dir_strp = try self.makeString(compile_unit_dir);
1776 const producer_strp = try self.makeString(link.producer_string);1777 const producer_strp = try self.makeString(link.producer_string);
17771778
...@@ -1823,19 +1824,15 @@ pub fn writeDbgInfoHeader(self: *Dwarf, module: *Module, low_pc: u64, high_pc: u...@@ -1823,19 +1824,15 @@ pub fn writeDbgInfoHeader(self: *Dwarf, module: *Module, low_pc: u64, high_pc: u
1823 }1824 }
1824}1825}
18251826
1826fn getCompDir(self: Dwarf, module: *Module) []const u8 {1827fn resolveCompilationDir(module: *Module, buffer: *[std.fs.MAX_PATH_BYTES]u8) []const u8 {
1827 // For macOS stack traces, we want to avoid having to parse the compilation unit debug1828 // We fully resolve all paths at this point to avoid lack of source line info in stack
1828 // info. As long as each debug info file has a path independent of the compilation unit1829 // traces or lack of debugging information which, if relative paths were used, would
1829 // directory (DW_AT_comp_dir), then we never have to look at the compilation unit debug1830 // be very location dependent.
1830 // info. If we provide an absolute path to LLVM here for the compilation unit debug1831 // TODO: the only concern I have with this is WASI as either host or target, should
1831 // info, LLVM will emit DWARF info that depends on DW_AT_comp_dir. To avoid this, we1832 // we leave the paths as relative then?
1832 // pass "." for the compilation unit directory. This forces each debug file to have a1833 const comp_dir_path = module.root_pkg.root_src_directory.path orelse ".";
1833 // directory rather than be relative to DW_AT_comp_dir. According to DWARF 5, debug1834 if (std.fs.path.isAbsolute(comp_dir_path)) return comp_dir_path;
1834 // files will no longer reference DW_AT_comp_dir, for the purpose of being able to1835 return std.os.realpath(comp_dir_path, buffer) catch comp_dir_path; // If realpath fails, fallback to whatever comp_dir_path was
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 ".";
1839}1836}
18401837
1841fn writeAddrAssumeCapacity(self: *Dwarf, buf: *std.ArrayList(u8), addr: u64) void {1838fn 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,7 +2146,7 @@ pub fn writeDbgAranges(self: *Dwarf, addr: u64, size: u64) !void {
2149 }2146 }
2150}2147}
21512148
2152pub fn writeDbgLineHeader(self: *Dwarf, module: *Module) !void {2149pub fn writeDbgLineHeader(self: *Dwarf) !void {
2153 const gpa = self.allocator;2150 const gpa = self.allocator;
21542151
2155 const ptr_width_bytes: u8 = self.ptrWidthBytes();2152 const ptr_width_bytes: u8 = self.ptrWidthBytes();
...@@ -2167,7 +2164,7 @@ pub fn writeDbgLineHeader(self: *Dwarf, module: *Module) !void {...@@ -2167,7 +2164,7 @@ pub fn writeDbgLineHeader(self: *Dwarf, module: *Module) !void {
2167 // Convert all input DI files into a set of include dirs and file names.2164 // Convert all input DI files into a set of include dirs and file names.
2168 var arena = std.heap.ArenaAllocator.init(gpa);2165 var arena = std.heap.ArenaAllocator.init(gpa);
2169 defer arena.deinit();2166 defer arena.deinit();
2170 const paths = try self.genIncludeDirsAndFileNames(arena.allocator(), module);2167 const paths = try self.genIncludeDirsAndFileNames(arena.allocator());
21712168
2172 // The size of this header is variable, depending on the number of directories,2169 // The size of this header is variable, depending on the number of directories,
2173 // files, and padding. We have a function to compute the upper bound size, however,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,7 +2548,7 @@ fn addDIFile(self: *Dwarf, mod: *Module, decl_index: Module.Decl.Index) !u28 {
2551 return @intCast(u28, gop.index + 1);2548 return @intCast(u28, gop.index + 1);
2552}2549}
25532550
2554fn genIncludeDirsAndFileNames(self: *Dwarf, arena: Allocator, module: *Module) !struct {2551fn genIncludeDirsAndFileNames(self: *Dwarf, arena: Allocator) !struct {
2555 dirs: []const []const u8,2552 dirs: []const []const u8,
2556 files: []const []const u8,2553 files: []const []const u8,
2557 files_dirs_indexes: []u28,2554 files_dirs_indexes: []u28,
...@@ -2565,19 +2562,22 @@ fn genIncludeDirsAndFileNames(self: *Dwarf, arena: Allocator, module: *Module) !...@@ -2565,19 +2562,22 @@ fn genIncludeDirsAndFileNames(self: *Dwarf, arena: Allocator, module: *Module) !
2565 var files_dir_indexes = std.ArrayList(u28).init(arena);2562 var files_dir_indexes = std.ArrayList(u28).init(arena);
2566 try files_dir_indexes.ensureTotalCapacity(self.di_files.count());2563 try files_dir_indexes.ensureTotalCapacity(self.di_files.count());
25672564
2568 const comp_dir = self.getCompDir(module);
2569
2570 for (self.di_files.keys()) |dif| {2565 for (self.di_files.keys()) |dif| {
2571 const full_path = try dif.fullPath(arena);2566 const dir_path = d: {
2572 const dir_path = std.fs.path.dirname(full_path) orelse ".";2567 var buffer: [std.fs.MAX_PATH_BYTES]u8 = undefined;
2573 const sub_file_path = std.fs.path.basename(full_path);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));
25742578
2575 const dir_index: u28 = blk: {2579 const dir_index: u28 = blk: {
2576 const actual_dir_path = if (mem.indexOf(u8, dir_path, comp_dir)) |_| inner: {2580 const dirs_gop = dirs.getOrPutAssumeCapacity(dir_path);
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);
2581 break :blk @intCast(u28, dirs_gop.index + 1);2581 break :blk @intCast(u28, dirs_gop.index + 1);
2582 };2582 };
25832583
src/link/Elf.zig+1-1
...@@ -1149,7 +1149,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node...@@ -1149,7 +1149,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node
1149 }1149 }
11501150
1151 if (self.debug_line_header_dirty) {1151 if (self.debug_line_header_dirty) {
1152 try dw.writeDbgLineHeader(module);1152 try dw.writeDbgLineHeader();
1153 self.debug_line_header_dirty = false;1153 self.debug_line_header_dirty = false;
1154 }1154 }
1155 }1155 }
src/link/MachO/DebugSymbols.zig+1-1
...@@ -281,7 +281,7 @@ pub fn flushModule(self: *DebugSymbols, macho_file: *MachO) !void {...@@ -281,7 +281,7 @@ pub fn flushModule(self: *DebugSymbols, macho_file: *MachO) !void {
281 }281 }
282282
283 if (self.debug_line_header_dirty) {283 if (self.debug_line_header_dirty) {
284 try self.dwarf.writeDbgLineHeader(module);284 try self.dwarf.writeDbgLineHeader();
285 self.debug_line_header_dirty = false;285 self.debug_line_header_dirty = false;
286 }286 }
287287
src/link/Wasm.zig+1-1
...@@ -2672,7 +2672,7 @@ pub fn flushModule(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Nod...@@ -2672,7 +2672,7 @@ pub fn flushModule(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Nod
2672 // as locations are always offsets relative to 'code' section.2672 // as locations are always offsets relative to 'code' section.
2673 try dwarf.writeDbgInfoHeader(mod, 0, code_section_size);2673 try dwarf.writeDbgInfoHeader(mod, 0, code_section_size);
2674 try dwarf.writeDbgAranges(0, code_section_size);2674 try dwarf.writeDbgAranges(0, code_section_size);
2675 try dwarf.writeDbgLineHeader(mod);2675 try dwarf.writeDbgLineHeader();
2676 }2676 }
26772677
2678 var debug_bytes = std.ArrayList(u8).init(wasm.base.allocator);2678 var debug_bytes = std.ArrayList(u8).init(wasm.base.allocator);