diff --git a/src/codegen.zig b/src/codegen.zig index b8917bc02ccc0bf6f262d3eb090472f59aaf1dea..2213e7ee506d2156be699188d8d666c1c22d4e7b 100644 --- a/src/codegen.zig +++ b/src/codegen.zig @@ -754,23 +754,15 @@ fn lowerUavRef( } const uav_align = Type.fromInterned(uav.orig_ty).ptrAlignment(zcu); - _ = try lf.lowerUav(pt, uav_val, uav_align); - const vaddr = lf.getUavVAddr(uav_val, .{ + try lf.relocSymAddr(.{ .parent = reloc_parent, .offset = w.end, + .target = try lf.uavSymbol(pt, uav_val, uav_align), .addend = @intCast(offset), - }) catch |err| switch (err) { - error.OutOfMemory => |e| return e, - else => |e| std.debug.panic("TODO rework lowerUav. internal error: {t}", .{e}), - }; - const endian = target.cpu.arch.endian(); - switch (ptr_width_bytes) { - 2 => try w.writeInt(u16, @intCast(vaddr), endian), - 4 => try w.writeInt(u32, @intCast(vaddr), endian), - 8 => try w.writeInt(u64, vaddr, endian), - else => unreachable, - } + }); + + try w.splatByteAll(0, ptr_width_bytes); // overwritten by relocation } fn lowerNavRef( @@ -805,84 +797,14 @@ fn lowerNavRef( else => {}, } - const vaddr = lf.getNavVAddr(pt, nav_index, .{ + try lf.relocSymAddr(.{ .parent = reloc_parent, .offset = w.end, + .target = try lf.navSymbol(nav_index), .addend = @intCast(offset), - }) catch @panic("TODO rework getNavVAddr"); - const endian = target.cpu.arch.endian(); - switch (ptr_width_bytes) { - 2 => try w.writeInt(u16, @intCast(vaddr), endian), - 4 => try w.writeInt(u32, @intCast(vaddr), endian), - 8 => try w.writeInt(u64, vaddr, endian), - else => unreachable, - } -} + }); -pub fn genNavRef( - lf: *link.File, - pt: Zcu.PerThread, - nav_index: InternPool.Nav.Index, -) Error!link.File.SymbolId { - const zcu = pt.zcu; - const ip = &zcu.intern_pool; - const nav = ip.getNav(nav_index); - log.debug("genNavRef({f})", .{nav.fqn.fmt(ip)}); - - const is_threadlocal = nav.resolved.?.@"threadlocal" and zcu.comp.config.any_non_single_threaded; - const lib_name, const linkage = if (nav.getExtern(ip)) |e| - .{ e.lib_name, e.linkage } - else - .{ .none, .internal }; - if (lf.cast(.elf)) |elf_file| { - const zo = elf_file.zigObjectPtr().?; - switch (linkage) { - .internal => { - const sym_index = try zo.getOrCreateMetadataForNav(zcu, nav_index); - if (is_threadlocal) zo.symbol(sym_index).flags.is_tls = true; - return @fromBackingInt(@intCast(sym_index)); - }, - .strong, .weak => { - const sym_index = try elf_file.getGlobalSymbol(nav.name.toSlice(ip), lib_name.toSlice(ip)); - switch (linkage) { - .internal => unreachable, - .strong => {}, - .weak => zo.symbol(sym_index).flags.weak = true, - .link_once => unreachable, - } - if (is_threadlocal) zo.symbol(sym_index).flags.is_tls = true; - return @fromBackingInt(@intCast(sym_index)); - }, - .link_once => unreachable, - } - } else if (lf.cast(.elf2)) |elf| { - return elf.navSymbol(nav_index); - } else if (lf.cast(.macho)) |macho_file| { - const zo = macho_file.getZigObject().?; - switch (linkage) { - .internal => { - const sym_index = try zo.getOrCreateMetadataForNav(macho_file, nav_index); - if (is_threadlocal) zo.symbols.items[sym_index].flags.tlv = true; - return @fromBackingInt(@intCast(sym_index)); - }, - .strong, .weak => { - const sym_index = try macho_file.getGlobalSymbol(nav.name.toSlice(ip), lib_name.toSlice(ip)); - switch (linkage) { - .internal => unreachable, - .strong => {}, - .weak => zo.symbols.items[sym_index].flags.weak = true, - .link_once => unreachable, - } - if (is_threadlocal) zo.symbols.items[sym_index].flags.tlv = true; - return @fromBackingInt(@intCast(sym_index)); - }, - .link_once => unreachable, - } - } else if (lf.cast(.coff)) |coff| { - return @fromBackingInt(@intCast(@backingInt(try coff.navSymbol(zcu, nav_index)))); - } else { - std.debug.panic("TODO genNavRef for '{t}'", .{lf.tag}); - } + try w.splatByteAll(0, ptr_width_bytes); // overwritten by relocation } /// deprecated legacy type @@ -924,13 +846,13 @@ pub fn genTypedValue( .none => .none, .undef => .undef, .immediate => |imm| .{ .immediate = imm }, - .lea_nav => |nav| .{ .lea_symbol = try genNavRef(lf, pt, nav) }, - .load_uav => |uav| .{ .load_symbol = try lf.lowerUav( + .lea_nav => |nav| .{ .lea_symbol = try lf.navSymbol(nav) }, + .load_uav => |uav| .{ .load_symbol = try lf.uavSymbol( pt, uav.val, Type.fromInterned(uav.orig_ty).ptrAlignment(pt.zcu), ) }, - .lea_uav => |uav| .{ .lea_symbol = try lf.lowerUav( + .lea_uav => |uav| .{ .lea_symbol = try lf.uavSymbol( pt, uav.val, Type.fromInterned(uav.orig_ty).ptrAlignment(pt.zcu), diff --git a/src/codegen/aarch64/Mir.zig b/src/codegen/aarch64/Mir.zig index ad40e86902d4273b2b558fa1b1b97add12b29345..1233a8180db0e726d2d2904eb2246734ad18ab56 100644 --- a/src/codegen/aarch64/Mir.zig +++ b/src/codegen/aarch64/Mir.zig @@ -93,11 +93,7 @@ pub fn emit( lf, zcu, atom_index, - try @import("../../codegen.zig").genNavRef( - lf, - pt, - nav_reloc.nav, - ), + try lf.navSymbol(nav_reloc.nav), mir.body[nav_reloc.reloc.label], body_end - Instruction.size * (1 + nav_reloc.reloc.label), nav_reloc.reloc.addend, @@ -107,7 +103,7 @@ pub fn emit( lf, zcu, atom_index, - try lf.lowerUav( + try lf.uavSymbol( pt, uav_reloc.uav.val, ZigType.fromInterned(uav_reloc.uav.orig_ty).ptrAlignment(zcu), diff --git a/src/codegen/loongarch/Mir.zig b/src/codegen/loongarch/Mir.zig index f81843ff4e24ce3c395cd250844e1bed9bb368cb..e107984767b547ccb82c9ac1ab869c4ee4d02e24 100644 --- a/src/codegen/loongarch/Mir.zig +++ b/src/codegen/loongarch/Mir.zig @@ -83,11 +83,7 @@ pub fn emit( lf, zcu, atom_index, - try @import("../../codegen.zig").genNavRef( - lf, - pt, - nav_reloc.nav, - ), + try lf.navSymbol(nav_reloc.nav), nav_reloc.reloc.type, body_end - @sizeOf(Instruction) * (1 + nav_reloc.reloc.label), nav_reloc.reloc.addend, @@ -97,7 +93,7 @@ pub fn emit( lf, zcu, atom_index, - try lf.lowerUav( + try lf.uavSymbol( pt, uav_reloc.uav.val, ZigType.fromInterned(uav_reloc.uav.orig_ty).ptrAlignment(zcu), @@ -142,16 +138,11 @@ pub fn emit( ) catch |err| return zcu.codegenFail(func.owner_nav, "emit reloc failed: {t}", .{err}); - const func_nav = try @import("../../codegen.zig").genNavRef( - lf, - pt, - func.owner_nav, - ); for (mir.internal_relocs) |internal_reloc| emitReloc( lf, zcu, atom_index, - func_nav, + try lf.navSymbol(func.owner_nav), internal_reloc.reloc.type, body_end - @sizeOf(Instruction) * (1 + internal_reloc.reloc.label), @sizeOf(Instruction) * (@as(i64, @intCast(mir.prologue.len + mir.body.len - internal_reloc.target))), diff --git a/src/codegen/riscv64/CodeGen.zig b/src/codegen/riscv64/CodeGen.zig index 1db4dde0627e2ee00b6f65f9c48db0b53b29f8c2..aeb1dde892769fe1270542079b778ed6487d0cdf 100644 --- a/src/codegen/riscv64/CodeGen.zig +++ b/src/codegen/riscv64/CodeGen.zig @@ -8160,7 +8160,7 @@ fn genTypedValue(func: *Func, val: Value) InnerError!MCValue { const lf = func.bin_file; const result: codegen.MCValue = if (val.isUndef(pt.zcu)) - .{ .load_symbol = try lf.lowerUav(pt, val.toIntern(), .none) } + .{ .load_symbol = try lf.uavSymbol(pt, val.toIntern(), .none) } else try codegen.genTypedValue(lf, pt, val, func.target); const mcv: MCValue = switch (result) { diff --git a/src/codegen/x86_64/Emit.zig b/src/codegen/x86_64/Emit.zig index 6dcaf2173d2f1fb36cf8940a0146881de02cfb93..a82ae415ac502309854af8e9ca44636ee3c8ab43 100644 --- a/src/codegen/x86_64/Emit.zig +++ b/src/codegen/x86_64/Emit.zig @@ -100,11 +100,7 @@ pub fn emitMir(emit: *Emit) Error!void { .inst => |inst| .{ .inst = inst }, .table => .table, .nav => |nav| { - const symbol_id = try codegen.genNavRef( - emit.bin_file, - emit.pt, - nav, - ); + const symbol_id = try emit.bin_file.navSymbol(nav); const target_symbol: RelocInfo.Target.Symbol = if (ip.getNav(nav).getExtern(ip)) |@"extern"| .{ .symbol = symbol_id, .is_extern = switch (@"extern".visibility) { @@ -124,7 +120,7 @@ pub fn emitMir(emit: *Emit) Error!void { } }, .uav => |uav| .{ .symbol = .{ - .symbol = try emit.bin_file.lowerUav( + .symbol = try emit.bin_file.uavSymbol( emit.pt, uav.val, Type.fromInterned(uav.orig_ty).ptrAlignment(emit.pt.zcu), @@ -597,12 +593,12 @@ pub fn emitMir(emit: *Emit) Error!void { .nav => |nav| @unionInit( DwarfLoc, addr_loc, - try codegen.genNavRef(emit.bin_file, emit.pt, nav), + try emit.bin_file.navSymbol(nav), ), .uav => |uav| @unionInit( DwarfLoc, addr_loc, - try emit.bin_file.lowerUav( + try emit.bin_file.uavSymbol( emit.pt, uav.val, Type.fromInterned(uav.orig_ty) diff --git a/src/link.zig b/src/link.zig index 0e2d6e2ff5c54184fb473a25dee0a2488e3e746f..c72a65a888eb4489153569c6971c9eec6d63f217 100644 --- a/src/link.zig +++ b/src/link.zig @@ -1039,6 +1039,7 @@ pub const File = struct { pub const RelocInfo = struct { parent: Parent, offset: u64, + target: SymbolId, addend: u32, pub const Parent = union(enum) { @@ -1048,16 +1049,9 @@ pub const File = struct { }; }; - /// Get allocated `Nav`'s address in virtual memory. - /// The linker is passed information about the containing atom, `parent_atom_index`, and offset within it's - /// memory buffer, `offset`, so that it can make a note of potential relocation sites, should the - /// `Nav`'s address was not yet resolved, or the containing atom gets moved in virtual memory. - /// May be called before or after updateFunc/updateNav therefore it is up to the linker to allocate - /// the block/atom. /// Never called when LLVM is codegenning the ZCU. - pub fn getNavVAddr(base: *File, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index, reloc_info: RelocInfo) Error!u64 { - assert(pt.zcu.llvm_object == null); - + pub fn relocSymAddr(base: *File, reloc_info: RelocInfo) Error!void { + assert(base.comp.zcu.?.llvm_object == null); switch (base.tag) { .lld => unreachable, .c => unreachable, @@ -1067,20 +1061,19 @@ pub const File = struct { .spork8 => unreachable, inline else => |tag| { dev.check(tag.devFeature()); - return @as(*tag.Type(), @fieldParentPtr("base", base)).getNavVAddr(pt, nav_index, reloc_info); + return @as(*tag.Type(), @fieldParentPtr("base", base)).relocSymAddr(reloc_info); }, } } /// Never called when LLVM is codegenning the ZCU. - pub fn lowerUav( + pub fn uavSymbol( base: *File, pt: Zcu.PerThread, - decl_val: InternPool.Index, - decl_align: InternPool.Alignment, + uav_val: InternPool.Index, + uav_align: InternPool.Alignment, ) Error!SymbolId { assert(pt.zcu.llvm_object == null); - switch (base.tag) { .lld => unreachable, .c => unreachable, @@ -1090,15 +1083,14 @@ pub const File = struct { .spork8 => unreachable, inline else => |tag| { dev.check(tag.devFeature()); - return @as(*tag.Type(), @fieldParentPtr("base", base)).lowerUav(pt, decl_val, decl_align); + return @as(*tag.Type(), @fieldParentPtr("base", base)).uavSymbol(pt, uav_val, uav_align); }, } } /// Never called when LLVM is codegenning the ZCU. - pub fn getUavVAddr(base: *File, decl_val: InternPool.Index, reloc_info: RelocInfo) Error!u64 { + pub fn navSymbol(base: *File, nav: InternPool.Nav.Index) Error!SymbolId { assert(base.comp.zcu.?.llvm_object == null); - switch (base.tag) { .lld => unreachable, .c => unreachable, @@ -1108,7 +1100,7 @@ pub const File = struct { .spork8 => unreachable, inline else => |tag| { dev.check(tag.devFeature()); - return @as(*tag.Type(), @fieldParentPtr("base", base)).getUavVAddr(decl_val, reloc_info); + return @as(*tag.Type(), @fieldParentPtr("base", base)).navSymbol(nav); }, } } diff --git a/src/link/Coff.zig b/src/link/Coff.zig index 1aa577aa45026387561fc81794ce7e43f42b71be..dbdea4966de0b5ba91b7e2b026a7b80c419d5854 100644 --- a/src/link/Coff.zig +++ b/src/link/Coff.zig @@ -2935,18 +2935,19 @@ fn navMapIndex(coff: *Coff, zcu: *Zcu, nav_index: InternPool.Nav.Index) !Node.Na if (!sym_gop.found_existing) sym_gop.value_ptr.* = coff.addSymbolAssumeCapacity(); return @fromBackingInt(@intCast(sym_gop.index)); } -pub fn navSymbol(coff: *Coff, zcu: *Zcu, nav_index: InternPool.Nav.Index) !Symbol.Index { +pub fn navSymbol(coff: *Coff, nav_index: InternPool.Nav.Index) link.Error!link.File.SymbolId { + const zcu = coff.base.comp.zcu.?; const ip = &zcu.intern_pool; const nav = ip.getNav(nav_index); - if (nav.getExtern(ip)) |@"extern"| return coff.globalSymbol(.{ + if (nav.getExtern(ip)) |@"extern"| return @bitCast(try coff.globalSymbol(.{ .name = @"extern".name.toSlice(ip), .lib_name = @"extern".lib_name.toSlice(ip), // TODO: Threadlocal as well? .type = if (ip.isFunctionType(nav.resolved.?.type)) .code else .data, .dll_storage_class = if (@"extern".is_dll_import) .dllimport else .default, - }); + })); const nmi = try coff.navMapIndex(zcu, nav_index); - return nmi.symbol(coff); + return @bitCast(nmi.symbol(coff)); } fn uavMapIndex(coff: *Coff, uav_val: InternPool.Index) !Node.UavMapIndex { @@ -2956,10 +2957,6 @@ fn uavMapIndex(coff: *Coff, uav_val: InternPool.Index) !Node.UavMapIndex { if (!sym_gop.found_existing) sym_gop.value_ptr.* = coff.addSymbolAssumeCapacity(); return @fromBackingInt(@intCast(sym_gop.index)); } -pub fn uavSymbol(coff: *Coff, uav_val: InternPool.Index) !Symbol.Index { - const umi = try coff.uavMapIndex(uav_val); - return umi.symbol(coff); -} pub fn lazySymbol(coff: *Coff, lazy: link.File.LazySymbol) !Symbol.Index { const gpa = coff.base.comp.gpa; @@ -2972,24 +2969,8 @@ pub fn lazySymbol(coff: *Coff, lazy: link.File.LazySymbol) !Symbol.Index { return sym_gop.value_ptr.*; } -pub fn getNavVAddr( - coff: *Coff, - pt: Zcu.PerThread, - nav: InternPool.Nav.Index, - reloc_info: link.File.RelocInfo, -) link.Error!u64 { - return coff.getVAddr(reloc_info, try coff.navSymbol(pt.zcu, nav)); -} - -pub fn getUavVAddr( - coff: *Coff, - uav: InternPool.Index, - reloc_info: link.File.RelocInfo, -) link.Error!u64 { - return coff.getVAddr(reloc_info, try coff.uavSymbol(uav)); -} - -pub fn getVAddr(coff: *Coff, reloc_info: link.File.RelocInfo, target_si: Symbol.Index) link.Error!u64 { +pub fn relocSymAddr(coff: *Coff, reloc_info: link.File.RelocInfo) link.Error!void { + const target_si: Symbol.Index = @bitCast(reloc_info.target); try coff.addReloc( @fromBackingInt(@intCast(@backingInt(reloc_info.parent.atom_index))), reloc_info.offset, @@ -3001,10 +2982,6 @@ pub fn getVAddr(coff: *Coff, reloc_info: link.File.RelocInfo, target_si: Symbol. .I386 => .{ .I386 = .DIR32 }, }, ); - - var vaddr: u64 = target_si.get(coff).rva; - if (coff.isImage()) vaddr += coff.optionalHeaderField(.image_base); - return vaddr; } /// Caller guarantees there is capacity for one member and two nodes @@ -5580,13 +5557,15 @@ pub fn updateContainerType( }; } -pub fn lowerUav( +pub fn uavSymbol( coff: *Coff, pt: Zcu.PerThread, uav_val: InternPool.Index, uav_align: InternPool.Alignment, ) link.Error!link.File.SymbolId { - const zcu = pt.zcu; + _ = pt; + + const zcu = coff.base.comp.zcu.?; const gpa = zcu.gpa; try coff.pending_uavs.ensureUnusedCapacity(gpa, 1); @@ -7471,8 +7450,8 @@ fn updateExportInner( try coff.symbols.ensureUnusedCapacity(gpa, 1); const exported_si: Symbol.Index = switch (exp.exported) { - .nav => |nav| try coff.navSymbol(zcu, nav), - .uav => |uav| @fromBackingInt(@intCast(@backingInt(try coff.lowerUav( + .nav => |nav| @bitCast(try coff.navSymbol(nav)), + .uav => |uav| @fromBackingInt(@intCast(@backingInt(try coff.uavSymbol( pt, uav, Type.fromInterned(ip.typeOf(uav)).abiAlignment(zcu), diff --git a/src/link/Elf.zig b/src/link/Elf.zig index b0e188390f24c3000d382aae4b76646fd6306644..3cbcc53361033b74e8ea1c69189f6909d3be7ad6 100644 --- a/src/link/Elf.zig +++ b/src/link/Elf.zig @@ -463,21 +463,21 @@ pub fn deinit(self: *Elf) void { self.dump_argv_list.deinit(gpa); } -pub fn getNavVAddr(self: *Elf, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index, reloc_info: link.File.RelocInfo) !u64 { - return self.zigObjectPtr().?.getNavVAddr(self, pt, nav_index, reloc_info); +pub fn navSymbol(self: *Elf, nav: InternPool.Nav.Index) link.Error!link.File.SymbolId { + return self.zigObjectPtr().?.navSymbol(self, nav); } -pub fn lowerUav( +pub fn relocSymAddr(self: *Elf, reloc_info: link.File.RelocInfo) !void { + return self.zigObjectPtr().?.relocSymAddr(self, reloc_info); +} + +pub fn uavSymbol( self: *Elf, pt: Zcu.PerThread, uav: InternPool.Index, explicit_alignment: InternPool.Alignment, ) !link.File.SymbolId { - return self.zigObjectPtr().?.lowerUav(self, pt, uav, explicit_alignment); -} - -pub fn getUavVAddr(self: *Elf, uav: InternPool.Index, reloc_info: link.File.RelocInfo) !u64 { - return self.zigObjectPtr().?.getUavVAddr(self, uav, reloc_info); + return self.zigObjectPtr().?.uavSymbol(self, pt, uav, explicit_alignment); } /// Returns end pos of collision, if any. diff --git a/src/link/Elf/ZigObject.zig b/src/link/Elf/ZigObject.zig index 98ca8b9f25792bd25f091735689ec6e6fecaf916..69fc2f1ae2efdf9fbb5035ce9f81137d63a1e869 100644 --- a/src/link/Elf/ZigObject.zig +++ b/src/link/Elf/ZigObject.zig @@ -917,24 +917,42 @@ pub fn codeAlloc(self: *ZigObject, elf_file: *Elf, atom_index: Atom.Index) ![]u8 return code; } -pub fn getNavVAddr( - self: *ZigObject, +pub fn navSymbol( + zo: *ZigObject, elf_file: *Elf, - pt: Zcu.PerThread, nav_index: InternPool.Nav.Index, - reloc_info: link.File.RelocInfo, -) !u64 { - const zcu = pt.zcu; +) link.Error!link.File.SymbolId { + const zcu = elf_file.base.comp.zcu.?; const ip = &zcu.intern_pool; const nav = ip.getNav(nav_index); - log.debug("getNavVAddr {f}({d})", .{ nav.fqn.fmt(ip), nav_index }); - const this_sym_index = if (nav.getExtern(ip)) |@"extern"| try self.getGlobalSymbol( - elf_file, - nav.name.toSlice(ip), - @"extern".lib_name.toSlice(ip), - ) else try self.getOrCreateMetadataForNav(zcu, nav_index); - const this_sym = self.symbol(this_sym_index); - const vaddr = this_sym.address(.{}, elf_file); + if (nav.getExtern(ip)) |@"extern"| { + const sym_index = try zo.getGlobalSymbol( + elf_file, + nav.name.toSlice(ip), + @"extern".lib_name.toSlice(ip), + ); + if (@"extern".linkage == .weak) { + zo.symbol(sym_index).flags.weak = true; + } + if (nav.resolved.?.@"threadlocal") { + zo.symbol(sym_index).flags.is_tls = true; + } + return @fromBackingInt(sym_index); + } else { + const sym_index = try zo.getOrCreateMetadataForNav(zcu, nav_index); + if (nav.resolved.?.@"threadlocal") { + zo.symbol(sym_index).flags.is_tls = true; + } + return @fromBackingInt(sym_index); + } +} + +pub fn relocSymAddr( + self: *ZigObject, + elf_file: *Elf, + reloc_info: link.File.RelocInfo, +) !void { + const this_sym_index = @backingInt(reloc_info.target); switch (reloc_info.parent) { .none => unreachable, .atom_index => |atom_index| { @@ -952,39 +970,9 @@ pub fn getNavVAddr( .target_off = reloc_info.addend, }), } - return @intCast(vaddr); } -pub fn getUavVAddr( - self: *ZigObject, - elf_file: *Elf, - uav: InternPool.Index, - reloc_info: link.File.RelocInfo, -) !u64 { - const sym_index = self.uavs.get(uav).?.symbol_index; - const sym = self.symbol(sym_index); - const vaddr = sym.address(.{}, elf_file); - switch (reloc_info.parent) { - .none => unreachable, - .atom_index => |atom_index| { - const parent_atom = self.symbol(@backingInt(atom_index)).atom(elf_file).?; - const r_type = relocation.encode(.abs, elf_file.getTarget().cpu.arch); - try parent_atom.addReloc(elf_file.base.comp.gpa, .{ - .r_offset = reloc_info.offset, - .r_info = (@as(u64, @intCast(sym_index)) << 32) | r_type, - .r_addend = reloc_info.addend, - }, self); - }, - .debug_output => |debug_output| try debug_output.dwarf.infoExternalReloc(.{ - .source_off = @intCast(reloc_info.offset), - .target_sym = @fromBackingInt(@intCast(sym_index)), - .target_off = reloc_info.addend, - }), - } - return @intCast(vaddr); -} - -pub fn lowerUav( +pub fn uavSymbol( self: *ZigObject, elf_file: *Elf, pt: Zcu.PerThread, @@ -1889,7 +1877,7 @@ pub fn updateExports( break :blk self.navs.getPtr(nav).?; }, .uav => |uav| self.uavs.getPtr(uav) orelse blk: { - _ = try self.lowerUav(elf_file, pt, uav, .none); + _ = try self.uavSymbol(elf_file, pt, uav, .none); break :blk self.uavs.getPtr(uav).?; }, }; diff --git a/src/link/Elf2.zig b/src/link/Elf2.zig index fdb5b0704402317e54207b754629ba8d408d7708..e47107140d51ffbbe200b64c1fda1e3f62bde6cb 100644 --- a/src/link/Elf2.zig +++ b/src/link/Elf2.zig @@ -4326,36 +4326,7 @@ pub fn navSymbol(elf: *Elf, nav_index: InternPool.Nav.Index) link.Error!link.Fil const s: Symbol.Id = .local(nmi.symbol(elf)); return s.toTypeErased(); } -pub fn uavSymbol( - elf: *Elf, - uav_val: InternPool.Index, - uav_align: InternPool.Alignment, -) link.Error!link.File.SymbolId { - const diags = &elf.base.comp.link_diags; - const umi = elf.uavMapIndex(uav_val, uav_align) catch |err| switch (err) { - else => |e| return e, - error.MappedFileIo => return diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}), - }; - const s: Symbol.Id = .local(umi.symbol(elf)); - return s.toTypeErased(); -} -pub fn getNavVAddr( - elf: *Elf, - pt: Zcu.PerThread, - nav: InternPool.Nav.Index, - reloc_info: link.File.RelocInfo, -) link.Error!u64 { - _ = pt; - return elf.getVAddr(reloc_info, try elf.navSymbol(nav)); -} -pub fn getUavVAddr( - elf: *Elf, - uav_val: InternPool.Index, - reloc_info: link.File.RelocInfo, -) link.Error!u64 { - return elf.getVAddr(reloc_info, try elf.uavSymbol(uav_val, .none)); -} -pub fn getVAddr(elf: *Elf, reloc_info: link.File.RelocInfo, target: link.File.SymbolId) link.Error!u64 { +pub fn relocSymAddr(elf: *Elf, reloc_info: link.File.RelocInfo) link.Error!void { try elf.addReloc( switch (reloc_info.parent) { .none => unreachable, @@ -4363,13 +4334,12 @@ pub fn getVAddr(elf: *Elf, reloc_info: link.File.RelocInfo, target: link.File.Sy .debug_output => |debug_output| Node.toAtom(debug_output.dwarf2.info_writer.ni), }, reloc_info.offset, - target, + reloc_info.target, reloc_info.addend, .absAddr(elf), ); - return Symbol.Id.fromTypeErased(target).value(elf); } -pub fn lowerUav( +pub fn uavSymbol( elf: *Elf, pt: Zcu.PerThread, uav_val: InternPool.Index, diff --git a/src/link/MachO.zig b/src/link/MachO.zig index d321d45939cd883d40a3dadd32462071b442fe67..dbabc88a512ff37af5fd0caa9ece4562b8e06378 100644 --- a/src/link/MachO.zig +++ b/src/link/MachO.zig @@ -3124,21 +3124,21 @@ pub fn freeNav(self: *MachO, nav: InternPool.Nav.Index) void { return self.getZigObject().?.freeNav(nav); } -pub fn getNavVAddr(self: *MachO, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index, reloc_info: link.File.RelocInfo) !u64 { - return self.getZigObject().?.getNavVAddr(self, pt, nav_index, reloc_info); +pub fn navSymbol(self: *MachO, nav: InternPool.Nav.Index) link.Error!link.File.SymbolId { + return self.getZigObject().?.navSymbol(self, nav); } -pub fn lowerUav( +pub fn relocSymAddr(self: *MachO, reloc_info: link.File.RelocInfo) link.Error!void { + return self.getZigObject().?.relocSymAddr(self, reloc_info); +} + +pub fn uavSymbol( self: *MachO, pt: Zcu.PerThread, uav: InternPool.Index, explicit_alignment: InternPool.Alignment, ) !link.File.SymbolId { - return self.getZigObject().?.lowerUav(self, pt, uav, explicit_alignment); -} - -pub fn getUavVAddr(self: *MachO, uav: InternPool.Index, reloc_info: link.File.RelocInfo) !u64 { - return self.getZigObject().?.getUavVAddr(self, uav, reloc_info); + return self.getZigObject().?.uavSymbol(self, pt, uav, explicit_alignment); } pub fn getGlobalSymbol(self: *MachO, name: []const u8, lib_name: ?[]const u8) !u32 { diff --git a/src/link/MachO/ZigObject.zig b/src/link/MachO/ZigObject.zig index 93a76ca63a92db3d6528b70f827ddc93a1c89022..624b8b967d05e9165d54c6144f453a8d0970ebb8 100644 --- a/src/link/MachO/ZigObject.zig +++ b/src/link/MachO/ZigObject.zig @@ -611,60 +611,43 @@ pub fn flush(self: *ZigObject, macho_file: *MachO, tid: Zcu.PerThread.Id) link.E assert(!self.debug_strtab_dirty); } -pub fn getNavVAddr( - self: *ZigObject, +pub fn navSymbol( + zo: *ZigObject, macho_file: *MachO, - pt: Zcu.PerThread, nav_index: InternPool.Nav.Index, - reloc_info: link.File.RelocInfo, -) !u64 { - const zcu = pt.zcu; +) link.Error!link.File.SymbolId { + const zcu = macho_file.base.comp.zcu.?; const ip = &zcu.intern_pool; const nav = ip.getNav(nav_index); - log.debug("getNavVAddr {f}({d})", .{ nav.fqn.fmt(ip), nav_index }); - const sym_index = if (nav.getExtern(ip)) |@"extern"| try self.getGlobalSymbol( - macho_file, - nav.name.toSlice(ip), - @"extern".lib_name.toSlice(ip), - ) else try self.getOrCreateMetadataForNav(macho_file, nav_index); - const sym = self.symbols.items[sym_index]; - const vaddr = sym.getAddress(.{}, macho_file); - switch (reloc_info.parent) { - .none => unreachable, - .atom_index => |atom_index| { - const parent_atom = self.symbols.items[@backingInt(atom_index)].getAtom(macho_file).?; - try parent_atom.addReloc(macho_file, .{ - .tag = .@"extern", - .offset = @intCast(reloc_info.offset), - .target = sym_index, - .addend = reloc_info.addend, - .type = .unsigned, - .meta = .{ - .pcrel = false, - .has_subtractor = false, - .length = 3, - .symbolnum = @intCast(sym.nlist_idx), - }, - }); - }, - .debug_output => |debug_output| try debug_output.dwarf.infoExternalReloc(.{ - .source_off = @intCast(reloc_info.offset), - .target_sym = @fromBackingInt(@intCast(sym_index)), - .target_off = reloc_info.addend, - }), + if (nav.getExtern(ip)) |@"extern"| { + const sym_index = try zo.getGlobalSymbol( + macho_file, + nav.name.toSlice(ip), + @"extern".lib_name.toSlice(ip), + ); + if (@"extern".linkage == .weak) { + zo.symbols.items[sym_index].flags.weak = true; + } + if (nav.resolved.?.@"threadlocal") { + zo.symbols.items[sym_index].flags.tlv = true; + } + return @fromBackingInt(sym_index); + } else { + const sym_index = try zo.getOrCreateMetadataForNav(macho_file, nav_index); + if (nav.resolved.?.@"threadlocal") { + zo.symbols.items[sym_index].flags.tlv = true; + } + return @fromBackingInt(sym_index); } - return vaddr; } -pub fn getUavVAddr( +pub fn relocSymAddr( self: *ZigObject, macho_file: *MachO, - uav: InternPool.Index, reloc_info: link.File.RelocInfo, -) !u64 { - const sym_index = self.uavs.get(uav).?.symbol_index; +) !void { + const sym_index = @backingInt(reloc_info.target); const sym = self.symbols.items[sym_index]; - const vaddr = sym.getAddress(.{}, macho_file); switch (reloc_info.parent) { .none => unreachable, .atom_index => |atom_index| { @@ -689,10 +672,9 @@ pub fn getUavVAddr( .target_off = reloc_info.addend, }), } - return vaddr; } -pub fn lowerUav( +pub fn uavSymbol( self: *ZigObject, macho_file: *MachO, pt: Zcu.PerThread, @@ -1281,7 +1263,7 @@ pub fn updateExports( break :blk self.navs.getPtr(nav).?; }, .uav => |uav| self.uavs.getPtr(uav) orelse blk: { - _ = try self.lowerUav(macho_file, pt, uav, .none); + _ = try self.uavSymbol(macho_file, pt, uav, .none); break :blk self.uavs.getPtr(uav).?; }, };