authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2026-08-02 16:02:49+01:00
committergravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2026-09-26 18:21:21+01:00
log4bd05848f28f413b415b29491ba0e2b3fa3c2dda
treef2270a6ea9a0eef4320f5ae1969fd8a4a02d9d65
parent0579c6a0254a00f5bb0d3cbef51ada1a1feaf500
signature Commit is signed but in an unrecognized format.

link: simplify public API

There was a bunch of legacy cruft in the linker's public API which was duplicating functionality, particularly regarding symbols and relocations. Move towards standardising on an interface based on `link.File.SymbolId`. The `navSymbol` and `uavSymbol` functions return `link.File.SymbolId`s representing a given NAV or UAV; then, with that `SymbolId`, codegen can call `relocSymAddr` to relocate that symbol's absolute address. The caller is responsible for writing placeholder bytes (probably zeroes) to be overwritten by that relocation. Previously the API told you an address to write in, but this was entirely redundant with the added relocation.

12 files changed, 122 insertions(+), 306 deletions(-)

src/codegen.zig+12-90
......@@ -754,23 +754,15 @@ fn lowerUavRef(
754754 }
755755
756756 const uav_align = Type.fromInterned(uav.orig_ty).ptrAlignment(zcu);
757 _ = try lf.lowerUav(pt, uav_val, uav_align);
758757
759 const vaddr = lf.getUavVAddr(uav_val, .{
758 try lf.relocSymAddr(.{
760759 .parent = reloc_parent,
761760 .offset = w.end,
761 .target = try lf.uavSymbol(pt, uav_val, uav_align),
762762 .addend = @intCast(offset),
763 }) catch |err| switch (err) {
764 error.OutOfMemory => |e| return e,
765 else => |e| std.debug.panic("TODO rework lowerUav. internal error: {t}", .{e}),
766 };
767 const endian = target.cpu.arch.endian();
768 switch (ptr_width_bytes) {
769 2 => try w.writeInt(u16, @intCast(vaddr), endian),
770 4 => try w.writeInt(u32, @intCast(vaddr), endian),
771 8 => try w.writeInt(u64, vaddr, endian),
772 else => unreachable,
773 }
763 });
764
765 try w.splatByteAll(0, ptr_width_bytes); // overwritten by relocation
774766}
775767
776768fn lowerNavRef(
......@@ -805,84 +797,14 @@ fn lowerNavRef(
805797 else => {},
806798 }
807799
808 const vaddr = lf.getNavVAddr(pt, nav_index, .{
800 try lf.relocSymAddr(.{
809801 .parent = reloc_parent,
810802 .offset = w.end,
803 .target = try lf.navSymbol(nav_index),
811804 .addend = @intCast(offset),
812 }) catch @panic("TODO rework getNavVAddr");
813 const endian = target.cpu.arch.endian();
814 switch (ptr_width_bytes) {
815 2 => try w.writeInt(u16, @intCast(vaddr), endian),
816 4 => try w.writeInt(u32, @intCast(vaddr), endian),
817 8 => try w.writeInt(u64, vaddr, endian),
818 else => unreachable,
819 }
820}
821
822pub fn genNavRef(
823 lf: *link.File,
824 pt: Zcu.PerThread,
825 nav_index: InternPool.Nav.Index,
826) Error!link.File.SymbolId {
827 const zcu = pt.zcu;
828 const ip = &zcu.intern_pool;
829 const nav = ip.getNav(nav_index);
830 log.debug("genNavRef({f})", .{nav.fqn.fmt(ip)});
805 });
831806
832 const is_threadlocal = nav.resolved.?.@"threadlocal" and zcu.comp.config.any_non_single_threaded;
833 const lib_name, const linkage = if (nav.getExtern(ip)) |e|
834 .{ e.lib_name, e.linkage }
835 else
836 .{ .none, .internal };
837 if (lf.cast(.elf)) |elf_file| {
838 const zo = elf_file.zigObjectPtr().?;
839 switch (linkage) {
840 .internal => {
841 const sym_index = try zo.getOrCreateMetadataForNav(zcu, nav_index);
842 if (is_threadlocal) zo.symbol(sym_index).flags.is_tls = true;
843 return @fromBackingInt(@intCast(sym_index));
844 },
845 .strong, .weak => {
846 const sym_index = try elf_file.getGlobalSymbol(nav.name.toSlice(ip), lib_name.toSlice(ip));
847 switch (linkage) {
848 .internal => unreachable,
849 .strong => {},
850 .weak => zo.symbol(sym_index).flags.weak = true,
851 .link_once => unreachable,
852 }
853 if (is_threadlocal) zo.symbol(sym_index).flags.is_tls = true;
854 return @fromBackingInt(@intCast(sym_index));
855 },
856 .link_once => unreachable,
857 }
858 } else if (lf.cast(.elf2)) |elf| {
859 return elf.navSymbol(nav_index);
860 } else if (lf.cast(.macho)) |macho_file| {
861 const zo = macho_file.getZigObject().?;
862 switch (linkage) {
863 .internal => {
864 const sym_index = try zo.getOrCreateMetadataForNav(macho_file, nav_index);
865 if (is_threadlocal) zo.symbols.items[sym_index].flags.tlv = true;
866 return @fromBackingInt(@intCast(sym_index));
867 },
868 .strong, .weak => {
869 const sym_index = try macho_file.getGlobalSymbol(nav.name.toSlice(ip), lib_name.toSlice(ip));
870 switch (linkage) {
871 .internal => unreachable,
872 .strong => {},
873 .weak => zo.symbols.items[sym_index].flags.weak = true,
874 .link_once => unreachable,
875 }
876 if (is_threadlocal) zo.symbols.items[sym_index].flags.tlv = true;
877 return @fromBackingInt(@intCast(sym_index));
878 },
879 .link_once => unreachable,
880 }
881 } else if (lf.cast(.coff)) |coff| {
882 return @fromBackingInt(@intCast(@backingInt(try coff.navSymbol(zcu, nav_index))));
883 } else {
884 std.debug.panic("TODO genNavRef for '{t}'", .{lf.tag});
885 }
807 try w.splatByteAll(0, ptr_width_bytes); // overwritten by relocation
886808}
887809
888810/// deprecated legacy type
......@@ -924,13 +846,13 @@ pub fn genTypedValue(
924846 .none => .none,
925847 .undef => .undef,
926848 .immediate => |imm| .{ .immediate = imm },
927 .lea_nav => |nav| .{ .lea_symbol = try genNavRef(lf, pt, nav) },
928 .load_uav => |uav| .{ .load_symbol = try lf.lowerUav(
849 .lea_nav => |nav| .{ .lea_symbol = try lf.navSymbol(nav) },
850 .load_uav => |uav| .{ .load_symbol = try lf.uavSymbol(
929851 pt,
930852 uav.val,
931853 Type.fromInterned(uav.orig_ty).ptrAlignment(pt.zcu),
932854 ) },
933 .lea_uav => |uav| .{ .lea_symbol = try lf.lowerUav(
855 .lea_uav => |uav| .{ .lea_symbol = try lf.uavSymbol(
934856 pt,
935857 uav.val,
936858 Type.fromInterned(uav.orig_ty).ptrAlignment(pt.zcu),
src/codegen/aarch64/Mir.zig+2-6
......@@ -93,11 +93,7 @@ pub fn emit(
9393 lf,
9494 zcu,
9595 atom_index,
96 try @import("../../codegen.zig").genNavRef(
97 lf,
98 pt,
99 nav_reloc.nav,
100 ),
96 try lf.navSymbol(nav_reloc.nav),
10197 mir.body[nav_reloc.reloc.label],
10298 body_end - Instruction.size * (1 + nav_reloc.reloc.label),
10399 nav_reloc.reloc.addend,
......@@ -107,7 +103,7 @@ pub fn emit(
107103 lf,
108104 zcu,
109105 atom_index,
110 try lf.lowerUav(
106 try lf.uavSymbol(
111107 pt,
112108 uav_reloc.uav.val,
113109 ZigType.fromInterned(uav_reloc.uav.orig_ty).ptrAlignment(zcu),
src/codegen/loongarch/Mir.zig+3-12
......@@ -83,11 +83,7 @@ pub fn emit(
8383 lf,
8484 zcu,
8585 atom_index,
86 try @import("../../codegen.zig").genNavRef(
87 lf,
88 pt,
89 nav_reloc.nav,
90 ),
86 try lf.navSymbol(nav_reloc.nav),
9187 nav_reloc.reloc.type,
9288 body_end - @sizeOf(Instruction) * (1 + nav_reloc.reloc.label),
9389 nav_reloc.reloc.addend,
......@@ -97,7 +93,7 @@ pub fn emit(
9793 lf,
9894 zcu,
9995 atom_index,
100 try lf.lowerUav(
96 try lf.uavSymbol(
10197 pt,
10298 uav_reloc.uav.val,
10399 ZigType.fromInterned(uav_reloc.uav.orig_ty).ptrAlignment(zcu),
......@@ -142,16 +138,11 @@ pub fn emit(
142138 ) catch |err|
143139 return zcu.codegenFail(func.owner_nav, "emit reloc failed: {t}", .{err});
144140
145 const func_nav = try @import("../../codegen.zig").genNavRef(
146 lf,
147 pt,
148 func.owner_nav,
149 );
150141 for (mir.internal_relocs) |internal_reloc| emitReloc(
151142 lf,
152143 zcu,
153144 atom_index,
154 func_nav,
145 try lf.navSymbol(func.owner_nav),
155146 internal_reloc.reloc.type,
156147 body_end - @sizeOf(Instruction) * (1 + internal_reloc.reloc.label),
157148 @sizeOf(Instruction) * (@as(i64, @intCast(mir.prologue.len + mir.body.len - internal_reloc.target))),
src/codegen/riscv64/CodeGen.zig+1-1
......@@ -8160,7 +8160,7 @@ fn genTypedValue(func: *Func, val: Value) InnerError!MCValue {
81608160 const lf = func.bin_file;
81618161
81628162 const result: codegen.MCValue = if (val.isUndef(pt.zcu))
8163 .{ .load_symbol = try lf.lowerUav(pt, val.toIntern(), .none) }
8163 .{ .load_symbol = try lf.uavSymbol(pt, val.toIntern(), .none) }
81648164 else
81658165 try codegen.genTypedValue(lf, pt, val, func.target);
81668166 const mcv: MCValue = switch (result) {
src/codegen/x86_64/Emit.zig+4-8
......@@ -100,11 +100,7 @@ pub fn emitMir(emit: *Emit) Error!void {
100100 .inst => |inst| .{ .inst = inst },
101101 .table => .table,
102102 .nav => |nav| {
103 const symbol_id = try codegen.genNavRef(
104 emit.bin_file,
105 emit.pt,
106 nav,
107 );
103 const symbol_id = try emit.bin_file.navSymbol(nav);
108104 const target_symbol: RelocInfo.Target.Symbol = if (ip.getNav(nav).getExtern(ip)) |@"extern"| .{
109105 .symbol = symbol_id,
110106 .is_extern = switch (@"extern".visibility) {
......@@ -124,7 +120,7 @@ pub fn emitMir(emit: *Emit) Error!void {
124120 }
125121 },
126122 .uav => |uav| .{ .symbol = .{
127 .symbol = try emit.bin_file.lowerUav(
123 .symbol = try emit.bin_file.uavSymbol(
128124 emit.pt,
129125 uav.val,
130126 Type.fromInterned(uav.orig_ty).ptrAlignment(emit.pt.zcu),
......@@ -597,12 +593,12 @@ pub fn emitMir(emit: *Emit) Error!void {
597593 .nav => |nav| @unionInit(
598594 DwarfLoc,
599595 addr_loc,
600 try codegen.genNavRef(emit.bin_file, emit.pt, nav),
596 try emit.bin_file.navSymbol(nav),
601597 ),
602598 .uav => |uav| @unionInit(
603599 DwarfLoc,
604600 addr_loc,
605 try emit.bin_file.lowerUav(
601 try emit.bin_file.uavSymbol(
606602 emit.pt,
607603 uav.val,
608604 Type.fromInterned(uav.orig_ty)
src/link.zig+10-18
......@@ -1039,6 +1039,7 @@ pub const File = struct {
10391039 pub const RelocInfo = struct {
10401040 parent: Parent,
10411041 offset: u64,
1042 target: SymbolId,
10421043 addend: u32,
10431044
10441045 pub const Parent = union(enum) {
......@@ -1048,16 +1049,9 @@ pub const File = struct {
10481049 };
10491050 };
10501051
1051 /// Get allocated `Nav`'s address in virtual memory.
1052 /// The linker is passed information about the containing atom, `parent_atom_index`, and offset within it's
1053 /// memory buffer, `offset`, so that it can make a note of potential relocation sites, should the
1054 /// `Nav`'s address was not yet resolved, or the containing atom gets moved in virtual memory.
1055 /// May be called before or after updateFunc/updateNav therefore it is up to the linker to allocate
1056 /// the block/atom.
10571052 /// Never called when LLVM is codegenning the ZCU.
1058 pub fn getNavVAddr(base: *File, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index, reloc_info: RelocInfo) Error!u64 {
1059 assert(pt.zcu.llvm_object == null);
1060
1053 pub fn relocSymAddr(base: *File, reloc_info: RelocInfo) Error!void {
1054 assert(base.comp.zcu.?.llvm_object == null);
10611055 switch (base.tag) {
10621056 .lld => unreachable,
10631057 .c => unreachable,
......@@ -1067,20 +1061,19 @@ pub const File = struct {
10671061 .spork8 => unreachable,
10681062 inline else => |tag| {
10691063 dev.check(tag.devFeature());
1070 return @as(*tag.Type(), @fieldParentPtr("base", base)).getNavVAddr(pt, nav_index, reloc_info);
1064 return @as(*tag.Type(), @fieldParentPtr("base", base)).relocSymAddr(reloc_info);
10711065 },
10721066 }
10731067 }
10741068
10751069 /// Never called when LLVM is codegenning the ZCU.
1076 pub fn lowerUav(
1070 pub fn uavSymbol(
10771071 base: *File,
10781072 pt: Zcu.PerThread,
1079 decl_val: InternPool.Index,
1080 decl_align: InternPool.Alignment,
1073 uav_val: InternPool.Index,
1074 uav_align: InternPool.Alignment,
10811075 ) Error!SymbolId {
10821076 assert(pt.zcu.llvm_object == null);
1083
10841077 switch (base.tag) {
10851078 .lld => unreachable,
10861079 .c => unreachable,
......@@ -1090,15 +1083,14 @@ pub const File = struct {
10901083 .spork8 => unreachable,
10911084 inline else => |tag| {
10921085 dev.check(tag.devFeature());
1093 return @as(*tag.Type(), @fieldParentPtr("base", base)).lowerUav(pt, decl_val, decl_align);
1086 return @as(*tag.Type(), @fieldParentPtr("base", base)).uavSymbol(pt, uav_val, uav_align);
10941087 },
10951088 }
10961089 }
10971090
10981091 /// Never called when LLVM is codegenning the ZCU.
1099 pub fn getUavVAddr(base: *File, decl_val: InternPool.Index, reloc_info: RelocInfo) Error!u64 {
1092 pub fn navSymbol(base: *File, nav: InternPool.Nav.Index) Error!SymbolId {
11001093 assert(base.comp.zcu.?.llvm_object == null);
1101
11021094 switch (base.tag) {
11031095 .lld => unreachable,
11041096 .c => unreachable,
......@@ -1108,7 +1100,7 @@ pub const File = struct {
11081100 .spork8 => unreachable,
11091101 inline else => |tag| {
11101102 dev.check(tag.devFeature());
1111 return @as(*tag.Type(), @fieldParentPtr("base", base)).getUavVAddr(decl_val, reloc_info);
1103 return @as(*tag.Type(), @fieldParentPtr("base", base)).navSymbol(nav);
11121104 },
11131105 }
11141106 }
src/link/Coff.zig+13-34
......@@ -2935,18 +2935,19 @@ fn navMapIndex(coff: *Coff, zcu: *Zcu, nav_index: InternPool.Nav.Index) !Node.Na
29352935 if (!sym_gop.found_existing) sym_gop.value_ptr.* = coff.addSymbolAssumeCapacity();
29362936 return @fromBackingInt(@intCast(sym_gop.index));
29372937}
2938pub fn navSymbol(coff: *Coff, zcu: *Zcu, nav_index: InternPool.Nav.Index) !Symbol.Index {
2938pub fn navSymbol(coff: *Coff, nav_index: InternPool.Nav.Index) link.Error!link.File.SymbolId {
2939 const zcu = coff.base.comp.zcu.?;
29392940 const ip = &zcu.intern_pool;
29402941 const nav = ip.getNav(nav_index);
2941 if (nav.getExtern(ip)) |@"extern"| return coff.globalSymbol(.{
2942 if (nav.getExtern(ip)) |@"extern"| return @bitCast(try coff.globalSymbol(.{
29422943 .name = @"extern".name.toSlice(ip),
29432944 .lib_name = @"extern".lib_name.toSlice(ip),
29442945 // TODO: Threadlocal as well?
29452946 .type = if (ip.isFunctionType(nav.resolved.?.type)) .code else .data,
29462947 .dll_storage_class = if (@"extern".is_dll_import) .dllimport else .default,
2947 });
2948 }));
29482949 const nmi = try coff.navMapIndex(zcu, nav_index);
2949 return nmi.symbol(coff);
2950 return @bitCast(nmi.symbol(coff));
29502951}
29512952
29522953fn uavMapIndex(coff: *Coff, uav_val: InternPool.Index) !Node.UavMapIndex {
......@@ -2956,10 +2957,6 @@ fn uavMapIndex(coff: *Coff, uav_val: InternPool.Index) !Node.UavMapIndex {
29562957 if (!sym_gop.found_existing) sym_gop.value_ptr.* = coff.addSymbolAssumeCapacity();
29572958 return @fromBackingInt(@intCast(sym_gop.index));
29582959}
2959pub fn uavSymbol(coff: *Coff, uav_val: InternPool.Index) !Symbol.Index {
2960 const umi = try coff.uavMapIndex(uav_val);
2961 return umi.symbol(coff);
2962}
29632960
29642961pub fn lazySymbol(coff: *Coff, lazy: link.File.LazySymbol) !Symbol.Index {
29652962 const gpa = coff.base.comp.gpa;
......@@ -2972,24 +2969,8 @@ pub fn lazySymbol(coff: *Coff, lazy: link.File.LazySymbol) !Symbol.Index {
29722969 return sym_gop.value_ptr.*;
29732970}
29742971
2975pub fn getNavVAddr(
2976 coff: *Coff,
2977 pt: Zcu.PerThread,
2978 nav: InternPool.Nav.Index,
2979 reloc_info: link.File.RelocInfo,
2980) link.Error!u64 {
2981 return coff.getVAddr(reloc_info, try coff.navSymbol(pt.zcu, nav));
2982}
2983
2984pub fn getUavVAddr(
2985 coff: *Coff,
2986 uav: InternPool.Index,
2987 reloc_info: link.File.RelocInfo,
2988) link.Error!u64 {
2989 return coff.getVAddr(reloc_info, try coff.uavSymbol(uav));
2990}
2991
2992pub fn getVAddr(coff: *Coff, reloc_info: link.File.RelocInfo, target_si: Symbol.Index) link.Error!u64 {
2972pub fn relocSymAddr(coff: *Coff, reloc_info: link.File.RelocInfo) link.Error!void {
2973 const target_si: Symbol.Index = @bitCast(reloc_info.target);
29932974 try coff.addReloc(
29942975 @fromBackingInt(@intCast(@backingInt(reloc_info.parent.atom_index))),
29952976 reloc_info.offset,
......@@ -3001,10 +2982,6 @@ pub fn getVAddr(coff: *Coff, reloc_info: link.File.RelocInfo, target_si: Symbol.
30012982 .I386 => .{ .I386 = .DIR32 },
30022983 },
30032984 );
3004
3005 var vaddr: u64 = target_si.get(coff).rva;
3006 if (coff.isImage()) vaddr += coff.optionalHeaderField(.image_base);
3007 return vaddr;
30082985}
30092986
30102987/// Caller guarantees there is capacity for one member and two nodes
......@@ -5580,13 +5557,15 @@ pub fn updateContainerType(
55805557 };
55815558}
55825559
5583pub fn lowerUav(
5560pub fn uavSymbol(
55845561 coff: *Coff,
55855562 pt: Zcu.PerThread,
55865563 uav_val: InternPool.Index,
55875564 uav_align: InternPool.Alignment,
55885565) link.Error!link.File.SymbolId {
5589 const zcu = pt.zcu;
5566 _ = pt;
5567
5568 const zcu = coff.base.comp.zcu.?;
55905569 const gpa = zcu.gpa;
55915570
55925571 try coff.pending_uavs.ensureUnusedCapacity(gpa, 1);
......@@ -7471,8 +7450,8 @@ fn updateExportInner(
74717450
74727451 try coff.symbols.ensureUnusedCapacity(gpa, 1);
74737452 const exported_si: Symbol.Index = switch (exp.exported) {
7474 .nav => |nav| try coff.navSymbol(zcu, nav),
7475 .uav => |uav| @fromBackingInt(@intCast(@backingInt(try coff.lowerUav(
7453 .nav => |nav| @bitCast(try coff.navSymbol(nav)),
7454 .uav => |uav| @fromBackingInt(@intCast(@backingInt(try coff.uavSymbol(
74767455 pt,
74777456 uav,
74787457 Type.fromInterned(ip.typeOf(uav)).abiAlignment(zcu),
src/link/Elf.zig+8-8
......@@ -463,21 +463,21 @@ pub fn deinit(self: *Elf) void {
463463 self.dump_argv_list.deinit(gpa);
464464}
465465
466pub fn getNavVAddr(self: *Elf, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index, reloc_info: link.File.RelocInfo) !u64 {
467 return self.zigObjectPtr().?.getNavVAddr(self, pt, nav_index, reloc_info);
466pub fn navSymbol(self: *Elf, nav: InternPool.Nav.Index) link.Error!link.File.SymbolId {
467 return self.zigObjectPtr().?.navSymbol(self, nav);
468468}
469469
470pub fn lowerUav(
470pub fn relocSymAddr(self: *Elf, reloc_info: link.File.RelocInfo) !void {
471 return self.zigObjectPtr().?.relocSymAddr(self, reloc_info);
472}
473
474pub fn uavSymbol(
471475 self: *Elf,
472476 pt: Zcu.PerThread,
473477 uav: InternPool.Index,
474478 explicit_alignment: InternPool.Alignment,
475479) !link.File.SymbolId {
476 return self.zigObjectPtr().?.lowerUav(self, pt, uav, explicit_alignment);
477}
478
479pub fn getUavVAddr(self: *Elf, uav: InternPool.Index, reloc_info: link.File.RelocInfo) !u64 {
480 return self.zigObjectPtr().?.getUavVAddr(self, uav, reloc_info);
480 return self.zigObjectPtr().?.uavSymbol(self, pt, uav, explicit_alignment);
481481}
482482
483483/// Returns end pos of collision, if any.
src/link/Elf/ZigObject.zig+30-42
......@@ -917,53 +917,42 @@ pub fn codeAlloc(self: *ZigObject, elf_file: *Elf, atom_index: Atom.Index) ![]u8
917917 return code;
918918}
919919
920pub fn getNavVAddr(
921 self: *ZigObject,
920pub fn navSymbol(
921 zo: *ZigObject,
922922 elf_file: *Elf,
923 pt: Zcu.PerThread,
924923 nav_index: InternPool.Nav.Index,
925 reloc_info: link.File.RelocInfo,
926) !u64 {
927 const zcu = pt.zcu;
924) link.Error!link.File.SymbolId {
925 const zcu = elf_file.base.comp.zcu.?;
928926 const ip = &zcu.intern_pool;
929927 const nav = ip.getNav(nav_index);
930 log.debug("getNavVAddr {f}({d})", .{ nav.fqn.fmt(ip), nav_index });
931 const this_sym_index = if (nav.getExtern(ip)) |@"extern"| try self.getGlobalSymbol(
932 elf_file,
933 nav.name.toSlice(ip),
934 @"extern".lib_name.toSlice(ip),
935 ) else try self.getOrCreateMetadataForNav(zcu, nav_index);
936 const this_sym = self.symbol(this_sym_index);
937 const vaddr = this_sym.address(.{}, elf_file);
938 switch (reloc_info.parent) {
939 .none => unreachable,
940 .atom_index => |atom_index| {
941 const parent_atom = self.symbol(@backingInt(atom_index)).atom(elf_file).?;
942 const r_type = relocation.encode(.abs, elf_file.getTarget().cpu.arch);
943 try parent_atom.addReloc(elf_file.base.comp.gpa, .{
944 .r_offset = reloc_info.offset,
945 .r_info = (@as(u64, @intCast(this_sym_index)) << 32) | r_type,
946 .r_addend = reloc_info.addend,
947 }, self);
948 },
949 .debug_output => |debug_output| try debug_output.dwarf.infoExternalReloc(.{
950 .source_off = @intCast(reloc_info.offset),
951 .target_sym = @fromBackingInt(@intCast(this_sym_index)),
952 .target_off = reloc_info.addend,
953 }),
928 if (nav.getExtern(ip)) |@"extern"| {
929 const sym_index = try zo.getGlobalSymbol(
930 elf_file,
931 nav.name.toSlice(ip),
932 @"extern".lib_name.toSlice(ip),
933 );
934 if (@"extern".linkage == .weak) {
935 zo.symbol(sym_index).flags.weak = true;
936 }
937 if (nav.resolved.?.@"threadlocal") {
938 zo.symbol(sym_index).flags.is_tls = true;
939 }
940 return @fromBackingInt(sym_index);
941 } else {
942 const sym_index = try zo.getOrCreateMetadataForNav(zcu, nav_index);
943 if (nav.resolved.?.@"threadlocal") {
944 zo.symbol(sym_index).flags.is_tls = true;
945 }
946 return @fromBackingInt(sym_index);
954947 }
955 return @intCast(vaddr);
956948}
957949
958pub fn getUavVAddr(
950pub fn relocSymAddr(
959951 self: *ZigObject,
960952 elf_file: *Elf,
961 uav: InternPool.Index,
962953 reloc_info: link.File.RelocInfo,
963) !u64 {
964 const sym_index = self.uavs.get(uav).?.symbol_index;
965 const sym = self.symbol(sym_index);
966 const vaddr = sym.address(.{}, elf_file);
954) !void {
955 const this_sym_index = @backingInt(reloc_info.target);
967956 switch (reloc_info.parent) {
968957 .none => unreachable,
969958 .atom_index => |atom_index| {
......@@ -971,20 +960,19 @@ pub fn getUavVAddr(
971960 const r_type = relocation.encode(.abs, elf_file.getTarget().cpu.arch);
972961 try parent_atom.addReloc(elf_file.base.comp.gpa, .{
973962 .r_offset = reloc_info.offset,
974 .r_info = (@as(u64, @intCast(sym_index)) << 32) | r_type,
963 .r_info = (@as(u64, @intCast(this_sym_index)) << 32) | r_type,
975964 .r_addend = reloc_info.addend,
976965 }, self);
977966 },
978967 .debug_output => |debug_output| try debug_output.dwarf.infoExternalReloc(.{
979968 .source_off = @intCast(reloc_info.offset),
980 .target_sym = @fromBackingInt(@intCast(sym_index)),
969 .target_sym = @fromBackingInt(@intCast(this_sym_index)),
981970 .target_off = reloc_info.addend,
982971 }),
983972 }
984 return @intCast(vaddr);
985973}
986974
987pub fn lowerUav(
975pub fn uavSymbol(
988976 self: *ZigObject,
989977 elf_file: *Elf,
990978 pt: Zcu.PerThread,
......@@ -1889,7 +1877,7 @@ pub fn updateExports(
18891877 break :blk self.navs.getPtr(nav).?;
18901878 },
18911879 .uav => |uav| self.uavs.getPtr(uav) orelse blk: {
1892 _ = try self.lowerUav(elf_file, pt, uav, .none);
1880 _ = try self.uavSymbol(elf_file, pt, uav, .none);
18931881 break :blk self.uavs.getPtr(uav).?;
18941882 },
18951883 };
src/link/Elf2.zig+3-33
......@@ -4326,36 +4326,7 @@ pub fn navSymbol(elf: *Elf, nav_index: InternPool.Nav.Index) link.Error!link.Fil
43264326 const s: Symbol.Id = .local(nmi.symbol(elf));
43274327 return s.toTypeErased();
43284328}
4329pub fn uavSymbol(
4330 elf: *Elf,
4331 uav_val: InternPool.Index,
4332 uav_align: InternPool.Alignment,
4333) link.Error!link.File.SymbolId {
4334 const diags = &elf.base.comp.link_diags;
4335 const umi = elf.uavMapIndex(uav_val, uav_align) catch |err| switch (err) {
4336 else => |e| return e,
4337 error.MappedFileIo => return diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}),
4338 };
4339 const s: Symbol.Id = .local(umi.symbol(elf));
4340 return s.toTypeErased();
4341}
4342pub fn getNavVAddr(
4343 elf: *Elf,
4344 pt: Zcu.PerThread,
4345 nav: InternPool.Nav.Index,
4346 reloc_info: link.File.RelocInfo,
4347) link.Error!u64 {
4348 _ = pt;
4349 return elf.getVAddr(reloc_info, try elf.navSymbol(nav));
4350}
4351pub fn getUavVAddr(
4352 elf: *Elf,
4353 uav_val: InternPool.Index,
4354 reloc_info: link.File.RelocInfo,
4355) link.Error!u64 {
4356 return elf.getVAddr(reloc_info, try elf.uavSymbol(uav_val, .none));
4357}
4358pub fn getVAddr(elf: *Elf, reloc_info: link.File.RelocInfo, target: link.File.SymbolId) link.Error!u64 {
4329pub fn relocSymAddr(elf: *Elf, reloc_info: link.File.RelocInfo) link.Error!void {
43594330 try elf.addReloc(
43604331 switch (reloc_info.parent) {
43614332 .none => unreachable,
......@@ -4363,13 +4334,12 @@ pub fn getVAddr(elf: *Elf, reloc_info: link.File.RelocInfo, target: link.File.Sy
43634334 .debug_output => |debug_output| Node.toAtom(debug_output.dwarf2.info_writer.ni),
43644335 },
43654336 reloc_info.offset,
4366 target,
4337 reloc_info.target,
43674338 reloc_info.addend,
43684339 .absAddr(elf),
43694340 );
4370 return Symbol.Id.fromTypeErased(target).value(elf);
43714341}
4372pub fn lowerUav(
4342pub fn uavSymbol(
43734343 elf: *Elf,
43744344 pt: Zcu.PerThread,
43754345 uav_val: InternPool.Index,
src/link/MachO.zig+8-8
......@@ -3124,21 +3124,21 @@ pub fn freeNav(self: *MachO, nav: InternPool.Nav.Index) void {
31243124 return self.getZigObject().?.freeNav(nav);
31253125}
31263126
3127pub fn getNavVAddr(self: *MachO, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index, reloc_info: link.File.RelocInfo) !u64 {
3128 return self.getZigObject().?.getNavVAddr(self, pt, nav_index, reloc_info);
3127pub fn navSymbol(self: *MachO, nav: InternPool.Nav.Index) link.Error!link.File.SymbolId {
3128 return self.getZigObject().?.navSymbol(self, nav);
31293129}
31303130
3131pub fn lowerUav(
3131pub fn relocSymAddr(self: *MachO, reloc_info: link.File.RelocInfo) link.Error!void {
3132 return self.getZigObject().?.relocSymAddr(self, reloc_info);
3133}
3134
3135pub fn uavSymbol(
31323136 self: *MachO,
31333137 pt: Zcu.PerThread,
31343138 uav: InternPool.Index,
31353139 explicit_alignment: InternPool.Alignment,
31363140) !link.File.SymbolId {
3137 return self.getZigObject().?.lowerUav(self, pt, uav, explicit_alignment);
3138}
3139
3140pub fn getUavVAddr(self: *MachO, uav: InternPool.Index, reloc_info: link.File.RelocInfo) !u64 {
3141 return self.getZigObject().?.getUavVAddr(self, uav, reloc_info);
3141 return self.getZigObject().?.uavSymbol(self, pt, uav, explicit_alignment);
31423142}
31433143
31443144pub fn getGlobalSymbol(self: *MachO, name: []const u8, lib_name: ?[]const u8) !u32 {
src/link/MachO/ZigObject.zig+28-46
......@@ -611,60 +611,43 @@ pub fn flush(self: *ZigObject, macho_file: *MachO, tid: Zcu.PerThread.Id) link.E
611611 assert(!self.debug_strtab_dirty);
612612}
613613
614pub fn getNavVAddr(
615 self: *ZigObject,
614pub fn navSymbol(
615 zo: *ZigObject,
616616 macho_file: *MachO,
617 pt: Zcu.PerThread,
618617 nav_index: InternPool.Nav.Index,
619 reloc_info: link.File.RelocInfo,
620) !u64 {
621 const zcu = pt.zcu;
618) link.Error!link.File.SymbolId {
619 const zcu = macho_file.base.comp.zcu.?;
622620 const ip = &zcu.intern_pool;
623621 const nav = ip.getNav(nav_index);
624 log.debug("getNavVAddr {f}({d})", .{ nav.fqn.fmt(ip), nav_index });
625 const sym_index = if (nav.getExtern(ip)) |@"extern"| try self.getGlobalSymbol(
626 macho_file,
627 nav.name.toSlice(ip),
628 @"extern".lib_name.toSlice(ip),
629 ) else try self.getOrCreateMetadataForNav(macho_file, nav_index);
630 const sym = self.symbols.items[sym_index];
631 const vaddr = sym.getAddress(.{}, macho_file);
632 switch (reloc_info.parent) {
633 .none => unreachable,
634 .atom_index => |atom_index| {
635 const parent_atom = self.symbols.items[@backingInt(atom_index)].getAtom(macho_file).?;
636 try parent_atom.addReloc(macho_file, .{
637 .tag = .@"extern",
638 .offset = @intCast(reloc_info.offset),
639 .target = sym_index,
640 .addend = reloc_info.addend,
641 .type = .unsigned,
642 .meta = .{
643 .pcrel = false,
644 .has_subtractor = false,
645 .length = 3,
646 .symbolnum = @intCast(sym.nlist_idx),
647 },
648 });
649 },
650 .debug_output => |debug_output| try debug_output.dwarf.infoExternalReloc(.{
651 .source_off = @intCast(reloc_info.offset),
652 .target_sym = @fromBackingInt(@intCast(sym_index)),
653 .target_off = reloc_info.addend,
654 }),
622 if (nav.getExtern(ip)) |@"extern"| {
623 const sym_index = try zo.getGlobalSymbol(
624 macho_file,
625 nav.name.toSlice(ip),
626 @"extern".lib_name.toSlice(ip),
627 );
628 if (@"extern".linkage == .weak) {
629 zo.symbols.items[sym_index].flags.weak = true;
630 }
631 if (nav.resolved.?.@"threadlocal") {
632 zo.symbols.items[sym_index].flags.tlv = true;
633 }
634 return @fromBackingInt(sym_index);
635 } else {
636 const sym_index = try zo.getOrCreateMetadataForNav(macho_file, nav_index);
637 if (nav.resolved.?.@"threadlocal") {
638 zo.symbols.items[sym_index].flags.tlv = true;
639 }
640 return @fromBackingInt(sym_index);
655641 }
656 return vaddr;
657642}
658643
659pub fn getUavVAddr(
644pub fn relocSymAddr(
660645 self: *ZigObject,
661646 macho_file: *MachO,
662 uav: InternPool.Index,
663647 reloc_info: link.File.RelocInfo,
664) !u64 {
665 const sym_index = self.uavs.get(uav).?.symbol_index;
648) !void {
649 const sym_index = @backingInt(reloc_info.target);
666650 const sym = self.symbols.items[sym_index];
667 const vaddr = sym.getAddress(.{}, macho_file);
668651 switch (reloc_info.parent) {
669652 .none => unreachable,
670653 .atom_index => |atom_index| {
......@@ -689,10 +672,9 @@ pub fn getUavVAddr(
689672 .target_off = reloc_info.addend,
690673 }),
691674 }
692 return vaddr;
693675}
694676
695pub fn lowerUav(
677pub fn uavSymbol(
696678 self: *ZigObject,
697679 macho_file: *MachO,
698680 pt: Zcu.PerThread,
......@@ -1281,7 +1263,7 @@ pub fn updateExports(
12811263 break :blk self.navs.getPtr(nav).?;
12821264 },
12831265 .uav => |uav| self.uavs.getPtr(uav) orelse blk: {
1284 _ = try self.lowerUav(macho_file, pt, uav, .none);
1266 _ = try self.uavSymbol(macho_file, pt, uav, .none);
12851267 break :blk self.uavs.getPtr(uav).?;
12861268 },
12871269 };