authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2026-10-17 16:39:05+01:00
committergravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2026-10-19 18:30:34+01:00
log77340b28c806e30c3d5759abe6883fc35eaed60c
tree91185aef36b2e9f36f409f073a855dc8cd6e7c9b
parent51cd726f86e0036e9cc19339a70655a149f9d79f
signature Commit is signed but in an unrecognized format.

Elf2: stop constantly re-applying DWARF relocations


1 files changed, 39 insertions(+), 2 deletions(-)

src/link/Elf2.zig+39-2
......@@ -1073,10 +1073,14 @@ const dwarf_relocs = struct {
10731073 const Addr = struct {
10741074 first_target_reloc: NodeReloc.Index,
10751075 symbol_relocs: std.ArrayList(SymbolReloc.Index),
1076 /// Index into `symbol_relocs`.
1077 pending_reloc_index: usize,
10761078 };
10771079 const StrOffsets = struct {
10781080 first_target_reloc: NodeReloc.Index,
10791081 node_relocs: std.ArrayList(NodeReloc.Index),
1082 /// Index into `node_relocs`.
1083 pending_reloc_index: usize,
10801084 };
10811085 const Unit = struct {
10821086 frame_cie_first_target_reloc: NodeReloc.Index,
......@@ -5000,10 +5004,12 @@ fn create(
50005004 .dwarf_addr = .{
50015005 .first_target_reloc = .none,
50025006 .symbol_relocs = .empty,
5007 .pending_reloc_index = 0,
50035008 },
50045009 .dwarf_str_offsets = .{
50055010 .first_target_reloc = .none,
50065011 .node_relocs = .empty,
5012 .pending_reloc_index = 0,
50075013 },
50085014 .dwarf_units = &.{},
50095015 .dwarf_consts = .empty,
......@@ -11010,6 +11016,9 @@ pub fn idle(elf: *Elf) link.Error!bool {
1101011016 if (elf.bss_moved) {
1101111017 elf.bss_moved = false;
1101211018
11019 const idle_prog_node = elf.mf.update_prog_node.start(".bss", 0);
11020 defer idle_prog_node.end();
11021
1101311022 const data_phndx = elf.getNode(elf.ni.data).segment;
1101411023 const data_offset: u64, const data_vaddr: u64, const data_filesz: u64 = switch (elf.phdrSlice()) {
1101511024 inline else => |phdr| .{
......@@ -11040,6 +11049,32 @@ pub fn idle(elf: *Elf) link.Error!bool {
1104011049
1104111050 break :task;
1104211051 }
11052 if (elf.dwarf_addr.pending_reloc_index < elf.dwarf_addr.symbol_relocs.items.len) {
11053 const idle_prog_node = elf.mf.update_prog_node.start(@tagName(Node.debug_addr), 0);
11054 defer idle_prog_node.end();
11055 const debug_addr_ni = elf.dwarf.debug_addr.ni.unwrap().?;
11056 const debug_addr_vaddr = elf.getNodeVAddr(debug_addr_ni);
11057 for (elf.dwarf_addr.symbol_relocs.items[elf.dwarf_addr.pending_reloc_index..]) |symbol_ri| {
11058 const symbol_reloc = symbol_ri.get(elf);
11059 assert(symbol_reloc.node.unwrap().? == debug_addr_ni);
11060 symbol_reloc.flushMovedNode(elf, debug_addr_vaddr);
11061 }
11062 elf.dwarf_addr.pending_reloc_index = elf.dwarf_addr.symbol_relocs.items.len;
11063 break :task;
11064 }
11065 if (elf.dwarf_str_offsets.pending_reloc_index < elf.dwarf_str_offsets.node_relocs.items.len) {
11066 const idle_prog_node = elf.mf.update_prog_node.start(@tagName(Node.debug_str_offsets), 0);
11067 defer idle_prog_node.end();
11068 const debug_str_offsets_ni = elf.dwarf.debug_str_offsets.ni.unwrap().?;
11069 const debug_str_offsets_vaddr = elf.getNodeVAddr(debug_str_offsets_ni);
11070 for (elf.dwarf_str_offsets.node_relocs.items[elf.dwarf_str_offsets.pending_reloc_index..]) |node_ri| {
11071 const node_reloc = node_ri.get(elf);
11072 assert(node_reloc.node.unwrap().? == debug_str_offsets_ni);
11073 node_reloc.flushMovedNode(elf, debug_str_offsets_vaddr);
11074 }
11075 elf.dwarf_str_offsets.pending_reloc_index = elf.dwarf_str_offsets.node_relocs.items.len;
11076 break :task;
11077 }
1104311078 }
1104411079 if (elf.inputs.items.len - elf.input_pending_index > 0) return true;
1104511080 if (elf.input_sections.items.len - elf.input_section_pending_index > 0) return true;
......@@ -11047,6 +11082,8 @@ pub fn idle(elf: *Elf) link.Error!bool {
1104711082 if (elf.changed_symtab_index.count() > 0) return true;
1104811083 if (elf.mf.updates.items.len > 0) return true;
1104911084 if (elf.bss_moved) return true;
11085 if (elf.dwarf_addr.pending_reloc_index < elf.dwarf_addr.symbol_relocs.items.len) return true;
11086 if (elf.dwarf_str_offsets.pending_reloc_index < elf.dwarf_str_offsets.node_relocs.items.len) return true;
1105011087 return false;
1105111088}
1105211089
......@@ -11177,7 +11214,6 @@ fn genPending(elf: *Elf, pt: Zcu.PerThread) link.Error!void {
1117711214fn genPendingDebug(elf: *Elf, gpa: std.mem.Allocator) link.Error!void {
1117811215 while (elf.dwarf.debug_addr.map.count() - elf.dwarf.debug_addr.pending_index > 0) {
1117911216 const debug_addr_ni = elf.dwarf.debug_addr.ni.unwrap().?;
11180 try debug_addr_ni.moved(gpa, &elf.mf);
1118111217 var da_nw: link.MappedFile.Node.Writer = undefined;
1118211218 debug_addr_ni.writer(gpa, &elf.mf, &da_nw);
1118311219 defer da_nw.deinit();
......@@ -11190,7 +11226,6 @@ fn genPendingDebug(elf: *Elf, gpa: std.mem.Allocator) link.Error!void {
1119011226 }
1119111227 while (elf.dwarf.debug_str_offsets.map.count() - elf.dwarf.debug_str_offsets.pending_index > 0) {
1119211228 const debug_str_offsets_ni = elf.dwarf.debug_str_offsets.ni.unwrap().?;
11193 try debug_str_offsets_ni.moved(gpa, &elf.mf);
1119411229 var dso_nw: link.MappedFile.Node.Writer = undefined;
1119511230 debug_str_offsets_ni.writer(gpa, &elf.mf, &dso_nw);
1119611231 defer dso_nw.deinit();
......@@ -11659,6 +11694,7 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void
1165911694 assert(symbol_reloc.node.unwrap().? == ni);
1166011695 symbol_reloc.flushMovedNode(elf, node_vaddr);
1166111696 }
11697 elf.dwarf_addr.pending_reloc_index = elf.dwarf_addr.symbol_relocs.items.len;
1166211698 },
1166311699 .debug_str_offsets => {
1166411700 const target_section_offset = elf.computeNodeSectionOffset(ni);
......@@ -11675,6 +11711,7 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void
1167511711 assert(node_reloc.node.unwrap().? == ni);
1167611712 node_reloc.flushMovedNode(elf, node_vaddr);
1167711713 }
11714 elf.dwarf_str_offsets.pending_reloc_index = elf.dwarf_str_offsets.node_relocs.items.len;
1167811715 },
1167911716 .unit_frame_cie => |ui| {
1168011717 const target_section_offset = elf.computeNodeSectionOffset(ni);