authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2026-10-17 17:06:45+01:00
committergravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2026-10-19 18:30:34+01:00
logd070d85471004dfaaf4e865d64e4405116822d2a
tree3172e4ba8dbd4f6543bf70b2849d972b9c2830aa
parent0b4d75a0acd5311edf4f027d77d346bcfdc9b977
signature Commit is signed but in an unrecognized format.

Elf2: simplify relocation application


1 files changed, 54 insertions(+), 132 deletions(-)

src/link/Elf2.zig+54-132
...@@ -1943,28 +1943,20 @@ const SymbolReloc = struct {...@@ -1943,28 +1943,20 @@ const SymbolReloc = struct {
1943 }1943 }
1944 };1944 };
19451945
1946 fn flushMovedNode(reloc: *SymbolReloc, elf: *Elf, node_vaddr: u64) void {
1947 if (reloc.rela_index.unwrap()) |rela_index| {
1948 // The node has moved, so the offset of the relocation within the section might have
1949 // changed, so update the `offset` field of the `ElfN.Rela` entry.
1950 reloc.relaSection(elf).relaSetOffset(elf, rela_index, node_vaddr + reloc.offset);
1951 }
1952 // This is not just the inverse of the above condition, because if `reloc` is relative
1953 // to the base of this DSO, then `rela_index` is an `R_*_RELATIVE` relocation, but we
1954 // still need to call `SymbolReloc.apply` to update that relocation's addend.
1955 if (elf.ehdrType() != .REL) {
1956 reloc.apply(elf);
1957 }
1958 }
1959
1960 fn apply(reloc: *SymbolReloc, elf: *Elf) void {1946 fn apply(reloc: *SymbolReloc, elf: *Elf) void {
1961 assert(elf.ehdrType() != .REL);
1962 const node = reloc.node.unwrap() orelse return; // deleted1947 const node = reloc.node.unwrap() orelse return; // deleted
1963 if (node.hasMoved(&elf.mf) or reloc.target.hasMoved(elf)) {1948 if (node.hasMoved(&elf.mf) or reloc.target.hasMoved(elf)) {
1964 // There's no point applying the relocation now, because it will be re-applied by1949 // There's no point applying the relocation now, because it will be re-applied by
1965 // `flushMoved` at some point anyway.1950 // `flushMoved` at some point anyway.
1966 return;1951 return;
1967 }1952 }
1953 if (elf.ehdrType() == .REL) {
1954 // All we need to do is update the output relocation.
1955 const rela_index = reloc.rela_index.unwrap().?;
1956 const reloc_addr = elf.getNodeVAddr(node) + reloc.offset;
1957 reloc.relaSection(elf).relaSetOffset(elf, rela_index, reloc_addr);
1958 return;
1959 }
1968 switch (reloc.result) {1960 switch (reloc.result) {
1969 .ok => {},1961 .ok => {},
1970 .overflowed => elf.overflowed_reloc_count -= 1,1962 .overflowed => elf.overflowed_reloc_count -= 1,
...@@ -2030,7 +2022,11 @@ const SymbolReloc = struct {...@@ -2030,7 +2022,11 @@ const SymbolReloc = struct {
2030 // is required, meaning we can handle it now and return early.2022 // is required, meaning we can handle it now and return early.
2031 if (reloc.rela_index.unwrap()) |rela_index| switch (elf.classifySymbolValue(reloc.target)) {2023 if (reloc.rela_index.unwrap()) |rela_index| switch (elf.classifySymbolValue(reloc.target)) {
2032 .static => unreachable,2024 .static => unreachable,
2033 .dynamic => return, // the relocation happens at runtime2025 .dynamic => {
2026 // The relocation happens at runtime; we just need to update its offset.
2027 elf.shndx.rela_dyn.relaSetOffset(elf, rela_index, dest_vaddr);
2028 return;
2029 },
2034 .static_relative => {2030 .static_relative => {
2035 // We have emitted an R_*_RELATIVE relocation to help lower an absolute-address2031 // We have emitted an R_*_RELATIVE relocation to help lower an absolute-address
2036 // relocation. The value computed above is valid, but instead of writing it to the2032 // relocation. The value computed above is valid, but instead of writing it to the
...@@ -2042,6 +2038,7 @@ const SymbolReloc = struct {...@@ -2042,6 +2038,7 @@ const SymbolReloc = struct {
2042 }2038 }
2043 assert(reloc.type.action.simple.cast == .unsigned);2039 assert(reloc.type.action.simple.cast == .unsigned);
2044 assert(reloc.type.action.simple.shift == .@"0");2040 assert(reloc.type.action.simple.shift == .@"0");
2041 elf.shndx.rela_dyn.relaSetOffset(elf, rela_index, dest_vaddr);
2045 elf.shndx.rela_dyn.relaSetAddend(elf, rela_index, target_val);2042 elf.shndx.rela_dyn.relaSetAddend(elf, rela_index, target_val);
2046 return;2043 return;
2047 },2044 },
...@@ -2122,34 +2119,14 @@ const NodeReloc = struct {...@@ -2122,34 +2119,14 @@ const NodeReloc = struct {
2122 }2119 }
2123 };2120 };
21242121
2125 fn flushMovedNode(reloc: *NodeReloc, elf: *Elf, node_vaddr: u64) void {
2126 if (reloc.rela_index.unwrap()) |rela_index| {
2127 assert(elf.ehdrType() == .REL);
2128 // The node has moved, so the offset of the relocation within the section might have
2129 // changed, so update the `offset` field of the `ElfN.Rela` entry.
2130 elf.getNodeShndx(reloc.node.unwrap().?).get(elf).rela.shndx.relaSetOffset(elf, rela_index, node_vaddr + reloc.offset);
2131 } else {
2132 assert(elf.ehdrType() != .REL);
2133 reloc.apply(elf);
2134 }
2135 }
2136
2137 fn flushMovedTarget(reloc: *NodeReloc, elf: *Elf, target_section_offset: u64) void {
2138 if (reloc.rela_index.unwrap()) |rela_index| {
2139 assert(elf.ehdrType() == .REL);
2140 // The target has moved, so the `addend` field of the `ElfN.Rela` entry needs to be updated.
2141 elf.getNodeShndx(reloc.node.unwrap().?).get(elf).rela.shndx.relaSetAddend(elf, rela_index, target_section_offset +% @as(u64, @bitCast(reloc.addend)));
2142 } else {
2143 assert(elf.ehdrType() != .REL);
2144 reloc.apply(elf);
2145 }
2146 }
2147
2148 fn apply(reloc: *NodeReloc, elf: *Elf) void {2122 fn apply(reloc: *NodeReloc, elf: *Elf) void {
2149 const node = reloc.node.unwrap() orelse return; // deleted2123 const node = reloc.node.unwrap() orelse return; // deleted
2150 if (reloc.rela_index.unwrap()) |rela_index| {2124 if (reloc.rela_index.unwrap()) |rela_index| {
2151 assert(elf.ehdrType() == .REL);2125 assert(elf.ehdrType() == .REL);
2152 _ = rela_index;2126 // Ensure the output relocation is up-to-date.
2127 const rela_shndx = elf.getNodeShndx(reloc.node.unwrap().?).get(elf).rela.shndx;
2128 rela_shndx.relaSetOffset(elf, rela_index, elf.getNodeVAddr(node) + reloc.offset);
2129 rela_shndx.relaSetAddend(elf, rela_index, elf.getNodeVAddr(node) +% @as(u64, @bitCast(reloc.addend)));
2153 } else {2130 } else {
2154 assert(elf.ehdrType() != .REL);2131 assert(elf.ehdrType() != .REL);
2155 if (node.hasMoved(&elf.mf) or reloc.target.hasMoved(&elf.mf)) {2132 if (node.hasMoved(&elf.mf) or reloc.target.hasMoved(&elf.mf)) {
...@@ -4308,14 +4285,12 @@ const Symbol = struct {...@@ -4308,14 +4285,12 @@ const Symbol = struct {
4308 }4285 }
43094286
4310 fn applyTargetRelocs(sym_id: Symbol.Id, elf: *Elf) void {4287 fn applyTargetRelocs(sym_id: Symbol.Id, elf: *Elf) void {
4311 if (elf.ehdrType() != .REL) {4288 var ri = sym_id.index(elf).ptr(elf).first_target_reloc;
4312 var ri = sym_id.index(elf).ptr(elf).first_target_reloc;4289 while (ri != .none) {
4313 while (ri != .none) {4290 const reloc = ri.get(elf);
4314 const reloc = ri.get(elf);4291 assert(reloc.target == sym_id);
4315 assert(reloc.target == sym_id);4292 reloc.apply(elf);
4316 reloc.apply(elf);4293 ri = reloc.next;
4317 ri = reloc.next;
4318 }
4319 }4294 }
43204295
4321 if (elf.got.getIndex(.{ .symbol = sym_id })) |got_index| {4296 if (elf.got.getIndex(.{ .symbol = sym_id })) |got_index| {
...@@ -6623,43 +6598,6 @@ fn computeNodeVAddr(elf: *Elf, ni: MappedFile.Node.Index) u64 {...@@ -6623,43 +6598,6 @@ fn computeNodeVAddr(elf: *Elf, ni: MappedFile.Node.Index) u64 {
6623 const offset, _ = ni.location(&elf.mf).resolve(&elf.mf);6598 const offset, _ = ni.location(&elf.mf).resolve(&elf.mf);
6624 return parent_vaddr + offset;6599 return parent_vaddr + offset;
6625}6600}
6626fn computeNodeSectionOffset(elf: *Elf, ni: MappedFile.Node.Index) u64 {
6627 const parent_ni = ni.parent(&elf.mf).unwrap().?;
6628 const parent_section_offset = parent_section_offset: switch (elf.getNode(parent_ni)) {
6629 .deleted,
6630 .archive,
6631 .archive_header,
6632 .archive_input_member,
6633 .archive_elf_member_header,
6634 .elf,
6635 .ehdr,
6636 .shdr,
6637 .segment,
6638 => unreachable,
6639 .section, .section_manual_size => 0,
6640 .input_section, .copied_global => unreachable,
6641 .nav, .uav, .lazy_code, .lazy_const_data => unreachable,
6642 .debug_shared, .debug_addr, .eh_frame_footer, .debug_str_offsets, .unit_padding => unreachable,
6643 .unit_frame, .unit_debug_info, .unit_debug_line => {
6644 const parent_section_offset, _ = parent_ni.location(&elf.mf).resolve(&elf.mf);
6645 break :parent_section_offset parent_section_offset;
6646 },
6647 .unit_frame_cie,
6648 .unit_debug_info_header,
6649 .unit_debug_info_footer,
6650 .unit_debug_line_header,
6651 .unit_debug_rnglists,
6652 .const_debug_info,
6653 .global_debug_info,
6654 .func_frame_fde,
6655 .func_debug_info,
6656 .func_debug_line,
6657 .decl_debug_info,
6658 => unreachable,
6659 };
6660 const offset, _ = ni.location(&elf.mf).resolve(&elf.mf);
6661 return parent_section_offset + offset;
6662}
6663fn computeNodeElfOffset(elf: *Elf, ni: MappedFile.Node.Index) u64 {6601fn computeNodeElfOffset(elf: *Elf, ni: MappedFile.Node.Index) u64 {
6664 return ni.fileLocation(&elf.mf, false).offset - elf.ni.elf.fileLocation(&elf.mf, false).offset;6602 return ni.fileLocation(&elf.mf, false).offset - elf.ni.elf.fileLocation(&elf.mf, false).offset;
6665}6603}
...@@ -6801,7 +6739,6 @@ pub fn resetNodeRelocs(elf: *Elf, ni: MappedFile.Node.Index) void {...@@ -6801,7 +6739,6 @@ pub fn resetNodeRelocs(elf: *Elf, ni: MappedFile.Node.Index) void {
6801fn flushMovedNodeRelocs(6739fn flushMovedNodeRelocs(
6802 elf: *Elf,6740 elf: *Elf,
6803 node: MappedFile.Node.Index,6741 node: MappedFile.Node.Index,
6804 node_vaddr: u64,
6805 opts: struct {6742 opts: struct {
6806 first_symbol_reloc: SymbolReloc.Index = .none,6743 first_symbol_reloc: SymbolReloc.Index = .none,
6807 skip_symbol_relocs: MappedFile.Node.Index.Optional = .none,6744 skip_symbol_relocs: MappedFile.Node.Index.Optional = .none,
...@@ -6817,7 +6754,7 @@ fn flushMovedNodeRelocs(...@@ -6817,7 +6754,7 @@ fn flushMovedNodeRelocs(
6817 if (reloc.node == opts.skip_symbol_relocs) continue;6754 if (reloc.node == opts.skip_symbol_relocs) continue;
6818 break;6755 break;
6819 }6756 }
6820 reloc.flushMovedNode(elf, node_vaddr);6757 reloc.apply(elf);
6821 }6758 }
6822 }6759 }
68236760
...@@ -6828,7 +6765,7 @@ fn flushMovedNodeRelocs(...@@ -6828,7 +6765,7 @@ fn flushMovedNodeRelocs(
6828 if (reloc.node == opts.skip_node_relocs) continue;6765 if (reloc.node == opts.skip_node_relocs) continue;
6829 break;6766 break;
6830 }6767 }
6831 reloc.flushMovedNode(elf, node_vaddr);6768 reloc.apply(elf);
6832 }6769 }
6833 }6770 }
68346771
...@@ -9406,6 +9343,7 @@ fn addRelocAssumeCapacity(...@@ -9406,6 +9343,7 @@ fn addRelocAssumeCapacity(
9406 .rela_index = rela_index.toOptional(),9343 .rela_index = rela_index.toOptional(),
9407 .result = .ok,9344 .result = .ok,
9408 });9345 });
9346 ri.get(elf).apply(elf);
9409 },9347 },
9410 .DYN, .EXEC => switch (elf.ehdrMachine()) {9348 .DYN, .EXEC => switch (elf.ehdrMachine()) {
9411 .AARCH64 => switch (@"type".AARCH64) {9349 .AARCH64 => switch (@"type".AARCH64) {
...@@ -11053,11 +10991,10 @@ pub fn idle(elf: *Elf) link.Error!bool {...@@ -11053,11 +10991,10 @@ pub fn idle(elf: *Elf) link.Error!bool {
11053 const idle_prog_node = elf.mf.update_prog_node.start(@tagName(Node.debug_addr), 0);10991 const idle_prog_node = elf.mf.update_prog_node.start(@tagName(Node.debug_addr), 0);
11054 defer idle_prog_node.end();10992 defer idle_prog_node.end();
11055 const debug_addr_ni = elf.dwarf.debug_addr.ni.unwrap().?;10993 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| {10994 for (elf.dwarf_addr.symbol_relocs.items[elf.dwarf_addr.pending_reloc_index..]) |symbol_ri| {
11058 const symbol_reloc = symbol_ri.get(elf);10995 const symbol_reloc = symbol_ri.get(elf);
11059 assert(symbol_reloc.node.unwrap().? == debug_addr_ni);10996 assert(symbol_reloc.node.unwrap().? == debug_addr_ni);
11060 symbol_reloc.flushMovedNode(elf, debug_addr_vaddr);10997 symbol_reloc.apply(elf);
11061 }10998 }
11062 elf.dwarf_addr.pending_reloc_index = elf.dwarf_addr.symbol_relocs.items.len;10999 elf.dwarf_addr.pending_reloc_index = elf.dwarf_addr.symbol_relocs.items.len;
11063 break :task;11000 break :task;
...@@ -11066,11 +11003,10 @@ pub fn idle(elf: *Elf) link.Error!bool {...@@ -11066,11 +11003,10 @@ pub fn idle(elf: *Elf) link.Error!bool {
11066 const idle_prog_node = elf.mf.update_prog_node.start(@tagName(Node.debug_str_offsets), 0);11003 const idle_prog_node = elf.mf.update_prog_node.start(@tagName(Node.debug_str_offsets), 0);
11067 defer idle_prog_node.end();11004 defer idle_prog_node.end();
11068 const debug_str_offsets_ni = elf.dwarf.debug_str_offsets.ni.unwrap().?;11005 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| {11006 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);11007 const node_reloc = node_ri.get(elf);
11072 assert(node_reloc.node.unwrap().? == debug_str_offsets_ni);11008 assert(node_reloc.node.unwrap().? == debug_str_offsets_ni);
11073 node_reloc.flushMovedNode(elf, debug_str_offsets_vaddr);11009 node_reloc.apply(elf);
11074 }11010 }
11075 elf.dwarf_str_offsets.pending_reloc_index = elf.dwarf_str_offsets.node_relocs.items.len;11011 elf.dwarf_str_offsets.pending_reloc_index = elf.dwarf_str_offsets.node_relocs.items.len;
11076 break :task;11012 break :task;
...@@ -11565,7 +11501,7 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void...@@ -11565,7 +11501,7 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void
11565 reloc.apply(elf);11501 reloc.apply(elf);
11566 }11502 }
11567 } else if (shndx == elf.shndx.plt) {11503 } else if (shndx == elf.shndx.plt) {
11568 elf.flushMovedNodeRelocs(ni, addr, .{11504 elf.flushMovedNodeRelocs(ni, .{
11569 .first_symbol_reloc = elf.plt_first_symbol_reloc,11505 .first_symbol_reloc = elf.plt_first_symbol_reloc,
11570 });11506 });
11571 elf.flushMovedPltSection(.plt, old_addr, addr);11507 elf.flushMovedPltSection(.plt, old_addr, addr);
...@@ -11574,7 +11510,7 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void...@@ -11574,7 +11510,7 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void
11574 } else if (shndx == elf.shndx.plt_sec) {11510 } else if (shndx == elf.shndx.plt_sec) {
11575 elf.flushMovedPltSection(.plt_sec, old_addr, addr);11511 elf.flushMovedPltSection(.plt_sec, old_addr, addr);
11576 } else if (shndx == elf.shndx.eh_frame_hdr) {11512 } else if (shndx == elf.shndx.eh_frame_hdr) {
11577 elf.flushMovedNodeRelocs(ni, addr, .{11513 elf.flushMovedNodeRelocs(ni, .{
11578 .first_symbol_reloc = elf.eh_frame_hdr_first_symbol_reloc,11514 .first_symbol_reloc = elf.eh_frame_hdr_first_symbol_reloc,
11579 });11515 });
11580 }11516 }
...@@ -11627,7 +11563,7 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void...@@ -11627,7 +11563,7 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void
11627 }11563 }
11628 }11564 }
1162911565
11630 elf.flushMovedNodeRelocs(ni, new_section_addr, .{11566 elf.flushMovedNodeRelocs(ni, .{
11631 .first_symbol_reloc = isi.ptrConst(elf).first_symbol_reloc,11567 .first_symbol_reloc = isi.ptrConst(elf).first_symbol_reloc,
11632 .first_got_reloc = isi.ptrConst(elf).first_got_reloc,11568 .first_got_reloc = isi.ptrConst(elf).first_got_reloc,
11633 });11569 });
...@@ -11650,7 +11586,7 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void...@@ -11650,7 +11586,7 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void
11650 Symbol.Id.global(gsi).flushMoved(elf, new_addr);11586 Symbol.Id.global(gsi).flushMoved(elf, new_addr);
11651 }11587 }
11652 }11588 }
11653 elf.flushMovedNodeRelocs(ni, new_addr, .{11589 elf.flushMovedNodeRelocs(ni, .{
11654 .first_symbol_reloc = mi.firstSymbolReloc(elf),11590 .first_symbol_reloc = mi.firstSymbolReloc(elf),
11655 .skip_symbol_relocs = switch (tag) {11591 .skip_symbol_relocs = switch (tag) {
11656 else => comptime unreachable,11592 else => comptime unreachable,
...@@ -11664,12 +11600,11 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void...@@ -11664,12 +11600,11 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void
11664 });11600 });
11665 },11601 },
11666 .debug_shared => |ss| {11602 .debug_shared => |ss| {
11667 const target_section_offset = elf.computeNodeSectionOffset(ni);
11668 var target_ri = elf.dwarf_shared.getPtr(ss).first_target_reloc;11603 var target_ri = elf.dwarf_shared.getPtr(ss).first_target_reloc;
11669 while (target_ri != .none) {11604 while (target_ri != .none) {
11670 const target_reloc = target_ri.get(elf);11605 const target_reloc = target_ri.get(elf);
11671 assert(target_reloc.target == ni);11606 assert(target_reloc.target == ni);
11672 target_reloc.flushMovedTarget(elf, target_section_offset);11607 target_reloc.apply(elf);
11673 target_ri = target_reloc.next;11608 target_ri = target_reloc.next;
11674 }11609 }
11675 },11610 },
...@@ -11680,121 +11615,110 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void...@@ -11680,121 +11615,110 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void
11680 .unit_debug_line,11615 .unit_debug_line,
11681 => {},11616 => {},
11682 .debug_addr => {11617 .debug_addr => {
11683 const target_section_offset = elf.computeNodeSectionOffset(ni);
11684 var target_ri = elf.dwarf_addr.first_target_reloc;11618 var target_ri = elf.dwarf_addr.first_target_reloc;
11685 while (target_ri != .none) {11619 while (target_ri != .none) {
11686 const target_reloc = target_ri.get(elf);11620 const target_reloc = target_ri.get(elf);
11687 assert(target_reloc.target == ni);11621 assert(target_reloc.target == ni);
11688 target_reloc.flushMovedTarget(elf, target_section_offset);11622 target_reloc.apply(elf);
11689 target_ri = target_reloc.next;11623 target_ri = target_reloc.next;
11690 }11624 }
11691 const node_vaddr = elf.computeNodeVAddr(ni);
11692 for (elf.dwarf_addr.symbol_relocs.items) |symbol_ri| {11625 for (elf.dwarf_addr.symbol_relocs.items) |symbol_ri| {
11693 const symbol_reloc = symbol_ri.get(elf);11626 const symbol_reloc = symbol_ri.get(elf);
11694 assert(symbol_reloc.node.unwrap().? == ni);11627 assert(symbol_reloc.node.unwrap().? == ni);
11695 symbol_reloc.flushMovedNode(elf, node_vaddr);11628 symbol_reloc.apply(elf);
11696 }11629 }
11697 elf.dwarf_addr.pending_reloc_index = elf.dwarf_addr.symbol_relocs.items.len;11630 elf.dwarf_addr.pending_reloc_index = elf.dwarf_addr.symbol_relocs.items.len;
11698 },11631 },
11699 .debug_str_offsets => {11632 .debug_str_offsets => {
11700 const target_section_offset = elf.computeNodeSectionOffset(ni);
11701 var target_ri = elf.dwarf_str_offsets.first_target_reloc;11633 var target_ri = elf.dwarf_str_offsets.first_target_reloc;
11702 while (target_ri != .none) {11634 while (target_ri != .none) {
11703 const target_reloc = target_ri.get(elf);11635 const target_reloc = target_ri.get(elf);
11704 assert(target_reloc.target == ni);11636 assert(target_reloc.target == ni);
11705 target_reloc.flushMovedTarget(elf, target_section_offset);11637 target_reloc.apply(elf);
11706 target_ri = target_reloc.next;11638 target_ri = target_reloc.next;
11707 }11639 }
11708 const node_vaddr = elf.computeNodeVAddr(ni);
11709 for (elf.dwarf_str_offsets.node_relocs.items) |node_ri| {11640 for (elf.dwarf_str_offsets.node_relocs.items) |node_ri| {
11710 const node_reloc = node_ri.get(elf);11641 const node_reloc = node_ri.get(elf);
11711 assert(node_reloc.node.unwrap().? == ni);11642 assert(node_reloc.node.unwrap().? == ni);
11712 node_reloc.flushMovedNode(elf, node_vaddr);11643 node_reloc.apply(elf);
11713 }11644 }
11714 elf.dwarf_str_offsets.pending_reloc_index = elf.dwarf_str_offsets.node_relocs.items.len;11645 elf.dwarf_str_offsets.pending_reloc_index = elf.dwarf_str_offsets.node_relocs.items.len;
11715 },11646 },
11716 .unit_frame_cie => |ui| {11647 .unit_frame_cie => |ui| {
11717 const target_section_offset = elf.computeNodeSectionOffset(ni);
11718 var target_ri = elf.dwarf_units[@backingInt(ui)].frame_cie_first_target_reloc;11648 var target_ri = elf.dwarf_units[@backingInt(ui)].frame_cie_first_target_reloc;
11719 while (target_ri != .none) {11649 while (target_ri != .none) {
11720 const target_reloc = target_ri.get(elf);11650 const target_reloc = target_ri.get(elf);
11721 assert(target_reloc.target == ni);11651 assert(target_reloc.target == ni);
11722 target_reloc.flushMovedTarget(elf, target_section_offset);11652 target_reloc.apply(elf);
11723 target_ri = target_reloc.next;11653 target_ri = target_reloc.next;
11724 }11654 }
11725 },11655 },
11726 .unit_debug_info_header => |ui| {11656 .unit_debug_info_header => |ui| {
11727 const dwarf_unit = &elf.dwarf_units[@backingInt(ui)];11657 const dwarf_unit = &elf.dwarf_units[@backingInt(ui)];
11728 const target_section_offset = elf.computeNodeSectionOffset(ni);
11729 var target_ri = dwarf_unit.debug_info_header_first_target_reloc;11658 var target_ri = dwarf_unit.debug_info_header_first_target_reloc;
11730 while (target_ri != .none) {11659 while (target_ri != .none) {
11731 const target_reloc = target_ri.get(elf);11660 const target_reloc = target_ri.get(elf);
11732 assert(target_reloc.target == ni);11661 assert(target_reloc.target == ni);
11733 target_reloc.flushMovedTarget(elf, target_section_offset);11662 target_reloc.apply(elf);
11734 target_ri = target_reloc.next;11663 target_ri = target_reloc.next;
11735 }11664 }
11736 elf.flushMovedNodeRelocs(ni, elf.computeNodeVAddr(ni), .{11665 elf.flushMovedNodeRelocs(ni, .{
11737 .first_node_reloc = dwarf_unit.debug_info_header_first_node_reloc,11666 .first_node_reloc = dwarf_unit.debug_info_header_first_node_reloc,
11738 });11667 });
11739 },11668 },
11740 .unit_debug_info_footer => {},11669 .unit_debug_info_footer => {},
11741 .unit_debug_line_header => |ui| {11670 .unit_debug_line_header => |ui| {
11742 const dwarf_unit = &elf.dwarf_units[@backingInt(ui)];11671 const dwarf_unit = &elf.dwarf_units[@backingInt(ui)];
11743 const target_section_offset = elf.computeNodeSectionOffset(ni);
11744 var target_ri = dwarf_unit.debug_line_header_first_target_reloc;11672 var target_ri = dwarf_unit.debug_line_header_first_target_reloc;
11745 while (target_ri != .none) {11673 while (target_ri != .none) {
11746 const target_reloc = target_ri.get(elf);11674 const target_reloc = target_ri.get(elf);
11747 assert(target_reloc.target == ni);11675 assert(target_reloc.target == ni);
11748 target_reloc.flushMovedTarget(elf, target_section_offset);11676 target_reloc.apply(elf);
11749 target_ri = target_reloc.next;11677 target_ri = target_reloc.next;
11750 }11678 }
11751 elf.flushMovedNodeRelocs(ni, elf.computeNodeVAddr(ni), .{11679 elf.flushMovedNodeRelocs(ni, .{
11752 .first_node_reloc = dwarf_unit.debug_line_header_first_node_reloc,11680 .first_node_reloc = dwarf_unit.debug_line_header_first_node_reloc,
11753 });11681 });
11754 },11682 },
11755 .unit_debug_rnglists => |ui| {11683 .unit_debug_rnglists => |ui| {
11756 const dwarf_unit = &elf.dwarf_units[@backingInt(ui)];11684 const dwarf_unit = &elf.dwarf_units[@backingInt(ui)];
11757 const target_section_offset = elf.computeNodeSectionOffset(ni);
11758 var target_ri = dwarf_unit.debug_rnglists_first_target_reloc;11685 var target_ri = dwarf_unit.debug_rnglists_first_target_reloc;
11759 while (target_ri != .none) {11686 while (target_ri != .none) {
11760 const target_reloc = target_ri.get(elf);11687 const target_reloc = target_ri.get(elf);
11761 assert(target_reloc.target == ni);11688 assert(target_reloc.target == ni);
11762 target_reloc.flushMovedTarget(elf, target_section_offset);11689 target_reloc.apply(elf);
11763 target_ri = target_reloc.next;11690 target_ri = target_reloc.next;
11764 }11691 }
11765 const node_vaddr = elf.computeNodeVAddr(ni);
11766 for (dwarf_unit.debug_rnglists_symbol_relocs.items) |symbol_ri| {11692 for (dwarf_unit.debug_rnglists_symbol_relocs.items) |symbol_ri| {
11767 const symbol_reloc = symbol_ri.get(elf);11693 const symbol_reloc = symbol_ri.get(elf);
11768 assert(symbol_reloc.node.unwrap().? == ni);11694 assert(symbol_reloc.node.unwrap().? == ni);
11769 symbol_reloc.flushMovedNode(elf, node_vaddr);11695 symbol_reloc.apply(elf);
11770 }11696 }
11771 },11697 },
11772 .const_debug_info => |cpi| {11698 .const_debug_info => |cpi| {
11773 const dwarf_const = &elf.dwarf_consts.get(cpi).?;11699 const dwarf_const = &elf.dwarf_consts.get(cpi).?;
11774 const target_section_offset = elf.computeNodeSectionOffset(ni);
11775 var target_ri = dwarf_const.debug_info_first_target_reloc;11700 var target_ri = dwarf_const.debug_info_first_target_reloc;
11776 while (target_ri != .none) {11701 while (target_ri != .none) {
11777 const target_reloc = target_ri.get(elf);11702 const target_reloc = target_ri.get(elf);
11778 assert(target_reloc.target == ni);11703 assert(target_reloc.target == ni);
11779 target_reloc.flushMovedTarget(elf, target_section_offset);11704 target_reloc.apply(elf);
11780 target_ri = target_reloc.next;11705 target_ri = target_reloc.next;
11781 }11706 }
11782 elf.flushMovedNodeRelocs(ni, elf.computeNodeVAddr(ni), .{11707 elf.flushMovedNodeRelocs(ni, .{
11783 .first_symbol_reloc = dwarf_const.debug_info_first_symbol_reloc,11708 .first_symbol_reloc = dwarf_const.debug_info_first_symbol_reloc,
11784 .first_node_reloc = dwarf_const.debug_info_first_node_reloc,11709 .first_node_reloc = dwarf_const.debug_info_first_node_reloc,
11785 });11710 });
11786 },11711 },
11787 .global_debug_info => |gi| {11712 .global_debug_info => |gi| {
11788 const dwarf_global = &elf.dwarf_globals.items[@backingInt(gi)];11713 const dwarf_global = &elf.dwarf_globals.items[@backingInt(gi)];
11789 const target_section_offset = elf.computeNodeSectionOffset(ni);
11790 var target_ri = dwarf_global.debug_info_first_target_reloc;11714 var target_ri = dwarf_global.debug_info_first_target_reloc;
11791 while (target_ri != .none) {11715 while (target_ri != .none) {
11792 const target_reloc = target_ri.get(elf);11716 const target_reloc = target_ri.get(elf);
11793 assert(target_reloc.target == ni);11717 assert(target_reloc.target == ni);
11794 target_reloc.flushMovedTarget(elf, target_section_offset);11718 target_reloc.apply(elf);
11795 target_ri = target_reloc.next;11719 target_ri = target_reloc.next;
11796 }11720 }
11797 elf.flushMovedNodeRelocs(ni, elf.computeNodeVAddr(ni), .{11721 elf.flushMovedNodeRelocs(ni, .{
11798 .first_symbol_reloc = dwarf_global.debug_info_first_symbol_reloc,11722 .first_symbol_reloc = dwarf_global.debug_info_first_symbol_reloc,
11799 .first_node_reloc = dwarf_global.debug_info_first_node_reloc,11723 .first_node_reloc = dwarf_global.debug_info_first_node_reloc,
11800 });11724 });
...@@ -11810,22 +11734,21 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void...@@ -11810,22 +11734,21 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void
11810 elf.dwarf.updateEhFrameFde(ni.slice(&elf.mf), offset);11734 elf.dwarf.updateEhFrameFde(ni.slice(&elf.mf), offset);
11811 },11735 },
11812 }11736 }
11813 elf.flushMovedNodeRelocs(ni, elf.computeNodeVAddr(ni), .{11737 elf.flushMovedNodeRelocs(ni, .{
11814 .first_symbol_reloc = dwarf_func.frame_fde_first_symbol_reloc,11738 .first_symbol_reloc = dwarf_func.frame_fde_first_symbol_reloc,
11815 .first_node_reloc = dwarf_func.frame_fde_first_node_reloc,11739 .first_node_reloc = dwarf_func.frame_fde_first_node_reloc,
11816 });11740 });
11817 },11741 },
11818 .func_debug_info => |fi| {11742 .func_debug_info => |fi| {
11819 const dwarf_func = &elf.dwarf_funcs.items[@backingInt(fi)];11743 const dwarf_func = &elf.dwarf_funcs.items[@backingInt(fi)];
11820 const target_section_offset = elf.computeNodeSectionOffset(ni);
11821 var target_ri = dwarf_func.debug_info_first_target_reloc;11744 var target_ri = dwarf_func.debug_info_first_target_reloc;
11822 while (target_ri != .none) {11745 while (target_ri != .none) {
11823 const target_reloc = target_ri.get(elf);11746 const target_reloc = target_ri.get(elf);
11824 assert(target_reloc.target == ni);11747 assert(target_reloc.target == ni);
11825 target_reloc.flushMovedTarget(elf, target_section_offset);11748 target_reloc.apply(elf);
11826 target_ri = target_reloc.next;11749 target_ri = target_reloc.next;
11827 }11750 }
11828 elf.flushMovedNodeRelocs(ni, elf.computeNodeVAddr(ni), .{11751 elf.flushMovedNodeRelocs(ni, .{
11829 .first_symbol_reloc = dwarf_func.debug_info_first_symbol_reloc,11752 .first_symbol_reloc = dwarf_func.debug_info_first_symbol_reloc,
11830 .skip_symbol_relocs = if (elf.navs.getPtr(fi.nav(&elf.dwarf))) |nav|11753 .skip_symbol_relocs = if (elf.navs.getPtr(fi.nav(&elf.dwarf))) |nav|
11831 nav.lsi.index().ptr(elf).node11754 nav.lsi.index().ptr(elf).node
...@@ -11837,7 +11760,7 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void...@@ -11837,7 +11760,7 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void
11837 },11760 },
11838 .func_debug_line => |fi| {11761 .func_debug_line => |fi| {
11839 const dwarf_func = &elf.dwarf_funcs.items[@backingInt(fi)];11762 const dwarf_func = &elf.dwarf_funcs.items[@backingInt(fi)];
11840 elf.flushMovedNodeRelocs(ni, elf.computeNodeVAddr(ni), .{11763 elf.flushMovedNodeRelocs(ni, .{
11841 .first_symbol_reloc = dwarf_func.debug_line_first_symbol_reloc,11764 .first_symbol_reloc = dwarf_func.debug_line_first_symbol_reloc,
11842 .first_node_reloc = dwarf_func.debug_line_first_node_reloc,11765 .first_node_reloc = dwarf_func.debug_line_first_node_reloc,
11843 .skip_node_relocs = fi.get(&elf.dwarf).debug_info_ni,11766 .skip_node_relocs = fi.get(&elf.dwarf).debug_info_ni,
...@@ -11845,15 +11768,14 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void...@@ -11845,15 +11768,14 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void
11845 },11768 },
11846 .decl_debug_info => |di| {11769 .decl_debug_info => |di| {
11847 const dwarf_decl = &elf.dwarf_decls.get(di).?;11770 const dwarf_decl = &elf.dwarf_decls.get(di).?;
11848 const target_section_offset = elf.computeNodeSectionOffset(ni);
11849 var target_ri = dwarf_decl.debug_info_first_target_reloc;11771 var target_ri = dwarf_decl.debug_info_first_target_reloc;
11850 while (target_ri != .none) {11772 while (target_ri != .none) {
11851 const target_reloc = target_ri.get(elf);11773 const target_reloc = target_ri.get(elf);
11852 assert(target_reloc.target == ni);11774 assert(target_reloc.target == ni);
11853 target_reloc.flushMovedTarget(elf, target_section_offset);11775 target_reloc.apply(elf);
11854 target_ri = target_reloc.next;11776 target_ri = target_reloc.next;
11855 }11777 }
11856 elf.flushMovedNodeRelocs(ni, elf.computeNodeVAddr(ni), .{11778 elf.flushMovedNodeRelocs(ni, .{
11857 .first_node_reloc = dwarf_decl.debug_info_first_node_reloc,11779 .first_node_reloc = dwarf_decl.debug_info_first_node_reloc,
11858 });11780 });
11859 },11781 },