authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-12-07 22:29:07+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-12-09 09:24:25+01:00
log62145a1b0850f4def3f2ab401da7bed47045044d
treee2f50f7f324f8b5499313f0ecd3d138dcdd0cbb4
parent6817219e275a739794006d242bfa13840757b768

dwarf: refactor routine for precalculating size of dbg line header


1 files changed, 23 insertions(+), 18 deletions(-)

src/link/Dwarf.zig+23-18
...@@ -2303,7 +2303,6 @@ pub fn writeDbgLineHeader(self: *Dwarf, module: *Module) !void {...@@ -2303,7 +2303,6 @@ pub fn writeDbgLineHeader(self: *Dwarf, module: *Module) !void {
2303 // files, and padding. We have a function to compute the upper bound size, however,2303 // files, and padding. We have a function to compute the upper bound size, however,
2304 // because it's needed for determining where to put the offset of the first `SrcFn`.2304 // because it's needed for determining where to put the offset of the first `SrcFn`.
2305 const needed_bytes = self.dbgLineNeededHeaderBytes(paths.dirs, paths.files);2305 const needed_bytes = self.dbgLineNeededHeaderBytes(paths.dirs, paths.files);
2306 log.debug("dbg_line_prg_off = {x}, needed_bytes = {x}", .{ dbg_line_prg_off, needed_bytes });
2307 var di_buf = try std.ArrayList(u8).initCapacity(self.allocator, needed_bytes);2306 var di_buf = try std.ArrayList(u8).initCapacity(self.allocator, needed_bytes);
2308 defer di_buf.deinit();2307 defer di_buf.deinit();
23092308
...@@ -2390,6 +2389,8 @@ pub fn writeDbgLineHeader(self: *Dwarf, module: *Module) !void {...@@ -2390,6 +2389,8 @@ pub fn writeDbgLineHeader(self: *Dwarf, module: *Module) !void {
2390 },2389 },
2391 }2390 }
23922391
2392 assert(needed_bytes == di_buf.items.len);
2393
2393 // We use NOPs because consumers empirically do not respect the header length field.2394 // We use NOPs because consumers empirically do not respect the header length field.
2394 if (di_buf.items.len > dbg_line_prg_off) {2395 if (di_buf.items.len > dbg_line_prg_off) {
2395 // Move the first N files to the end to make more padding for the header.2396 // Move the first N files to the end to make more padding for the header.
...@@ -2448,27 +2449,31 @@ fn ptrWidthBytes(self: Dwarf) u8 {...@@ -2448,27 +2449,31 @@ fn ptrWidthBytes(self: Dwarf) u8 {
2448}2449}
24492450
2450fn dbgLineNeededHeaderBytes(self: Dwarf, dirs: []const []const u8, files: []const []const u8) u32 {2451fn dbgLineNeededHeaderBytes(self: Dwarf, dirs: []const []const u8, files: []const []const u8) u32 {
2451 _ = self;2452 var size = switch (self.bin_file.tag) { // length field
2452 const directory_entry_format_count = 1;2453 .macho => @sizeOf(u32),
2453 const file_name_entry_format_count = 1;2454 else => switch (self.ptr_width) {
2454 const directory_count = dirs.len + 1;2455 .p32 => @as(usize, @sizeOf(u32)),
2455 const file_name_count = files.len;2456 .p64 => @sizeOf(u32) + @sizeOf(u64),
24562457 },
2457 var dir_names_len: usize = 0;2458 };
2458 for (dirs) |dir| {2459 size += @sizeOf(u16); // version field
2459 dir_names_len += dir.len + 1;2460 size += switch (self.bin_file.tag) { // offset to end-of-header
2461 .macho => @sizeOf(u32),
2462 else => self.ptrWidthBytes(),
2463 };
2464 size += 18; // opcodes
2465
2466 for (dirs) |dir| { // include dirs
2467 size += dir.len + 1;
2460 }2468 }
2469 size += 1; // include dirs sentinel
24612470
2462 var file_names_len: usize = 0;2471 for (files) |file| { // file names
2463 for (files) |file| {2472 size += file.len + 1 + 1 + 1 + 1;
2464 file_names_len += file.len + 1;
2465 }2473 }
2474 size += 1; // file names sentinel
24662475
2467 return @intCast(u32, 53 + directory_entry_format_count * 2 + file_name_entry_format_count * 2 +2476 return @intCast(u32, size);
2468 directory_count * 8 + file_name_count * 8 +
2469 // These are encoded as DW.FORM.string rather than DW.FORM.strp as we would like
2470 // because of a workaround for readelf and gdb failing to understand DWARFv5 correctly.
2471 dir_names_len + file_names_len);
2472}2477}
24732478
2474/// The reloc offset for the line offset of a function from the previous function's line.2479/// The reloc offset for the line offset of a function from the previous function's line.