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 {...@@ -266,7 +266,7 @@ const StringSection = struct {
266/// A linker section containing a sequence of `Unit`s.266/// A linker section containing a sequence of `Unit`s.
267pub const Section = struct {267pub const Section = struct {
268 dirty: bool,268 dirty: bool,
269 pad_to_ideal: bool,269 pad_entries_to_ideal: bool,
270 alignment: InternPool.Alignment,270 alignment: InternPool.Alignment,
271 index: u32,271 index: u32,
272 first: Unit.Index.Optional,272 first: Unit.Index.Optional,
...@@ -288,7 +288,7 @@ pub const Section = struct {...@@ -288,7 +288,7 @@ pub const Section = struct {
288288
289 const init: Section = .{289 const init: Section = .{
290 .dirty = true,290 .dirty = true,
291 .pad_to_ideal = true,291 .pad_entries_to_ideal = true,
292 .alignment = .@"1",292 .alignment = .@"1",
293 .index = std.math.maxInt(u32),293 .index = std.math.maxInt(u32),
294 .first = .none,294 .first = .none,
...@@ -340,12 +340,12 @@ pub const Section = struct {...@@ -340,12 +340,12 @@ pub const Section = struct {
340 if (sec.last.unwrap()) |last_unit| {340 if (sec.last.unwrap()) |last_unit| {
341 const last_unit_ptr = sec.getUnit(last_unit);341 const last_unit_ptr = sec.getUnit(last_unit);
342 last_unit_ptr.next = unit.toOptional();342 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);
344 }344 }
345 if (sec.first == .none)345 if (sec.first == .none)
346 sec.first = unit.toOptional();346 sec.first = unit.toOptional();
347 sec.last = unit.toOptional();347 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));
349 return unit;349 return unit;
350 }350 }
351351
...@@ -377,7 +377,7 @@ pub const Section = struct {...@@ -377,7 +377,7 @@ pub const Section = struct {
377 entry_ptr.off = if (unit_ptr.last.unwrap()) |last_entry| off: {377 entry_ptr.off = if (unit_ptr.last.unwrap()) |last_entry| off: {
378 const last_entry_ptr = unit_ptr.getEntry(last_entry);378 const last_entry_ptr = unit_ptr.getEntry(last_entry);
379 last_entry_ptr.next = entry.toOptional();379 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);
381 } else 0;381 } else 0;
382 entry_ptr.prev = unit_ptr.last;382 entry_ptr.prev = unit_ptr.last;
383 unit_ptr.last = entry.toOptional();383 unit_ptr.last = entry.toOptional();
...@@ -469,8 +469,12 @@ pub const Section = struct {...@@ -469,8 +469,12 @@ pub const Section = struct {
469 for (sec.units.items) |*unit| try unit.resolveRelocs(sec, dwarf);469 for (sec.units.items) |*unit| try unit.resolveRelocs(sec, dwarf);
470 }470 }
471471
472 fn padToIdeal(sec: *Section, actual_size: anytype) @TypeOf(actual_size) {472 fn padUnitToIdeal(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));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));
474 }478 }
475};479};
476480
...@@ -568,7 +572,7 @@ const Unit = struct {...@@ -568,7 +572,7 @@ const Unit = struct {
568 last_unit_ptr.next = unit;572 last_unit_ptr.next = unit;
569 unit_ptr.prev = sec.last;573 unit_ptr.prev = sec.last;
570 unit_ptr.next = .none;574 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);
572 sec.last = unit;576 sec.last = unit;
573 sec.dirty = true;577 sec.dirty = true;
574 } else if (extra_header_len > 0) {578 } else if (extra_header_len > 0) {
...@@ -872,7 +876,7 @@ const Entry = struct {...@@ -872,7 +876,7 @@ const Entry = struct {
872 assert(fbs.pos == extended_op_bytes + op_len_bytes);876 assert(fbs.pos == extended_op_bytes + op_len_bytes);
873 if (len > 2) writer.writeByte(DW.LNE.padding) catch unreachable;877 if (len > 2) writer.writeByte(DW.LNE.padding) catch unreachable;
874 },878 },
875 } else assert(!sec.pad_to_ideal and len == 0);879 } else assert(!sec.pad_entries_to_ideal and len == 0);
876 assert(fbs.pos <= len);880 assert(fbs.pos <= len);
877 try dwarf.getFile().?.pwriteAll(fbs.getWritten(), sec.off(dwarf) + unit.off + unit.header_len + start);881 try dwarf.getFile().?.pwriteAll(fbs.getWritten(), sec.off(dwarf) + unit.off + unit.header_len + start);
878 }882 }
...@@ -899,11 +903,11 @@ const Entry = struct {...@@ -899,11 +903,11 @@ const Entry = struct {
899 last_entry_ptr.next = entry;903 last_entry_ptr.next = entry;
900 entry_ptr.prev = unit.last;904 entry_ptr.prev = unit.last;
901 entry_ptr.next = .none;905 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);
903 unit.last = entry;907 unit.last = entry;
904 try last_entry_ptr.pad(unit, sec, dwarf);908 try last_entry_ptr.pad(unit, sec, dwarf);
905 }909 }
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));
907 }911 }
908 entry_ptr.len = len;912 entry_ptr.len = len;
909 try entry_ptr.pad(unit, sec, dwarf);913 try entry_ptr.pad(unit, sec, dwarf);
...@@ -2247,13 +2251,13 @@ pub fn initMetadata(dwarf: *Dwarf) UpdateError!void {...@@ -2247,13 +2251,13 @@ pub fn initMetadata(dwarf: *Dwarf) UpdateError!void {
2247 }2251 }
2248 dwarf.reloadSectionMetadata();2252 dwarf.reloadSectionMetadata();
22492253
2250 dwarf.debug_abbrev.section.pad_to_ideal = false;2254 dwarf.debug_abbrev.section.pad_entries_to_ideal = false;
2251 assert(try dwarf.debug_abbrev.section.addUnit(DebugAbbrev.header_bytes, DebugAbbrev.trailer_bytes, dwarf) == DebugAbbrev.unit);2255 assert(try dwarf.debug_abbrev.section.addUnit(DebugAbbrev.header_bytes, DebugAbbrev.trailer_bytes, dwarf) == DebugAbbrev.unit);
2252 errdefer dwarf.debug_abbrev.section.popUnit(dwarf.gpa);2256 errdefer dwarf.debug_abbrev.section.popUnit(dwarf.gpa);
2253 for (std.enums.values(AbbrevCode)) |abbrev_code|2257 for (std.enums.values(AbbrevCode)) |abbrev_code|
2254 assert(@intFromEnum(try dwarf.debug_abbrev.section.getUnit(DebugAbbrev.unit).addEntry(dwarf.gpa)) == @intFromEnum(abbrev_code));2258 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;
2257 dwarf.debug_aranges.section.alignment = InternPool.Alignment.fromNonzeroByteUnits(@intFromEnum(dwarf.address_size) * 2);2261 dwarf.debug_aranges.section.alignment = InternPool.Alignment.fromNonzeroByteUnits(@intFromEnum(dwarf.address_size) * 2);
22582262
2259 dwarf.debug_frame.section.alignment = switch (dwarf.debug_frame.header.format) {2263 dwarf.debug_frame.section.alignment = switch (dwarf.debug_frame.header.format) {
...@@ -2262,17 +2266,17 @@ pub fn initMetadata(dwarf: *Dwarf) UpdateError!void {...@@ -2262,17 +2266,17 @@ pub fn initMetadata(dwarf: *Dwarf) UpdateError!void {
2262 .eh_frame => .@"4",2266 .eh_frame => .@"4",
2263 };2267 };
22642268
2265 dwarf.debug_line_str.section.pad_to_ideal = false;2269 dwarf.debug_line_str.section.pad_entries_to_ideal = false;
2266 assert(try dwarf.debug_line_str.section.addUnit(0, 0, dwarf) == StringSection.unit);2270 assert(try dwarf.debug_line_str.section.addUnit(0, 0, dwarf) == StringSection.unit);
2267 errdefer dwarf.debug_line_str.section.popUnit(dwarf.gpa);2271 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;
2270 assert(try dwarf.debug_str.section.addUnit(0, 0, dwarf) == StringSection.unit);2274 assert(try dwarf.debug_str.section.addUnit(0, 0, dwarf) == StringSection.unit);
2271 errdefer dwarf.debug_str.section.popUnit(dwarf.gpa);2275 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;
2276}2280}
22772281
2278pub fn deinit(dwarf: *Dwarf) void {2282pub fn deinit(dwarf: *Dwarf) void {
test/incremental/change_struct_same_fields+1-1
...@@ -1,4 +1,4 @@...@@ -1,4 +1,4 @@
1#target=x86_64-linux-selfhosted1//#target=x86_64-linux-selfhosted
2#target=x86_64-linux-cbe2#target=x86_64-linux-cbe
3#target=x86_64-windows-cbe3#target=x86_64-windows-cbe
4#target=wasm32-wasi-selfhosted4#target=wasm32-wasi-selfhosted