authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-12-05 22:34:10+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-12-09 09:24:25+01:00
log4c4821d9939447d65966b897a5780e39eb22334b
treee725c6d9d2363e42f4550d4b9ffd44f0a23ce422
parent5c67f9ce7a4d9f5aedbe8cfba1f361922701a144

dwarf: specify all referenced zig source files


1 files changed, 84 insertions(+), 15 deletions(-)

src/link/Dwarf.zig+84-15
...@@ -44,6 +44,11 @@ abbrev_table_offset: ?u64 = null,...@@ -44,6 +44,11 @@ abbrev_table_offset: ?u64 = null,
44/// Table of debug symbol names.44/// Table of debug symbol names.
45strtab: std.ArrayListUnmanaged(u8) = .{},45strtab: std.ArrayListUnmanaged(u8) = .{},
4646
47file_names_buffer: std.ArrayListUnmanaged(u8) = .{},
48file_names: std.ArrayListUnmanaged(u32) = .{},
49file_names_free_list: std.ArrayListUnmanaged(u28) = .{},
50file_names_lookup: std.AutoHashMapUnmanaged(*Module.File, u28) = .{},
51
47/// List of atoms that are owned directly by the DWARF module.52/// List of atoms that are owned directly by the DWARF module.
48/// TODO convert links in DebugInfoAtom into indices and make53/// TODO convert links in DebugInfoAtom into indices and make
49/// sure every atom is owned by this module.54/// sure every atom is owned by this module.
...@@ -906,6 +911,10 @@ pub fn deinit(self: *Dwarf) void {...@@ -906,6 +911,10 @@ pub fn deinit(self: *Dwarf) void {
906 self.dbg_line_fn_free_list.deinit(gpa);911 self.dbg_line_fn_free_list.deinit(gpa);
907 self.atom_free_list.deinit(gpa);912 self.atom_free_list.deinit(gpa);
908 self.strtab.deinit(gpa);913 self.strtab.deinit(gpa);
914 self.file_names_buffer.deinit(gpa);
915 self.file_names.deinit(gpa);
916 self.file_names_free_list.deinit(gpa);
917 self.file_names_lookup.deinit(gpa);
909 self.global_abbrev_relocs.deinit(gpa);918 self.global_abbrev_relocs.deinit(gpa);
910919
911 for (self.managed_atoms.items) |atom| {920 for (self.managed_atoms.items) |atom| {
...@@ -968,8 +977,12 @@ pub fn initDeclState(self: *Dwarf, mod: *Module, decl_index: Module.Decl.Index)...@@ -968,8 +977,12 @@ pub fn initDeclState(self: *Dwarf, mod: *Module, decl_index: Module.Decl.Index)
968 assert(self.getRelocDbgFileIndex() == dbg_line_buffer.items.len);977 assert(self.getRelocDbgFileIndex() == dbg_line_buffer.items.len);
969 // Once we support more than one source file, this will have the ability to be more978 // Once we support more than one source file, this will have the ability to be more
970 // than one possible value.979 // than one possible value.
971 const file_index = 1;980 const file_index = try self.addFileName(mod, decl_index);
972 leb128.writeUnsignedFixed(4, dbg_line_buffer.addManyAsArrayAssumeCapacity(4), file_index);981 leb128.writeUnsignedFixed(
982 4,
983 dbg_line_buffer.addManyAsArrayAssumeCapacity(4),
984 file_index + 1,
985 );
973986
974 // Emit a line for the begin curly with prologue_end=false. The codegen will987 // Emit a line for the begin curly with prologue_end=false. The codegen will
975 // do the work of setting prologue_end=true and epilogue_begin=true.988 // do the work of setting prologue_end=true and epilogue_begin=true.
...@@ -1132,7 +1145,8 @@ pub fn commitDeclState(...@@ -1132,7 +1145,8 @@ pub fn commitDeclState(
1132 self.dbg_line_fn_first = src_fn;1145 self.dbg_line_fn_first = src_fn;
1133 self.dbg_line_fn_last = src_fn;1146 self.dbg_line_fn_last = src_fn;
11341147
1135 src_fn.off = padToIdeal(self.dbgLineNeededHeaderBytes(module));1148 // TODO TEXME JK
1149 src_fn.off = padToIdeal(self.dbgLineNeededHeaderBytes(module) * 100);
1136 }1150 }
11371151
1138 const last_src_fn = self.dbg_line_fn_last.?;1152 const last_src_fn = self.dbg_line_fn_last.?;
...@@ -2271,6 +2285,7 @@ pub fn writeDbgLineHeader(self: *Dwarf, file: *File, module: *Module) !void {...@@ -2271,6 +2285,7 @@ pub fn writeDbgLineHeader(self: *Dwarf, file: *File, module: *Module) !void {
2271 // files, and padding. We have a function to compute the upper bound size, however,2285 // files, and padding. We have a function to compute the upper bound size, however,
2272 // because it's needed for determining where to put the offset of the first `SrcFn`.2286 // because it's needed for determining where to put the offset of the first `SrcFn`.
2273 const needed_bytes = self.dbgLineNeededHeaderBytes(module);2287 const needed_bytes = self.dbgLineNeededHeaderBytes(module);
2288 log.debug("dbg_line_prg_off = {x}, needed_bytes = {x}", .{ dbg_line_prg_off, needed_bytes });
2274 var di_buf = try std.ArrayList(u8).initCapacity(self.allocator, needed_bytes);2289 var di_buf = try std.ArrayList(u8).initCapacity(self.allocator, needed_bytes);
2275 defer di_buf.deinit();2290 defer di_buf.deinit();
22762291
...@@ -2325,15 +2340,28 @@ pub fn writeDbgLineHeader(self: *Dwarf, file: *File, module: *Module) !void {...@@ -2325,15 +2340,28 @@ pub fn writeDbgLineHeader(self: *Dwarf, file: *File, module: *Module) !void {
2325 1, // `DW.LNS.set_isa`2340 1, // `DW.LNS.set_isa`
2326 0, // include_directories (none except the compilation unit cwd)2341 0, // include_directories (none except the compilation unit cwd)
2327 });2342 });
2328 // file_names[0]2343 // // file_names[0]
2329 di_buf.appendSliceAssumeCapacity(module.root_pkg.root_src_path); // relative path name2344 // di_buf.appendSliceAssumeCapacity(module.root_pkg.root_src_path); // relative path name
2330 di_buf.appendSliceAssumeCapacity(&[_]u8{2345 // di_buf.appendSliceAssumeCapacity(&[_]u8{
2331 0, // null byte for the relative path name2346 // 0, // null byte for the relative path name
2332 0, // directory_index2347 // 0, // directory_index
2333 0, // mtime (TODO supply this)2348 // 0, // mtime (TODO supply this)
2334 0, // file size bytes (TODO supply this)2349 // 0, // file size bytes (TODO supply this)
2335 0, // file_names sentinel2350 // 0, // file_names sentinel
2336 });2351 // });
2352
2353 for (self.file_names.items) |off, i| {
2354 const file_name = self.getFileName(off);
2355 log.debug("file_name[{d}] = {s}", .{ i + 1, file_name });
2356 di_buf.appendSliceAssumeCapacity(file_name);
2357 di_buf.appendSliceAssumeCapacity(&[_]u8{
2358 0, // null byte for the relative path name
2359 0, // directory_index
2360 0, // mtime (TODO supply this)
2361 0, // file size bytes (TODO supply this)
2362 });
2363 }
2364 di_buf.appendAssumeCapacity(0); // file names sentinel
23372365
2338 const header_len = di_buf.items.len - after_header_len;2366 const header_len = di_buf.items.len - after_header_len;
2339 if (self.tag == .macho) {2367 if (self.tag == .macho) {
...@@ -2405,18 +2433,18 @@ fn ptrWidthBytes(self: Dwarf) u8 {...@@ -2405,18 +2433,18 @@ fn ptrWidthBytes(self: Dwarf) u8 {
2405}2433}
24062434
2407fn dbgLineNeededHeaderBytes(self: Dwarf, module: *Module) u32 {2435fn dbgLineNeededHeaderBytes(self: Dwarf, module: *Module) u32 {
2408 _ = self;
2409 const directory_entry_format_count = 1;2436 const directory_entry_format_count = 1;
2410 const file_name_entry_format_count = 1;2437 const file_name_entry_format_count = 1;
2411 const directory_count = 1;2438 const directory_count = 1;
2412 const file_name_count = 1;2439 const file_name_count = self.file_names.items.len;
2413 const root_src_dir_path_len = if (module.root_pkg.root_src_directory.path) |p| p.len else 1; // "."2440 const root_src_dir_path_len = if (module.root_pkg.root_src_directory.path) |p| p.len else 1; // "."
2441
2414 return @intCast(u32, 53 + directory_entry_format_count * 2 + file_name_entry_format_count * 2 +2442 return @intCast(u32, 53 + directory_entry_format_count * 2 + file_name_entry_format_count * 2 +
2415 directory_count * 8 + file_name_count * 8 +2443 directory_count * 8 + file_name_count * 8 +
2416 // These are encoded as DW.FORM.string rather than DW.FORM.strp as we would like2444 // These are encoded as DW.FORM.string rather than DW.FORM.strp as we would like
2417 // because of a workaround for readelf and gdb failing to understand DWARFv5 correctly.2445 // because of a workaround for readelf and gdb failing to understand DWARFv5 correctly.
2418 root_src_dir_path_len +2446 root_src_dir_path_len +
2419 module.root_pkg.root_src_path.len);2447 self.file_names_buffer.items.len);
2420}2448}
24212449
2422/// The reloc offset for the line offset of a function from the previous function's line.2450/// The reloc offset for the line offset of a function from the previous function's line.
...@@ -2527,6 +2555,47 @@ pub fn flushModule(self: *Dwarf, file: *File, module: *Module) !void {...@@ -2527,6 +2555,47 @@ pub fn flushModule(self: *Dwarf, file: *File, module: *Module) !void {
2527 }2555 }
2528}2556}
25292557
2558fn allocateFileIndex(self: *Dwarf) !u28 {
2559 try self.file_names.ensureUnusedCapacity(self.allocator, 1);
2560
2561 const index = blk: {
2562 if (self.file_names_free_list.popOrNull()) |index| {
2563 log.debug(" (reusing file name index {d})", .{index});
2564 break :blk index;
2565 } else {
2566 const index = @intCast(u28, self.file_names.items.len);
2567 log.debug(" (allocating file name index {d})", .{index});
2568 _ = self.file_names.addOneAssumeCapacity();
2569 break :blk index;
2570 }
2571 };
2572
2573 return index;
2574}
2575
2576fn addFileName(self: *Dwarf, mod: *Module, decl_index: Module.Decl.Index) !u28 {
2577 const decl = mod.declPtr(decl_index);
2578 const file_scope = decl.getFileScope();
2579 if (self.file_names_lookup.get(file_scope)) |file_index| {
2580 return file_index;
2581 }
2582 const index = try self.allocateFileIndex();
2583 const file_name = try file_scope.fullPath(self.allocator);
2584 defer self.allocator.free(file_name);
2585 try self.file_names_buffer.ensureUnusedCapacity(self.allocator, file_name.len + 1);
2586 const off = @intCast(u32, self.file_names_buffer.items.len);
2587 self.file_names_buffer.appendSliceAssumeCapacity(file_name);
2588 self.file_names_buffer.appendAssumeCapacity(0);
2589 self.file_names.items[index] = off;
2590 try self.file_names_lookup.putNoClobber(self.allocator, file_scope, index);
2591 return index;
2592}
2593
2594fn getFileName(self: Dwarf, off: u32) []const u8 {
2595 assert(off < self.file_names_buffer.items.len);
2596 return mem.sliceTo(@ptrCast([*:0]const u8, self.file_names_buffer.items.ptr) + off, 0);
2597}
2598
2530fn addDbgInfoErrorSet(2599fn addDbgInfoErrorSet(
2531 arena: Allocator,2600 arena: Allocator,
2532 module: *Module,2601 module: *Module,