authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2026-08-31 21:07:34-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2026-09-03 12:59:38-04:00
log00116e2c7d68d35284c8e671d7d00d59f76149bd
tree4b59ffac464e0a2a5b34c4b59bcebc0f964fdf36
parent566b6a6ec0ac2aa847fc3c8572c2404dcb67b51e

Elf2: use footer nodes to ensure space for trailing padding

This avoids needing to call `ensureMinimumSize` manually.

3 files changed, 146 insertions(+), 88 deletions(-)

src/link/Dwarf2.zig+6
...@@ -31,6 +31,7 @@ pub const Unit = struct {...@@ -31,6 +31,7 @@ pub const Unit = struct {
31 cie_ni: MappedFile.Node.Index.Optional,31 cie_ni: MappedFile.Node.Index.Optional,
32 debug_info_ni: MappedFile.Node.Index.Optional,32 debug_info_ni: MappedFile.Node.Index.Optional,
33 debug_info_header_ni: MappedFile.Node.Index.Optional,33 debug_info_header_ni: MappedFile.Node.Index.Optional,
34 debug_info_footer_ni: MappedFile.Node.Index.Optional,
34 debug_line_ni: MappedFile.Node.Index.Optional,35 debug_line_ni: MappedFile.Node.Index.Optional,
35 debug_line_header_ni: MappedFile.Node.Index.Optional,36 debug_line_header_ni: MappedFile.Node.Index.Optional,
36 debug_line_header_changed: bool,37 debug_line_header_changed: bool,
...@@ -1339,6 +1340,7 @@ pub fn initUnits(dwarf: *Dwarf, gpa: std.mem.Allocator, units_len: usize) std.me...@@ -1339,6 +1340,7 @@ pub fn initUnits(dwarf: *Dwarf, gpa: std.mem.Allocator, units_len: usize) std.me
1339 .cie_ni = .none,1340 .cie_ni = .none,
1340 .debug_info_ni = .none,1341 .debug_info_ni = .none,
1341 .debug_info_header_ni = .none,1342 .debug_info_header_ni = .none,
1343 .debug_info_footer_ni = .none,
1342 .debug_line_ni = .none,1344 .debug_line_ni = .none,
1343 .debug_line_header_ni = .none,1345 .debug_line_header_ni = .none,
1344 .debug_line_header_changed = false,1346 .debug_line_header_changed = false,
...@@ -1944,6 +1946,7 @@ pub fn updateComptimeNav(...@@ -1944,6 +1946,7 @@ pub fn updateComptimeNav(
1944 _ = try dwarf.const_pool.get(pt, .{ .elf2 = dwarf.lf.cast(.elf2).? }, nav_val.toIntern());1946 _ = try dwarf.const_pool.get(pt, .{ .elf2 = dwarf.lf.cast(.elf2).? }, nav_val.toIntern());
1945 break :done;1947 break :done;
1946 }1948 }
1949 return;
1947 },1950 },
1948 .enum_type => {1951 .enum_type => {
1949 const loaded_enum = ip.loadEnumType(nav_val.toIntern());1952 const loaded_enum = ip.loadEnumType(nav_val.toIntern());
...@@ -1951,6 +1954,7 @@ pub fn updateComptimeNav(...@@ -1951,6 +1954,7 @@ pub fn updateComptimeNav(
1951 _ = try dwarf.const_pool.get(pt, .{ .elf2 = dwarf.lf.cast(.elf2).? }, nav_val.toIntern());1954 _ = try dwarf.const_pool.get(pt, .{ .elf2 = dwarf.lf.cast(.elf2).? }, nav_val.toIntern());
1952 break :done;1955 break :done;
1953 }1956 }
1957 return;
1954 },1958 },
1955 .union_type => {1959 .union_type => {
1956 const loaded_union = ip.loadUnionType(nav_val.toIntern());1960 const loaded_union = ip.loadUnionType(nav_val.toIntern());
...@@ -1958,6 +1962,7 @@ pub fn updateComptimeNav(...@@ -1958,6 +1962,7 @@ pub fn updateComptimeNav(
1958 _ = try dwarf.const_pool.get(pt, .{ .elf2 = dwarf.lf.cast(.elf2).? }, nav_val.toIntern());1962 _ = try dwarf.const_pool.get(pt, .{ .elf2 = dwarf.lf.cast(.elf2).? }, nav_val.toIntern());
1959 break :done;1963 break :done;
1960 }1964 }
1965 return;
1961 },1966 },
1962 .opaque_type => {1967 .opaque_type => {
1963 const loaded_opaque = ip.loadOpaqueType(nav_val.toIntern());1968 const loaded_opaque = ip.loadOpaqueType(nav_val.toIntern());
...@@ -1965,6 +1970,7 @@ pub fn updateComptimeNav(...@@ -1965,6 +1970,7 @@ pub fn updateComptimeNav(
1965 _ = try dwarf.const_pool.get(pt, .{ .elf2 = dwarf.lf.cast(.elf2).? }, nav_val.toIntern());1970 _ = try dwarf.const_pool.get(pt, .{ .elf2 = dwarf.lf.cast(.elf2).? }, nav_val.toIntern());
1966 break :done;1971 break :done;
1967 }1972 }
1973 return;
1968 },1974 },
1969 .func => |func| if (func.owner_nav == nav_index and func.generic_owner == .none) {1975 .func => |func| if (func.owner_nav == nav_index and func.generic_owner == .none) {
1970 const fi = try dwarf.getFunc(func.owner_nav);1976 const fi = try dwarf.getFunc(func.owner_nav);
src/link/Elf2.zig+136-88
...@@ -287,11 +287,13 @@ const Node = union(enum) {...@@ -287,11 +287,13 @@ const Node = union(enum) {
287 lazy_const_data: LazyMapRef.Index(.const_data),287 lazy_const_data: LazyMapRef.Index(.const_data),
288288
289 debug_shared: Dwarf.SharedSection,289 debug_shared: Dwarf.SharedSection,
290 eh_frame_footer,
290 unit_padding,291 unit_padding,
291 unit_frame: Dwarf.Unit.Index,292 unit_frame: Dwarf.Unit.Index,
292 unit_frame_cie: Dwarf.Unit.Index,293 unit_frame_cie: Dwarf.Unit.Index,
293 unit_debug_info: Dwarf.Unit.Index,294 unit_debug_info: Dwarf.Unit.Index,
294 unit_debug_info_header: Dwarf.Unit.Index,295 unit_debug_info_header: Dwarf.Unit.Index,
296 unit_debug_info_footer: Dwarf.Unit.Index,
295 unit_debug_line: Dwarf.Unit.Index,297 unit_debug_line: Dwarf.Unit.Index,
296 unit_debug_line_header: Dwarf.Unit.Index,298 unit_debug_line_header: Dwarf.Unit.Index,
297 unit_debug_rnglists: Dwarf.Unit.Index,299 unit_debug_rnglists: Dwarf.Unit.Index,
...@@ -564,8 +566,8 @@ const Section = struct {...@@ -564,8 +566,8 @@ const Section = struct {
564 std.elf.SHN_LORESERVE...std.elf.SHN_HIRESERVE => @fromBackingInt(reserve(sec)),566 std.elf.SHN_LORESERVE...std.elf.SHN_HIRESERVE => @fromBackingInt(reserve(sec)),
565 };567 };
566 }568 }
567 pub fn toSection(s: Index) ?std.elf.Section {569 pub fn toSection(shndx: Index) ?std.elf.Section {
568 return switch (@backingInt(s)) {570 return switch (@backingInt(shndx)) {
569 std.elf.SHN_UNDEF...std.elf.SHN_LORESERVE - 1 => |sec| @intCast(sec),571 std.elf.SHN_UNDEF...std.elf.SHN_LORESERVE - 1 => |sec| @intCast(sec),
570 std.elf.SHN_LORESERVE...reserve(std.elf.SHN_LORESERVE) - 1 => null,572 std.elf.SHN_LORESERVE...reserve(std.elf.SHN_LORESERVE) - 1 => null,
571 reserve(std.elf.SHN_LORESERVE)...reserve(std.elf.SHN_HIRESERVE) => |sec| @intCast(573 reserve(std.elf.SHN_LORESERVE)...reserve(std.elf.SHN_HIRESERVE) => |sec| @intCast(
...@@ -574,28 +576,40 @@ const Section = struct {...@@ -574,28 +576,40 @@ const Section = struct {
574 };576 };
575 }577 }
576578
577 fn get(s: Index, elf: *Elf) *Section {579 fn get(shndx: Index, elf: *Elf) *Section {
578 return &elf.shdrs.items[@backingInt(s) - 1]; // overflow means you tried to get the `.UNDEF` section580 return &elf.shdrs.items[@backingInt(shndx) - 1]; // overflow means you tried to get the `.UNDEF` section
579 }581 }
580582
581 fn name(s: Index, elf: *Elf) String(.shstrtab) {583 fn name(shndx: Index, elf: *Elf) String(.shstrtab) {
582 return switch (elf.shdrPtr(s)) {584 return switch (elf.shdrPtr(shndx)) {
583 inline else => |shdr| @fromBackingInt(elf.targetLoad(&shdr.name)),585 inline else => |shdr| @fromBackingInt(elf.targetLoad(&shdr.name)),
584 };586 };
585 }587 }
586588
587 fn vaddr(s: Index, elf: *Elf) u64 {589 fn vaddr(shndx: Index, elf: *Elf) u64 {
588 return switch (elf.shdrPtr(s)) {590 return switch (elf.shdrPtr(shndx)) {
589 inline else => |shdr| elf.targetLoad(&shdr.addr),591 inline else => |shdr| elf.targetLoad(&shdr.addr),
590 };592 };
591 }593 }
592594
593 fn size(s: Index, elf: *Elf) u64 {595 fn size(shndx: Index, elf: *Elf) u64 {
594 return switch (elf.shdrPtr(s)) {596 return switch (elf.shdrPtr(shndx)) {
595 inline else => |shdr| elf.targetLoad(&shdr.size),597 inline else => |shdr| elf.targetLoad(&shdr.size),
596 };598 };
597 }599 }
598600
601 fn setSize(shndx: Index, elf: *Elf, new_size: u64) void {
602 return switch (elf.shdrPtr(shndx)) {
603 inline else => |shdr| {
604 elf.targetStore(&shdr.type, switch (new_size) {
605 0 => .NULL,
606 else => .PROGBITS,
607 });
608 elf.targetStore(&shdr.size, @intCast(new_size));
609 },
610 };
611 }
612
599 fn flags(s: Index, elf: *Elf) std.elf.SHF {613 fn flags(s: Index, elf: *Elf) std.elf.SHF {
600 return switch (elf.shdrPtr(s)) {614 return switch (elf.shdrPtr(s)) {
601 inline else => |shdr| elf.targetLoad(&shdr.flags).shf,615 inline else => |shdr| elf.targetLoad(&shdr.flags).shf,
...@@ -853,6 +867,15 @@ const Section = struct {...@@ -853,6 +867,15 @@ const Section = struct {
853 }867 }
854 };868 };
855};869};
870fn debugFrameFooterSize(elf: *Elf, frame_format: Dwarf.Frame.Format) usize {
871 return switch (frame_format) {
872 .eh_frame => switch (elf.ehdrType()) {
873 .REL => 0,
874 .EXEC, .DYN => 4,
875 },
876 .debug_frame => 0,
877 };
878}
856879
857const dwarf_relocs = struct {880const dwarf_relocs = struct {
858 const Shared = struct {881 const Shared = struct {
...@@ -3324,11 +3347,13 @@ pub fn symbolForAtom(elf: *Elf, atom: link.File.AtomId) link.File.SymbolId {...@@ -3324,11 +3347,13 @@ pub fn symbolForAtom(elf: *Elf, atom: link.File.AtomId) link.File.SymbolId {
3324 .input_section,3347 .input_section,
3325 .copied_global,3348 .copied_global,
3326 .debug_shared,3349 .debug_shared,
3350 .eh_frame_footer,
3327 .unit_padding,3351 .unit_padding,
3328 .unit_frame,3352 .unit_frame,
3329 .unit_frame_cie,3353 .unit_frame_cie,
3330 .unit_debug_info,3354 .unit_debug_info,
3331 .unit_debug_info_header,3355 .unit_debug_info_header,
3356 .unit_debug_info_footer,
3332 .unit_debug_line,3357 .unit_debug_line,
3333 .unit_debug_line_header,3358 .unit_debug_line_header,
3334 .unit_debug_rnglists,3359 .unit_debug_rnglists,
...@@ -4074,7 +4099,8 @@ fn initHeaders(...@@ -4074,7 +4099,8 @@ fn initHeaders(
4074 const expected_nodes_len = @as(usize, if (is_archive) 3 else 0) + // .archive, .archive_header, .archive_elf_member_header4099 const expected_nodes_len = @as(usize, if (is_archive) 3 else 0) + // .archive, .archive_header, .archive_elf_member_header
4075 3 + // `.elf`, `.ehdr`, and `.shdr` nodes4100 3 + // `.elf`, `.ehdr`, and `.shdr` nodes
4076 (shnum - 1) + // -1 because the SHN_UNDEF shdr does not have a `.section` node4101 (shnum - 1) + // -1 because the SHN_UNDEF shdr does not have a `.section` node
4077 (phnum -| 1); // -1 because the GNU_STACK phdr does not have a `.segment` node4102 (phnum -| 1) + // -1 because the GNU_STACK phdr does not have a `.segment` node
4103 @intFromBool(have_eh_frame and @"type" != .REL); // eh_frame_footer
40784104
4079 try elf.nodes.ensureTotalCapacity(gpa, expected_nodes_len);4105 try elf.nodes.ensureTotalCapacity(gpa, expected_nodes_len);
4080 try elf.shdrs.ensureTotalCapacity(gpa, shnum - 1); // -1 to exclude SHN_UNDEF4106 try elf.shdrs.ensureTotalCapacity(gpa, shnum - 1); // -1 to exclude SHN_UNDEF
...@@ -4841,7 +4867,7 @@ fn initHeaders(...@@ -4841,7 +4867,7 @@ fn initHeaders(
4841 }4867 }
4842 }4868 }
4843 if (have_eh_frame) {4869 if (have_eh_frame) {
4844 elf.ni.gnu_eh_frame = .wrap(elf.addNodeAssumeCapacity(4870 const gnu_eh_frame = elf.addNodeAssumeCapacity(
4845 try elf.ni.rodata.addFloatingChild(gpa, &elf.mf, .{4871 try elf.ni.rodata.addFloatingChild(gpa, &elf.mf, .{
4846 .size = @sizeOf(Dwarf.EhFrameHdr),4872 .size = @sizeOf(Dwarf.EhFrameHdr),
4847 .alignment = .@"4",4873 .alignment = .@"4",
...@@ -4849,10 +4875,11 @@ fn initHeaders(...@@ -4849,10 +4875,11 @@ fn initHeaders(
4849 .bubbles_moved = false,4875 .bubbles_moved = false,
4850 }),4876 }),
4851 .{ .segment = phndx.gnu_eh_frame },4877 .{ .segment = phndx.gnu_eh_frame },
4852 ));4878 );
4879 elf.ni.gnu_eh_frame = .wrap(gnu_eh_frame);
4853 elf.phdrs.items[phndx.gnu_eh_frame] = elf.ni.gnu_eh_frame;4880 elf.phdrs.items[phndx.gnu_eh_frame] = elf.ni.gnu_eh_frame;
48544881
4855 elf.shndx.eh_frame_hdr = try elf.addSection(elf.ni.gnu_eh_frame.unwrap().?, .{4882 elf.shndx.eh_frame_hdr = try elf.addSection(gnu_eh_frame, .{
4856 .name = ".eh_frame_hdr",4883 .name = ".eh_frame_hdr",
4857 .type = .PROGBITS,4884 .type = .PROGBITS,
4858 .flags = .{ .ALLOC = true },4885 .flags = .{ .ALLOC = true },
...@@ -4864,7 +4891,9 @@ fn initHeaders(...@@ -4864,7 +4891,9 @@ fn initHeaders(
4864 .flags = .{ .ALLOC = true },4891 .flags = .{ .ALLOC = true },
4865 .addralign = addr_align,4892 .addralign = addr_align,
4866 .node_align = elf.mf.flags.block_size,4893 .node_align = elf.mf.flags.block_size,
4894 .manual_size = true,
4867 });4895 });
4896
4868 const eh_frame_hdr_ni = elf.shndx.eh_frame_hdr.get(elf).ni;4897 const eh_frame_hdr_ni = elf.shndx.eh_frame_hdr.get(elf).ni;
4869 elf.eh_frame_hdr_first_symbol_reloc =4898 elf.eh_frame_hdr_first_symbol_reloc =
4870 @fromBackingInt(@intCast(elf.symbol_relocs.items.len));4899 @fromBackingInt(@intCast(elf.symbol_relocs.items.len));
...@@ -4873,6 +4902,13 @@ fn initHeaders(...@@ -4873,6 +4902,13 @@ fn initHeaders(
4873 @ptrCast(@alignCast(eh_frame_hdr_ni.slice(&elf.mf))),4902 @ptrCast(@alignCast(eh_frame_hdr_ni.slice(&elf.mf))),
4874 Symbol.Id.local(elf.shndx.eh_frame.get(elf).lsi).toTypeErased(),4903 Symbol.Id.local(elf.shndx.eh_frame.get(elf).lsi).toTypeErased(),
4875 );4904 );
4905 _ = elf.addNodeAssumeCapacity(
4906 try elf.shndx.eh_frame.get(elf).ni.addOnlyFooterChild(gpa, &elf.mf, .{
4907 .size = addr_align.forward(4),
4908 .alignment = addr_align,
4909 }),
4910 .eh_frame_footer,
4911 );
4876 }4912 }
48774913
4878 // Populate reserved GOT words.4914 // Populate reserved GOT words.
...@@ -5057,6 +5093,7 @@ fn initHeaders(...@@ -5057,6 +5093,7 @@ fn initHeaders(
5057 .flags = .{ .ALLOC = true },5093 .flags = .{ .ALLOC = true },
5058 .addralign = addr_align,5094 .addralign = addr_align,
5059 .node_align = elf.mf.flags.block_size,5095 .node_align = elf.mf.flags.block_size,
5096 .manual_size = true,
5060 });5097 });
5061 }5098 }
5062 if (elf.ni.tls.unwrap()) |tls_segment_ni| elf.shndx.tdata = try elf.addSection(tls_segment_ni, .{5099 if (elf.ni.tls.unwrap()) |tls_segment_ni| elf.shndx.tdata = try elf.addSection(tls_segment_ni, .{
...@@ -5072,6 +5109,7 @@ fn initHeaders(...@@ -5072,6 +5109,7 @@ fn initHeaders(
5072 .name = ".debug_frame",5109 .name = ".debug_frame",
5073 .addralign = addr_align,5110 .addralign = addr_align,
5074 .node_align = elf.mf.flags.block_size,5111 .node_align = elf.mf.flags.block_size,
5112 .manual_size = true,
5075 });5113 });
5076 elf.shndx.debug_info = try elf.addSection(elf.ni.elf, .{5114 elf.shndx.debug_info = try elf.addSection(elf.ni.elf, .{
5077 .name = ".debug_info",5115 .name = ".debug_info",
...@@ -5189,14 +5227,19 @@ fn getNodeShndx(elf: *const Elf, ni: MappedFile.Node.Index) Section.Index {...@@ -5189,14 +5227,19 @@ fn getNodeShndx(elf: *const Elf, ni: MappedFile.Node.Index) Section.Index {
5189 .lazy_code,5227 .lazy_code,
5190 .lazy_const_data,5228 .lazy_const_data,
5191 .debug_shared,5229 .debug_shared,
5230 .eh_frame_footer,
5192 .unit_padding,5231 .unit_padding,
5193 .unit_frame,5232 .unit_frame,
5194 .unit_debug_info,5233 .unit_debug_info,
5195 .unit_debug_line,5234 .unit_debug_line,
5196 .unit_debug_rnglists,5235 .unit_debug_rnglists,
5197 => elf.getNode(ni.parent(&elf.mf).unwrap().?).section,5236 => switch (elf.getNode(ni.parent(&elf.mf).unwrap().?)) {
5237 else => unreachable,
5238 .section, .section_manual_size => |shndx| shndx,
5239 },
5198 .unit_frame_cie,5240 .unit_frame_cie,
5199 .unit_debug_info_header,5241 .unit_debug_info_header,
5242 .unit_debug_info_footer,
5200 .unit_debug_line_header,5243 .unit_debug_line_header,
5201 .const_debug_info,5244 .const_debug_info,
5202 .global_debug_info,5245 .global_debug_info,
...@@ -5204,7 +5247,10 @@ fn getNodeShndx(elf: *const Elf, ni: MappedFile.Node.Index) Section.Index {...@@ -5204,7 +5247,10 @@ fn getNodeShndx(elf: *const Elf, ni: MappedFile.Node.Index) Section.Index {
5204 .func_debug_info,5247 .func_debug_info,
5205 .func_debug_line,5248 .func_debug_line,
5206 .decl_debug_info,5249 .decl_debug_info,
5207 => elf.getNode(ni.parent(&elf.mf).unwrap().?.parent(&elf.mf).unwrap().?).section,5250 => switch (elf.getNode(ni.parent(&elf.mf).unwrap().?.parent(&elf.mf).unwrap().?)) {
5251 else => unreachable,
5252 .section, .section_manual_size => |shndx| shndx,
5253 },
5208 };5254 };
5209}5255}
5210fn getNodeVAddr(elf: *Elf, ni: MappedFile.Node.Index) u64 {5256fn getNodeVAddr(elf: *Elf, ni: MappedFile.Node.Index) u64 {
...@@ -5228,11 +5274,13 @@ fn getNodeVAddr(elf: *Elf, ni: MappedFile.Node.Index) u64 {...@@ -5228,11 +5274,13 @@ fn getNodeVAddr(elf: *Elf, ni: MappedFile.Node.Index) u64 {
5228 .lazy_const_data,5274 .lazy_const_data,
5229 => |i| Symbol.Id.local(i.symbol(elf)).value(elf),5275 => |i| Symbol.Id.local(i.symbol(elf)).value(elf),
5230 .debug_shared,5276 .debug_shared,
5277 .eh_frame_footer,
5231 .unit_padding,5278 .unit_padding,
5232 .unit_frame,5279 .unit_frame,
5233 .unit_frame_cie,5280 .unit_frame_cie,
5234 .unit_debug_info,5281 .unit_debug_info,
5235 .unit_debug_info_header,5282 .unit_debug_info_header,
5283 .unit_debug_info_footer,
5236 .unit_debug_line,5284 .unit_debug_line,
5237 .unit_debug_line_header,5285 .unit_debug_line_header,
5238 .unit_debug_rnglists,5286 .unit_debug_rnglists,
...@@ -5266,14 +5314,14 @@ fn computeNodeVAddr(elf: *Elf, ni: MappedFile.Node.Index) u64 {...@@ -5266,14 +5314,14 @@ fn computeNodeVAddr(elf: *Elf, ni: MappedFile.Node.Index) u64 {
5266 .lazy_code,5314 .lazy_code,
5267 .lazy_const_data,5315 .lazy_const_data,
5268 => |i| Symbol.Id.local(i.symbol(elf)).value(elf),5316 => |i| Symbol.Id.local(i.symbol(elf)).value(elf),
5269 .debug_shared, .unit_padding => unreachable,5317 .debug_shared, .eh_frame_footer, .unit_padding => unreachable,
5270 .unit_frame, .unit_debug_info, .unit_debug_line => {5318 .unit_frame, .unit_debug_info, .unit_debug_line => {
5271 const section_ni = parent_ni.parent(&elf.mf).unwrap().?;
5272 const section_offset, _ = parent_ni.location(&elf.mf).resolve(&elf.mf);5319 const section_offset, _ = parent_ni.location(&elf.mf).resolve(&elf.mf);
5273 break :parent_vaddr elf.getNode(section_ni).section.vaddr(elf) + section_offset;5320 break :parent_vaddr elf.getNodeShndx(parent_ni).vaddr(elf) + section_offset;
5274 },5321 },
5275 .unit_frame_cie,5322 .unit_frame_cie,
5276 .unit_debug_info_header,5323 .unit_debug_info_header,
5324 .unit_debug_info_footer,
5277 .unit_debug_line_header,5325 .unit_debug_line_header,
5278 .unit_debug_rnglists,5326 .unit_debug_rnglists,
5279 .const_debug_info,5327 .const_debug_info,
...@@ -5303,13 +5351,14 @@ fn computeNodeSectionOffset(elf: *Elf, ni: MappedFile.Node.Index) u64 {...@@ -5303,13 +5351,14 @@ fn computeNodeSectionOffset(elf: *Elf, ni: MappedFile.Node.Index) u64 {
5303 .section, .section_manual_size => 0,5351 .section, .section_manual_size => 0,
5304 .input_section, .copied_global => unreachable,5352 .input_section, .copied_global => unreachable,
5305 .nav, .uav, .lazy_code, .lazy_const_data => unreachable,5353 .nav, .uav, .lazy_code, .lazy_const_data => unreachable,
5306 .debug_shared, .unit_padding => unreachable,5354 .debug_shared, .eh_frame_footer, .unit_padding => unreachable,
5307 .unit_frame, .unit_debug_info, .unit_debug_line => {5355 .unit_frame, .unit_debug_info, .unit_debug_line => {
5308 const parent_section_offset, _ = parent_ni.location(&elf.mf).resolve(&elf.mf);5356 const parent_section_offset, _ = parent_ni.location(&elf.mf).resolve(&elf.mf);
5309 break :parent_section_offset parent_section_offset;5357 break :parent_section_offset parent_section_offset;
5310 },5358 },
5311 .unit_frame_cie,5359 .unit_frame_cie,
5312 .unit_debug_info_header,5360 .unit_debug_info_header,
5361 .unit_debug_info_footer,
5313 .unit_debug_line_header,5362 .unit_debug_line_header,
5314 .unit_debug_rnglists,5363 .unit_debug_rnglists,
5315 .const_debug_info,5364 .const_debug_info,
...@@ -5351,6 +5400,7 @@ pub fn resetNodeRelocs(elf: *Elf, ni: MappedFile.Node.Index) void {...@@ -5351,6 +5400,7 @@ pub fn resetNodeRelocs(elf: *Elf, ni: MappedFile.Node.Index) void {
5351 .segment,5400 .segment,
5352 .copied_global,5401 .copied_global,
5353 .debug_shared,5402 .debug_shared,
5403 .eh_frame_footer,
5354 .unit_padding,5404 .unit_padding,
5355 .unit_frame,5405 .unit_frame,
5356 .unit_frame_cie,5406 .unit_frame_cie,
...@@ -5378,10 +5428,11 @@ pub fn resetNodeRelocs(elf: *Elf, ni: MappedFile.Node.Index) void {...@@ -5378,10 +5428,11 @@ pub fn resetNodeRelocs(elf: *Elf, ni: MappedFile.Node.Index) void {
5378 .unit_debug_info_header => |ui| .{5428 .unit_debug_info_header => |ui| .{
5379 .first_node_reloc = &elf.dwarf_units[@backingInt(ui)].debug_info_header_first_node_reloc,5429 .first_node_reloc = &elf.dwarf_units[@backingInt(ui)].debug_info_header_first_node_reloc,
5380 },5430 },
5431 .unit_debug_info_footer => unreachable, // cannot contain relocs
5381 .unit_debug_line_header => |ui| .{5432 .unit_debug_line_header => |ui| .{
5382 .first_node_reloc = &elf.dwarf_units[@backingInt(ui)].debug_line_header_first_node_reloc,5433 .first_node_reloc = &elf.dwarf_units[@backingInt(ui)].debug_line_header_first_node_reloc,
5383 },5434 },
5384 .unit_debug_rnglists => unreachable, // unsupported5435 .unit_debug_rnglists => unreachable, // cannot contain relocs
5385 .const_debug_info => |cpi| .{5436 .const_debug_info => |cpi| .{
5386 .first_symbol_reloc = &elf.dwarf_consts.getPtr(cpi).?.debug_info_first_symbol_reloc,5437 .first_symbol_reloc = &elf.dwarf_consts.getPtr(cpi).?.debug_info_first_symbol_reloc,
5387 .first_node_reloc = &elf.dwarf_consts.getPtr(cpi).?.debug_info_first_node_reloc,5438 .first_node_reloc = &elf.dwarf_consts.getPtr(cpi).?.debug_info_first_node_reloc,
...@@ -6049,7 +6100,7 @@ fn uavMapIndex(...@@ -6049,7 +6100,7 @@ fn uavMapIndex(
6049 elf.pending_uavs.appendAssumeCapacity(umi);6100 elf.pending_uavs.appendAssumeCapacity(umi);
6050 } else {6101 } else {
6051 const node = uav_gop.value_ptr.lsi.index().ptr(elf).node.unwrap().?;6102 const node = uav_gop.value_ptr.lsi.index().ptr(elf).node.unwrap().?;
6052 const shndx = elf.getNode(node.parent(&elf.mf).unwrap().?).section;6103 const shndx = elf.getNodeShndx(node);
6053 try shndx.ensureAligned(elf, resolved_align);6104 try shndx.ensureAligned(elf, resolved_align);
6054 if (resolved_align.order(node.alignment(&elf.mf)).compare(.gt)) {6105 if (resolved_align.order(node.alignment(&elf.mf)).compare(.gt)) {
6055 try node.realign(gpa, &elf.mf, resolved_align);6106 try node.realign(gpa, &elf.mf, resolved_align);
...@@ -7261,13 +7312,17 @@ fn zcuFilesReadyInner(elf: *Elf, zcu: *Zcu) Error!void {...@@ -7261,13 +7312,17 @@ fn zcuFilesReadyInner(elf: *Elf, zcu: *Zcu) Error!void {
7261 unit.debug_info_ni = .wrap(debug_info_ni);7312 unit.debug_info_ni = .wrap(debug_info_ni);
7262 break :debug_info_ni debug_info_ni;7313 break :debug_info_ni debug_info_ni;
7263 };7314 };
7264
7265 if (unit.debug_info_header_ni == .none) unit.debug_info_header_ni = .wrap(7315 if (unit.debug_info_header_ni == .none) unit.debug_info_header_ni = .wrap(
7266 elf.addNodeAssumeCapacity(try debug_info_ni.addOnlyHeaderChild(gpa, &elf.mf, .{7316 elf.addNodeAssumeCapacity(try debug_info_ni.addOnlyHeaderChild(gpa, &elf.mf, .{
7267 .next_moved = true,7317 .next_moved = true,
7268 .enable_next_moved = true,7318 .enable_next_moved = true,
7269 }), .{ .unit_debug_info_header = ui }),7319 }), .{ .unit_debug_info_header = ui }),
7270 );7320 );
7321 if (unit.debug_info_footer_ni == .none) unit.debug_info_footer_ni = .wrap(
7322 elf.addNodeAssumeCapacity(try debug_info_ni.addOnlyFooterChild(gpa, &elf.mf, .{
7323 .size = comptime Dwarf.uleb128Size(@backingInt(Dwarf.AbbrevCode.null)) * 2,
7324 }), .{ .unit_debug_info_footer = ui }),
7325 );
7271 },7326 },
7272 }7327 }
7273 switch (elf.shndx.debug_line) {7328 switch (elf.shndx.debug_line) {
...@@ -7284,7 +7339,6 @@ fn zcuFilesReadyInner(elf: *Elf, zcu: *Zcu) Error!void {...@@ -7284,7 +7339,6 @@ fn zcuFilesReadyInner(elf: *Elf, zcu: *Zcu) Error!void {
7284 unit.debug_line_ni = .wrap(debug_line_ni);7339 unit.debug_line_ni = .wrap(debug_line_ni);
7285 break :debug_line_ni debug_line_ni;7340 break :debug_line_ni debug_line_ni;
7286 };7341 };
7287
7288 if (unit.debug_line_header_ni == .none) unit.debug_line_header_ni = .wrap(7342 if (unit.debug_line_header_ni == .none) unit.debug_line_header_ni = .wrap(
7289 elf.addNodeAssumeCapacity(try debug_line_ni.addOnlyHeaderChild(gpa, &elf.mf, .{7343 elf.addNodeAssumeCapacity(try debug_line_ni.addOnlyHeaderChild(gpa, &elf.mf, .{
7290 // Idle tasks are going to try to keep this up to date before we are able to7344 // Idle tasks are going to try to keep this up to date before we are able to
...@@ -8264,11 +8318,13 @@ fn addGotRelocAssumeCapacity(...@@ -8264,11 +8318,13 @@ fn addGotRelocAssumeCapacity(
8264 .segment,8318 .segment,
8265 .copied_global,8319 .copied_global,
8266 .debug_shared,8320 .debug_shared,
8321 .eh_frame_footer,
8267 .unit_padding,8322 .unit_padding,
8268 .unit_frame,8323 .unit_frame,
8269 .unit_frame_cie,8324 .unit_frame_cie,
8270 .unit_debug_info,8325 .unit_debug_info,
8271 .unit_debug_info_header,8326 .unit_debug_info_header,
8327 .unit_debug_info_footer,
8272 .unit_debug_line,8328 .unit_debug_line,
8273 .unit_debug_line_header,8329 .unit_debug_line_header,
8274 .unit_debug_rnglists,8330 .unit_debug_rnglists,
...@@ -8601,6 +8657,7 @@ fn updateNavInner(elf: *Elf, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index)...@@ -8601,6 +8657,7 @@ fn updateNavInner(elf: *Elf, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index)
86018657
8602 // The NAV's node is done---now generate any UAVs or lazy code/data which the NAV needs.8658 // The NAV's node is done---now generate any UAVs or lazy code/data which the NAV needs.
8603 try elf.genPending(pt);8659 try elf.genPending(pt);
8660 try elf.dwarf.const_pool.flushPending(pt, .{ .elf2 = elf });
8604}8661}
86058662
8606pub fn updateContainerType(8663pub fn updateContainerType(
...@@ -8932,33 +8989,12 @@ fn updateFuncInner(...@@ -8932,33 +8989,12 @@ fn updateFuncInner(
8932 switch (elf.symPtr(nmi.symbol(elf).index())) {8989 switch (elf.symPtr(nmi.symbol(elf).index())) {
8933 inline else => |sym| elf.targetStore(&sym.size, @intCast(func_length)),8990 inline else => |sym| elf.targetStore(&sym.size, @intCast(func_length)),
8934 }8991 }
8935 debug_output: switch (debug_output) {8992 switch (debug_output) {
8936 .dwarf => unreachable,8993 .dwarf => unreachable,
8937 .eh_frame => |wip_nav| {8994 .eh_frame => |wip_nav| wip_nav.finishDebugFrameFde(func_length),
8938 wip_nav.finishDebugFrameFde(func_length);
8939 const frame_ni = switch (wip_nav.frame_format) {
8940 .debug_frame => elf.shndx.debug_frame,
8941 .eh_frame => elf.shndx.eh_frame,
8942 }.get(elf).ni;
8943 switch (wip_nav.frame_format) {
8944 .debug_frame => {},
8945 .eh_frame => {
8946 const last_offset, const last_size =
8947 frame_ni.last(&elf.mf).unwrap().?.location(&elf.mf).resolve(&elf.mf);
8948 try frame_ni.ensureMinimumSize(gpa, &elf.mf, last_offset + last_size + 4);
8949 },
8950 }
8951 },
8952 .dwarf2 => |debug| {8995 .dwarf2 => |debug| {
8953 try debug.finishFunc(func_length);8996 try debug.finishFunc(func_length);
8954 const unit = debug.wip_nav.unit.get(debug.wip_nav.dwarf);8997 const unit = debug.wip_nav.unit.get(debug.wip_nav.dwarf);
8955 {
8956 const debug_info_ni = unit.debug_info_ni.unwrap().?;
8957 const last_offset, const last_size =
8958 debug_info_ni.last(&elf.mf).unwrap().?.location(&elf.mf).resolve(&elf.mf);
8959 try debug_info_ni.ensureMinimumSize(gpa, &elf.mf, last_offset + last_size +
8960 comptime Dwarf.uleb128Size(@backingInt(Dwarf.AbbrevCode.null)) * 2);
8961 }
8962 {8998 {
8963 var dr_nw: MappedFile.Node.Writer = undefined;8999 var dr_nw: MappedFile.Node.Writer = undefined;
8964 unit.debug_rnglists_ni.unwrap().?.writer(gpa, &elf.mf, &dr_nw);9000 unit.debug_rnglists_ni.unwrap().?.writer(gpa, &elf.mf, &dr_nw);
...@@ -8983,7 +9019,7 @@ fn updateFuncInner(...@@ -8983,7 +9019,7 @@ fn updateFuncInner(
8983 {},9019 {},
8984 );9020 );
8985 }9021 }
8986 continue :debug_output .{ .eh_frame = &debug.wip_nav };9022 debug.wip_nav.finishDebugFrameFde(func_length);
8987 },9023 },
8988 .none => {},9024 .none => {},
8989 }9025 }
...@@ -8991,6 +9027,7 @@ fn updateFuncInner(...@@ -8991,6 +9027,7 @@ fn updateFuncInner(
89919027
8992 // The NAV's node is done---now generate any UAVs or lazy code/data which the NAV needs.9028 // The NAV's node is done---now generate any UAVs or lazy code/data which the NAV needs.
8993 try elf.genPending(pt);9029 try elf.genPending(pt);
9030 try elf.dwarf.const_pool.flushPending(pt, .{ .elf2 = elf });
8994}9031}
89959032
8996pub fn updateLineNumber(9033pub fn updateLineNumber(
...@@ -9297,7 +9334,7 @@ fn idleProgNode(...@@ -9297,7 +9334,7 @@ fn idleProgNode(
9297 break :name std.mem.print(&name, "{f}{f} {s}", .{9334 break :name std.mem.print(&name, "{f}{f} {s}", .{
9298 ii.path(elf).fmtEscapeString(),9335 ii.path(elf).fmtEscapeString(),
9299 fmtMemberString(ii.member(elf)),9336 fmtMemberString(ii.member(elf)),
9300 elf.getNode(isi.node(elf).parent(&elf.mf).unwrap().?).section.name(elf).slice(elf),9337 elf.getNodeShndx(isi.node(elf)).name(elf).slice(elf),
9301 }) catch &name;9338 }) catch &name;
9302 },9339 },
9303 .nav => |nmi| {9340 .nav => |nmi| {
...@@ -9316,6 +9353,7 @@ fn idleProgNode(...@@ -9316,6 +9353,7 @@ fn idleProgNode(
9316 .unit_frame_cie,9353 .unit_frame_cie,
9317 .unit_debug_info,9354 .unit_debug_info,
9318 .unit_debug_info_header,9355 .unit_debug_info_header,
9356 .unit_debug_info_footer,
9319 .unit_debug_line,9357 .unit_debug_line,
9320 .unit_debug_line_header,9358 .unit_debug_line_header,
9321 .unit_debug_rnglists,9359 .unit_debug_rnglists,
...@@ -9323,7 +9361,11 @@ fn idleProgNode(...@@ -9323,7 +9361,11 @@ fn idleProgNode(
9323 switch (tag) {9361 switch (tag) {
9324 else => unreachable,9362 else => unreachable,
9325 .unit_frame, .unit_frame_cie => "unwind",9363 .unit_frame, .unit_frame_cie => "unwind",
9326 .unit_debug_info, .unit_debug_info_header, .unit_debug_rnglists => "debug",9364 .unit_debug_info,
9365 .unit_debug_info_header,
9366 .unit_debug_info_footer,
9367 .unit_debug_rnglists,
9368 => "debug",
9327 .unit_debug_line, .unit_debug_line_header => "line",9369 .unit_debug_line, .unit_debug_line_header => "line",
9328 },9370 },
9329 ui.mod(&elf.dwarf).fully_qualified_name,9371 ui.mod(&elf.dwarf).fully_qualified_name,
...@@ -9393,7 +9435,6 @@ fn genPending(elf: *Elf, pt: Zcu.PerThread) link.Error!void {...@@ -9393,7 +9435,6 @@ fn genPending(elf: *Elf, pt: Zcu.PerThread) link.Error!void {
9393 elf.resetNodeRelocs(debug_info_ni);9435 elf.resetNodeRelocs(debug_info_ni);
9394 try elf.dwarf.genDecl(pt, &di_nw, pending.instance_val);9436 try elf.dwarf.genDecl(pt, &di_nw, pending.instance_val);
9395 }9437 }
9396 try elf.dwarf.const_pool.flushPending(pt, .{ .elf2 = elf });
9397 },9438 },
9398 .code_view => unreachable,9439 .code_view => unreachable,
9399 }9440 }
...@@ -9555,7 +9596,7 @@ fn flushInputSection(elf: *Elf, isi: InputSection.Index) Error!void {...@@ -9555,7 +9596,7 @@ fn flushInputSection(elf: *Elf, isi: InputSection.Index) Error!void {
9555 fr.seekTo(file_loc.offset) catch |err| switch (err) {9596 fr.seekTo(file_loc.offset) catch |err| switch (err) {
9556 error.Canceled => |e| return e,9597 error.Canceled => |e| return e,
9557 else => |e| return diags.fail("failed to read input section '{s}' from \"{f}{f}\": {t}", .{9598 else => |e| return diags.fail("failed to read input section '{s}' from \"{f}{f}\": {t}", .{
9558 elf.getNode(isi.node(elf).parent(&elf.mf).unwrap().?).section.name(elf).slice(elf),9599 elf.getNodeShndx(isi.node(elf)).name(elf).slice(elf),
9559 path.fmtEscapeString(),9600 path.fmtEscapeString(),
9560 fmtMemberString(ii.member(elf)),9601 fmtMemberString(ii.member(elf)),
9561 e,9602 e,
...@@ -9566,7 +9607,7 @@ fn flushInputSection(elf: *Elf, isi: InputSection.Index) Error!void {...@@ -9566,7 +9607,7 @@ fn flushInputSection(elf: *Elf, isi: InputSection.Index) Error!void {
9566 defer nw.deinit();9607 defer nw.deinit();
9567 const n_bytes = nw.interface.sendFileAll(&fr, .limited(@intCast(file_loc.size))) catch |err| switch (err) {9608 const n_bytes = nw.interface.sendFileAll(&fr, .limited(@intCast(file_loc.size))) catch |err| switch (err) {
9568 error.ReadFailed => return diags.fail("failed to read input section '{s}' from \"{f}{f}\": {t}", .{9609 error.ReadFailed => return diags.fail("failed to read input section '{s}' from \"{f}{f}\": {t}", .{
9569 elf.getNode(isi.node(elf).parent(&elf.mf).unwrap().?).section.name(elf).slice(elf),9610 elf.getNodeShndx(isi.node(elf)).name(elf).slice(elf),
9570 path.fmtEscapeString(),9611 path.fmtEscapeString(),
9571 fmtMemberString(ii.member(elf)),9612 fmtMemberString(ii.member(elf)),
9572 fr.err orelse (fr.seek_err orelse fr.size_err.?),9613 fr.err orelse (fr.seek_err orelse fr.size_err.?),
...@@ -9574,7 +9615,7 @@ fn flushInputSection(elf: *Elf, isi: InputSection.Index) Error!void {...@@ -9574,7 +9615,7 @@ fn flushInputSection(elf: *Elf, isi: InputSection.Index) Error!void {
9574 error.WriteFailed => return nw.err.?,9615 error.WriteFailed => return nw.err.?,
9575 };9616 };
9576 if (n_bytes != file_loc.size) return diags.fail("failed to read input section '{s}' from \"{f}{f}\": unexpected eof", .{9617 if (n_bytes != file_loc.size) return diags.fail("failed to read input section '{s}' from \"{f}{f}\": unexpected eof", .{
9577 elf.getNode(isi.node(elf).parent(&elf.mf).unwrap().?).section.name(elf).slice(elf),9618 elf.getNodeShndx(isi.node(elf)).name(elf).slice(elf),
9578 path.fmtEscapeString(),9619 path.fmtEscapeString(),
9579 fmtMemberString(ii.member(elf)),9620 fmtMemberString(ii.member(elf)),
9580 });9621 });
...@@ -9797,7 +9838,7 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void...@@ -9797,7 +9838,7 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void
9797 target_ri = target_reloc.next;9838 target_ri = target_reloc.next;
9798 }9839 }
9799 },9840 },
9800 .unit_padding, .unit_frame, .unit_debug_info, .unit_debug_line => {},9841 .eh_frame_footer, .unit_padding, .unit_frame, .unit_debug_info, .unit_debug_line => {},
9801 .unit_frame_cie => |ui| {9842 .unit_frame_cie => |ui| {
9802 const target_section_offset = elf.computeNodeSectionOffset(ni);9843 const target_section_offset = elf.computeNodeSectionOffset(ni);
9803 var target_ri = elf.dwarf_units[@backingInt(ui)].frame_cie_first_target_reloc;9844 var target_ri = elf.dwarf_units[@backingInt(ui)].frame_cie_first_target_reloc;
...@@ -9822,6 +9863,7 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void...@@ -9822,6 +9863,7 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void
9822 .first_node_reloc = dwarf_unit.debug_info_header_first_node_reloc,9863 .first_node_reloc = dwarf_unit.debug_info_header_first_node_reloc,
9823 });9864 });
9824 },9865 },
9866 .unit_debug_info_footer => {},
9825 .unit_debug_line_header => |ui| {9867 .unit_debug_line_header => |ui| {
9826 const dwarf_unit = &elf.dwarf_units[@backingInt(ui)];9868 const dwarf_unit = &elf.dwarf_units[@backingInt(ui)];
9827 const target_section_offset = elf.computeNodeSectionOffset(ni);9869 const target_section_offset = elf.computeNodeSectionOffset(ni);
...@@ -10179,11 +10221,13 @@ fn flushResized(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!vo...@@ -10179,11 +10221,13 @@ fn flushResized(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!vo
10179 .lazy_code,10221 .lazy_code,
10180 .lazy_const_data,10222 .lazy_const_data,
10181 .debug_shared,10223 .debug_shared,
10224 .eh_frame_footer,
10182 .unit_padding,10225 .unit_padding,
10183 .unit_frame,10226 .unit_frame,
10184 .unit_frame_cie,10227 .unit_frame_cie,
10185 .unit_debug_info,10228 .unit_debug_info,
10186 .unit_debug_info_header,10229 .unit_debug_info_header,
10230 .unit_debug_info_footer,
10187 .unit_debug_line,10231 .unit_debug_line,
10188 .unit_debug_line_header,10232 .unit_debug_line_header,
10189 .unit_debug_rnglists,10233 .unit_debug_rnglists,
...@@ -10219,6 +10263,8 @@ fn flushNextMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!...@@ -10219,6 +10263,8 @@ fn flushNextMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!
10219 .lazy_code,10263 .lazy_code,
10220 .lazy_const_data,10264 .lazy_const_data,
10221 .debug_shared,10265 .debug_shared,
10266 .eh_frame_footer,
10267 .unit_debug_info_footer,
10222 => unreachable,10268 => unreachable,
1022310269
10224 .archive_header => {10270 .archive_header => {
...@@ -10261,7 +10307,7 @@ fn flushNextMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!...@@ -10261,7 +10307,7 @@ fn flushNextMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!
10261 => |_, tag| {10307 => |_, tag| {
10262 const offset, const size = ni.location(&elf.mf).resolve(&elf.mf);10308 const offset, const size = ni.location(&elf.mf).resolve(&elf.mf);
10263 const parent_ni = ni.parent(&elf.mf).unwrap().?;10309 const parent_ni = ni.parent(&elf.mf).unwrap().?;
10264 const slice = if (ni.next(&elf.mf).unwrap()) |next_ni| slice: {10310 const slice = if (ni.next(&elf.mf).ifPos(&elf.mf, .floating).unwrap()) |next_ni| slice: {
10265 const parent_slice = parent_ni.slicePadding(&elf.mf);10311 const parent_slice = parent_ni.slicePadding(&elf.mf);
10266 const next_offset, _ = next_ni.location(&elf.mf).resolve(&elf.mf);10312 const next_offset, _ = next_ni.location(&elf.mf).resolve(&elf.mf);
10267 break :slice parent_slice[@intCast(offset)..@intCast(next_offset)];10313 break :slice parent_slice[@intCast(offset)..@intCast(next_offset)];
...@@ -10269,40 +10315,35 @@ fn flushNextMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!...@@ -10269,40 +10315,35 @@ fn flushNextMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!
10269 else => unreachable,10315 else => unreachable,
10270 .unit_padding, .unit_debug_rnglists => {10316 .unit_padding, .unit_debug_rnglists => {
10271 const parent_slice = parent_ni.slicePadding(&elf.mf);10317 const parent_slice = parent_ni.slicePadding(&elf.mf);
10272 switch (elf.getNode(parent_ni).section.debugFrameFormat(elf) orelse .debug_frame) {10318 const frame_shndx = elf.getNodeShndx(parent_ni);
10273 .eh_frame => {10319 const frame_format = frame_shndx.debugFrameFormat(elf) orelse
10274 const end = parent_slice.len - 4;10320 break :slice parent_slice[@intCast(offset)..];
10275 std.mem.writeInt(u32, parent_slice[end..][0..4], 0, elf.dwarf.endian);10321 const footer_size = elf.debugFrameFooterSize(frame_format);
10276 break :slice parent_slice[@intCast(offset)..end];10322 @memset(parent_slice[@intCast(offset + size)..][0..footer_size], 0);
10277 },10323 frame_shndx.setSize(elf, offset + size + footer_size);
10278 .debug_frame => break :slice parent_slice[@intCast(offset)..],10324 break :slice parent_slice[@intCast(offset)..][0..@intCast(size)];
10279 }
10280 },10325 },
10281 .unit_frame_cie, .func_frame_fde => {10326 .unit_frame_cie, .func_frame_fde => {
10282 const parent_offset, _ = parent_ni.location(&elf.mf).resolve(&elf.mf);10327 const parent_offset, _ = parent_ni.location(&elf.mf).resolve(&elf.mf);
10283 const frame_ni = parent_ni.parent(&elf.mf).unwrap().?;10328 const frame_ni = parent_ni.parent(&elf.mf).unwrap().?;
10284 const frame_slice = frame_ni.slicePadding(&elf.mf);10329 const frame_slice = frame_ni.slicePadding(&elf.mf);
10285 const frame_format = elf.getNode(frame_ni).section.debugFrameFormat(elf);10330 const frame_shndx = elf.getNode(frame_ni).section_manual_size;
10286 const slice = frame_slice[@intCast(parent_offset + offset)..if (parent_ni.next(&elf.mf).unwrap()) |parent_next_ni| frame_end: {10331 const frame_format = frame_shndx.debugFrameFormat(elf).?;
10332 if (parent_ni.next(&elf.mf).ifPos(&elf.mf, .floating).unwrap()) |parent_next_ni| {
10287 const parent_next_offset, _ = parent_next_ni.location(&elf.mf).resolve(&elf.mf);10333 const parent_next_offset, _ = parent_next_ni.location(&elf.mf).resolve(&elf.mf);
10288 break :frame_end @intCast(parent_next_offset);10334 const slice =
10289 } else frame_end: switch (frame_format orelse .debug_frame) {10335 frame_slice[@intCast(parent_offset + offset)..@intCast(parent_next_offset)];
10290 .eh_frame => {10336 var fw: Io.Writer = .fixed(slice[@intCast(size)..]);
10291 const frame_end = frame_slice.len - 4;10337 elf.dwarf.genDebugFrameCie(&fw, null, frame_format) catch |err| switch (err) {
10292 std.mem.writeInt(u32, frame_slice[frame_end..][0..4], 0, elf.dwarf.endian);10338 error.WriteFailed => break :slice slice,
10293 break :frame_end frame_end;10339 };
10294 },10340 elf.dwarf.updateUnitLength(fw.buffer, fw.buffer.len);
10295 .debug_frame => frame_slice.len,10341 break :slice slice[0..@intCast(size)];
10296 }];10342 }
10297 var fw: Io.Writer = .fixed(slice[@intCast(size)..]);10343 const footer_size = elf.debugFrameFooterSize(frame_format);
10298 (if (frame_format) |format|10344 @memset(frame_slice[@intCast(parent_offset + offset + size)..][0..footer_size], 0);
10299 elf.dwarf.genDebugFrameCie(&fw, null, format)10345 frame_shndx.setSize(elf, parent_offset + offset + size + footer_size);
10300 else10346 break :slice frame_slice[@intCast(parent_offset + offset)..][0..@intCast(size)];
10301 elf.dwarf.genUnitPadding(&fw)) catch |err| switch (err) {
10302 error.WriteFailed => break :slice slice,
10303 };
10304 elf.dwarf.updateUnitLength(fw.buffer, fw.buffer.len);
10305 break :slice slice[0..@intCast(size)];
10306 },10347 },
10307 .unit_debug_info_header,10348 .unit_debug_info_header,
10308 .unit_debug_line_header,10349 .unit_debug_line_header,
...@@ -10315,7 +10356,9 @@ fn flushNextMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!...@@ -10315,7 +10356,9 @@ fn flushNextMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!
10315 const parent_offset, _ = parent_ni.location(&elf.mf).resolve(&elf.mf);10356 const parent_offset, _ = parent_ni.location(&elf.mf).resolve(&elf.mf);
10316 const debug_ni = parent_ni.parent(&elf.mf).unwrap().?;10357 const debug_ni = parent_ni.parent(&elf.mf).unwrap().?;
10317 const debug_slice = debug_ni.slicePadding(&elf.mf);10358 const debug_slice = debug_ni.slicePadding(&elf.mf);
10318 var fw: Io.Writer = .fixed(debug_slice[@intCast(parent_offset)..if (parent_ni.next(&elf.mf).unwrap()) |parent_next_ni| debug_end: {10359 var fw: Io.Writer = .fixed(debug_slice[@intCast(parent_offset)..if (parent_ni
10360 .next(&elf.mf).ifPos(&elf.mf, .floating).unwrap()) |parent_next_ni|
10361 debug_end: {
10319 const parent_next_offset, _ = parent_next_ni.location(&elf.mf).resolve(&elf.mf);10362 const parent_next_offset, _ = parent_next_ni.location(&elf.mf).resolve(&elf.mf);
10320 break :debug_end @intCast(parent_next_offset);10363 break :debug_end @intCast(parent_next_offset);
10321 } else debug_slice.len]);10364 } else debug_slice.len]);
...@@ -10383,8 +10426,12 @@ fn flushNextMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!...@@ -10383,8 +10426,12 @@ fn flushNextMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!
10383 },10426 },
10384 }10427 }
10385 },10428 },
10386 .unit_frame, .unit_debug_info, .unit_debug_line => if (ni.last(&elf.mf).unwrap()) |last_ni|10429 .unit_frame, .unit_debug_info, .unit_debug_line => {
10387 try last_ni.nextMoved(elf.base.comp.gpa, &elf.mf),10430 var last_ni = ni.last(&elf.mf).unwrap() orelse return;
10431 while (last_ni.position(&elf.mf) == .footer)
10432 last_ni = last_ni.prev(&elf.mf).unwrap() orelse return;
10433 try last_ni.nextMoved(elf.base.comp.gpa, &elf.mf);
10434 },
10388 }10435 }
10389}10436}
1039010437
...@@ -10877,7 +10924,7 @@ pub fn printNode(...@@ -10877,7 +10924,7 @@ pub fn printNode(
10877 try w.print("({f}{f}, {s})", .{10924 try w.print("({f}{f}, {s})", .{
10878 ii.path(elf).fmtEscapeString(),10925 ii.path(elf).fmtEscapeString(),
10879 fmtMemberString(ii.member(elf)),10926 fmtMemberString(ii.member(elf)),
10880 elf.getNode(isi.node(elf).parent(&elf.mf).unwrap().?).section.name(elf).slice(elf),10927 elf.getNodeShndx(isi.node(elf)).name(elf).slice(elf),
10881 });10928 });
10882 },10929 },
10883 .copied_global => |name| try w.print("(copy:{s})", .{name.slice(elf)}),10930 .copied_global => |name| try w.print("(copy:{s})", .{name.slice(elf)}),
...@@ -10909,6 +10956,7 @@ pub fn printNode(...@@ -10909,6 +10956,7 @@ pub fn printNode(
10909 .unit_frame_cie,10956 .unit_frame_cie,
10910 .unit_debug_info,10957 .unit_debug_info,
10911 .unit_debug_info_header,10958 .unit_debug_info_header,
10959 .unit_debug_info_footer,
10912 .unit_debug_line,10960 .unit_debug_line,
10913 .unit_debug_line_header,10961 .unit_debug_line_header,
10914 .unit_debug_rnglists,10962 .unit_debug_rnglists,
src/link/MappedFile.zig+4
...@@ -355,6 +355,10 @@ pub const Node = extern struct {...@@ -355,6 +355,10 @@ pub const Node = extern struct {
355 assert(oi != .none);355 assert(oi != .none);
356 return oi;356 return oi;
357 }357 }
358
359 pub fn ifPos(oi: Optional, mf: *const MappedFile, pos: Node.Position) Optional {
360 return if ((oi.unwrap() orelse return .none).position(mf) == pos) oi else .none;
361 }
358 };362 };
359363
360 fn get(ni: Node.Index, mf: *const MappedFile) *Node {364 fn get(ni: Node.Index, mf: *const MappedFile) *Node {