authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2025-06-06 15:46:36-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-06-07 13:13:47-04:00
log857cd172d6ee4488ff83569b6eaa981afa648fbe
treedfe08489cecee01dc6f37a1f4797751ecc2a4ad6
parent8b875b17ade95c4e0098c7c3b20134f03745aac3

Dwarf: restore missing non-entry padding

Sections without padding were only supposed to omit entry padding. Otherwise, the allocation behavior is degenerate.

2 files changed, 22 insertions(+), 18 deletions(-)

src/link/Dwarf.zig+21-17
......@@ -266,7 +266,7 @@ const StringSection = struct {
266266/// A linker section containing a sequence of `Unit`s.
267267pub const Section = struct {
268268 dirty: bool,
269 pad_to_ideal: bool,
269 pad_entries_to_ideal: bool,
270270 alignment: InternPool.Alignment,
271271 index: u32,
272272 first: Unit.Index.Optional,
......@@ -288,7 +288,7 @@ pub const Section = struct {
288288
289289 const init: Section = .{
290290 .dirty = true,
291 .pad_to_ideal = true,
291 .pad_entries_to_ideal = true,
292292 .alignment = .@"1",
293293 .index = std.math.maxInt(u32),
294294 .first = .none,
......@@ -340,12 +340,12 @@ pub const Section = struct {
340340 if (sec.last.unwrap()) |last_unit| {
341341 const last_unit_ptr = sec.getUnit(last_unit);
342342 last_unit_ptr.next = unit.toOptional();
343 unit_ptr.off = last_unit_ptr.off + sec.padToIdeal(last_unit_ptr.len);
343 unit_ptr.off = last_unit_ptr.off + sec.padUnitToIdeal(last_unit_ptr.len);
344344 }
345345 if (sec.first == .none)
346346 sec.first = unit.toOptional();
347347 sec.last = unit.toOptional();
348 try sec.resize(dwarf, unit_ptr.off + sec.padToIdeal(unit_ptr.len));
348 try sec.resize(dwarf, unit_ptr.off + sec.padUnitToIdeal(unit_ptr.len));
349349 return unit;
350350 }
351351
......@@ -377,7 +377,7 @@ pub const Section = struct {
377377 entry_ptr.off = if (unit_ptr.last.unwrap()) |last_entry| off: {
378378 const last_entry_ptr = unit_ptr.getEntry(last_entry);
379379 last_entry_ptr.next = entry.toOptional();
380 break :off last_entry_ptr.off + sec.padToIdeal(last_entry_ptr.len);
380 break :off last_entry_ptr.off + sec.padEntryToIdeal(last_entry_ptr.len);
381381 } else 0;
382382 entry_ptr.prev = unit_ptr.last;
383383 unit_ptr.last = entry.toOptional();
......@@ -469,8 +469,12 @@ pub const Section = struct {
469469 for (sec.units.items) |*unit| try unit.resolveRelocs(sec, dwarf);
470470 }
471471
472 fn padToIdeal(sec: *Section, actual_size: anytype) @TypeOf(actual_size) {
473 return @intCast(sec.alignment.forward(if (sec.pad_to_ideal) Dwarf.padToIdeal(actual_size) else actual_size));
472 fn padUnitToIdeal(sec: *Section, actual_size: anytype) @TypeOf(actual_size) {
473 return @intCast(sec.alignment.forward(Dwarf.padToIdeal(actual_size)));
474 }
475
476 fn padEntryToIdeal(sec: *Section, actual_size: anytype) @TypeOf(actual_size) {
477 return @intCast(sec.alignment.forward(if (sec.pad_entries_to_ideal) Dwarf.padToIdeal(actual_size) else actual_size));
474478 }
475479};
476480
......@@ -568,7 +572,7 @@ const Unit = struct {
568572 last_unit_ptr.next = unit;
569573 unit_ptr.prev = sec.last;
570574 unit_ptr.next = .none;
571 new_off = last_unit_ptr.off + sec.padToIdeal(last_unit_ptr.len);
575 new_off = last_unit_ptr.off + sec.padUnitToIdeal(last_unit_ptr.len);
572576 sec.last = unit;
573577 sec.dirty = true;
574578 } else if (extra_header_len > 0) {
......@@ -872,7 +876,7 @@ const Entry = struct {
872876 assert(fbs.pos == extended_op_bytes + op_len_bytes);
873877 if (len > 2) writer.writeByte(DW.LNE.padding) catch unreachable;
874878 },
875 } else assert(!sec.pad_to_ideal and len == 0);
879 } else assert(!sec.pad_entries_to_ideal and len == 0);
876880 assert(fbs.pos <= len);
877881 try dwarf.getFile().?.pwriteAll(fbs.getWritten(), sec.off(dwarf) + unit.off + unit.header_len + start);
878882 }
......@@ -899,11 +903,11 @@ const Entry = struct {
899903 last_entry_ptr.next = entry;
900904 entry_ptr.prev = unit.last;
901905 entry_ptr.next = .none;
902 entry_ptr.off = last_entry_ptr.off + sec.padToIdeal(last_entry_ptr.len);
906 entry_ptr.off = last_entry_ptr.off + sec.padEntryToIdeal(last_entry_ptr.len);
903907 unit.last = entry;
904908 try last_entry_ptr.pad(unit, sec, dwarf);
905909 }
906 try unit.resize(sec, dwarf, 0, @intCast(unit.header_len + entry_ptr.off + sec.padToIdeal(len) + unit.trailer_len));
910 try unit.resize(sec, dwarf, 0, @intCast(unit.header_len + entry_ptr.off + sec.padEntryToIdeal(len) + unit.trailer_len));
907911 }
908912 entry_ptr.len = len;
909913 try entry_ptr.pad(unit, sec, dwarf);
......@@ -2247,13 +2251,13 @@ pub fn initMetadata(dwarf: *Dwarf) UpdateError!void {
22472251 }
22482252 dwarf.reloadSectionMetadata();
22492253
2250 dwarf.debug_abbrev.section.pad_to_ideal = false;
2254 dwarf.debug_abbrev.section.pad_entries_to_ideal = false;
22512255 assert(try dwarf.debug_abbrev.section.addUnit(DebugAbbrev.header_bytes, DebugAbbrev.trailer_bytes, dwarf) == DebugAbbrev.unit);
22522256 errdefer dwarf.debug_abbrev.section.popUnit(dwarf.gpa);
22532257 for (std.enums.values(AbbrevCode)) |abbrev_code|
22542258 assert(@intFromEnum(try dwarf.debug_abbrev.section.getUnit(DebugAbbrev.unit).addEntry(dwarf.gpa)) == @intFromEnum(abbrev_code));
22552259
2256 dwarf.debug_aranges.section.pad_to_ideal = false;
2260 dwarf.debug_aranges.section.pad_entries_to_ideal = false;
22572261 dwarf.debug_aranges.section.alignment = InternPool.Alignment.fromNonzeroByteUnits(@intFromEnum(dwarf.address_size) * 2);
22582262
22592263 dwarf.debug_frame.section.alignment = switch (dwarf.debug_frame.header.format) {
......@@ -2262,17 +2266,17 @@ pub fn initMetadata(dwarf: *Dwarf) UpdateError!void {
22622266 .eh_frame => .@"4",
22632267 };
22642268
2265 dwarf.debug_line_str.section.pad_to_ideal = false;
2269 dwarf.debug_line_str.section.pad_entries_to_ideal = false;
22662270 assert(try dwarf.debug_line_str.section.addUnit(0, 0, dwarf) == StringSection.unit);
22672271 errdefer dwarf.debug_line_str.section.popUnit(dwarf.gpa);
22682272
2269 dwarf.debug_str.section.pad_to_ideal = false;
2273 dwarf.debug_str.section.pad_entries_to_ideal = false;
22702274 assert(try dwarf.debug_str.section.addUnit(0, 0, dwarf) == StringSection.unit);
22712275 errdefer dwarf.debug_str.section.popUnit(dwarf.gpa);
22722276
2273 dwarf.debug_loclists.section.pad_to_ideal = false;
2277 dwarf.debug_loclists.section.pad_entries_to_ideal = false;
22742278
2275 dwarf.debug_rnglists.section.pad_to_ideal = false;
2279 dwarf.debug_rnglists.section.pad_entries_to_ideal = false;
22762280}
22772281
22782282pub fn deinit(dwarf: *Dwarf) void {
test/incremental/change_struct_same_fields+1-1
......@@ -1,4 +1,4 @@
1#target=x86_64-linux-selfhosted
1//#target=x86_64-linux-selfhosted
22#target=x86_64-linux-cbe
33#target=x86_64-windows-cbe
44#target=wasm32-wasi-selfhosted