| author | |
| committer | |
| log | 02b67d7e19455cfc069daf9e665fe28d4d01a9f2 |
| tree | d1aef670795636e89a52a22eb0d2fa0bc2dfb808 |
| parent | e4d1bd610534c9a6ed01a17481bc4b6dc5b7d8dc |
| signature | Commit is signed but in an unrecognized format. |
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(+), 290 deletions(-)
src/codegen.zig+12-74| ... | ... | @@ -754,23 +754,15 @@ fn lowerUavRef( |
| 754 | 754 | } |
| 755 | 755 | |
| 756 | 756 | const uav_align = Type.fromInterned(uav.orig_ty).ptrAlignment(zcu); |
| 757 | _ = try lf.lowerUav(pt, uav_val, uav_align); | |
| 758 | 757 | |
| 759 | const vaddr = lf.getUavVAddr(uav_val, .{ | |
| 758 | try lf.relocSymAddr(.{ | |
| 760 | 759 | .parent = reloc_parent, |
| 761 | 760 | .offset = w.end, |
| 761 | .target = try lf.uavSymbol(pt, uav_val, uav_align), | |
| 762 | 762 | .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 | |
| 774 | 766 | } |
| 775 | 767 | |
| 776 | 768 | fn lowerNavRef( |
| ... | ... | @@ -805,68 +797,14 @@ fn lowerNavRef( |
| 805 | 797 | else => {}, |
| 806 | 798 | } |
| 807 | 799 | |
| 808 | const vaddr = lf.getNavVAddr(pt, nav_index, .{ | |
| 800 | try lf.relocSymAddr(.{ | |
| 809 | 801 | .parent = reloc_parent, |
| 810 | 802 | .offset = w.end, |
| 803 | .target = try lf.navSymbol(nav_index), | |
| 811 | 804 | .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 | } | |
| 805 | }); | |
| 821 | 806 | |
| 822 | pub 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)}); | |
| 831 | ||
| 832 | const is_threadlocal = nav.resolved.?.@"threadlocal" and zcu.comp.config.any_non_single_threaded; | |
| 833 | if (lf.cast(.elf)) |elf_file| { | |
| 834 | const zo = elf_file.zigObjectPtr().?; | |
| 835 | if (nav.getExtern(ip)) |e| { | |
| 836 | const sym_index = try elf_file.getGlobalSymbol(nav.name.toSlice(ip), e.lib_name.toSlice(ip)); | |
| 837 | switch (e.linkage) { | |
| 838 | .strong => {}, | |
| 839 | .weak => zo.symbol(sym_index).flags.weak = true, | |
| 840 | } | |
| 841 | if (is_threadlocal) zo.symbol(sym_index).flags.is_tls = true; | |
| 842 | return @fromBackingInt(@intCast(sym_index)); | |
| 843 | } else { | |
| 844 | const sym_index = try zo.getOrCreateMetadataForNav(zcu, nav_index); | |
| 845 | if (is_threadlocal) zo.symbol(sym_index).flags.is_tls = true; | |
| 846 | return @fromBackingInt(@intCast(sym_index)); | |
| 847 | } | |
| 848 | } else if (lf.cast(.elf2)) |elf| { | |
| 849 | return elf.navSymbol(nav_index); | |
| 850 | } else if (lf.cast(.macho)) |macho_file| { | |
| 851 | const zo = macho_file.getZigObject().?; | |
| 852 | if (nav.getExtern(ip)) |e| { | |
| 853 | const sym_index = try macho_file.getGlobalSymbol(nav.name.toSlice(ip), e.lib_name.toSlice(ip)); | |
| 854 | switch (e.linkage) { | |
| 855 | .strong => {}, | |
| 856 | .weak => zo.symbols.items[sym_index].flags.weak = true, | |
| 857 | } | |
| 858 | if (is_threadlocal) zo.symbols.items[sym_index].flags.tlv = true; | |
| 859 | return @fromBackingInt(@intCast(sym_index)); | |
| 860 | } else { | |
| 861 | const sym_index = try zo.getOrCreateMetadataForNav(macho_file, nav_index); | |
| 862 | if (is_threadlocal) zo.symbols.items[sym_index].flags.tlv = true; | |
| 863 | return @fromBackingInt(@intCast(sym_index)); | |
| 864 | } | |
| 865 | } else if (lf.cast(.coff)) |coff| { | |
| 866 | return @fromBackingInt(@intCast(@backingInt(try coff.navSymbol(zcu, nav_index)))); | |
| 867 | } else { | |
| 868 | std.debug.panic("TODO genNavRef for '{t}'", .{lf.tag}); | |
| 869 | } | |
| 807 | try w.splatByteAll(0, ptr_width_bytes); // overwritten by relocation | |
| 870 | 808 | } |
| 871 | 809 | |
| 872 | 810 | /// deprecated legacy type |
| ... | ... | @@ -908,13 +846,13 @@ pub fn genTypedValue( |
| 908 | 846 | .none => .none, |
| 909 | 847 | .undef => .undef, |
| 910 | 848 | .immediate => |imm| .{ .immediate = imm }, |
| 911 | .lea_nav => |nav| .{ .lea_symbol = try genNavRef(lf, pt, nav) }, | |
| 912 | .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( | |
| 913 | 851 | pt, |
| 914 | 852 | uav.val, |
| 915 | 853 | Type.fromInterned(uav.orig_ty).ptrAlignment(pt.zcu), |
| 916 | 854 | ) }, |
| 917 | .lea_uav => |uav| .{ .lea_symbol = try lf.lowerUav( | |
| 855 | .lea_uav => |uav| .{ .lea_symbol = try lf.uavSymbol( | |
| 918 | 856 | pt, |
| 919 | 857 | uav.val, |
| 920 | 858 | Type.fromInterned(uav.orig_ty).ptrAlignment(pt.zcu), |
src/codegen/aarch64/Mir.zig+2-6| ... | ... | @@ -93,11 +93,7 @@ pub fn emit( |
| 93 | 93 | lf, |
| 94 | 94 | zcu, |
| 95 | 95 | atom_index, |
| 96 | try @import("../../codegen.zig").genNavRef( | |
| 97 | lf, | |
| 98 | pt, | |
| 99 | nav_reloc.nav, | |
| 100 | ), | |
| 96 | try lf.navSymbol(nav_reloc.nav), | |
| 101 | 97 | mir.body[nav_reloc.reloc.label], |
| 102 | 98 | body_end - Instruction.size * (1 + nav_reloc.reloc.label), |
| 103 | 99 | nav_reloc.reloc.addend, |
| ... | ... | @@ -107,7 +103,7 @@ pub fn emit( |
| 107 | 103 | lf, |
| 108 | 104 | zcu, |
| 109 | 105 | atom_index, |
| 110 | try lf.lowerUav( | |
| 106 | try lf.uavSymbol( | |
| 111 | 107 | pt, |
| 112 | 108 | uav_reloc.uav.val, |
| 113 | 109 | ZigType.fromInterned(uav_reloc.uav.orig_ty).ptrAlignment(zcu), |
src/codegen/loongarch/Mir.zig+3-12| ... | ... | @@ -83,11 +83,7 @@ pub fn emit( |
| 83 | 83 | lf, |
| 84 | 84 | zcu, |
| 85 | 85 | atom_index, |
| 86 | try @import("../../codegen.zig").genNavRef( | |
| 87 | lf, | |
| 88 | pt, | |
| 89 | nav_reloc.nav, | |
| 90 | ), | |
| 86 | try lf.navSymbol(nav_reloc.nav), | |
| 91 | 87 | nav_reloc.reloc.type, |
| 92 | 88 | body_end - @sizeOf(Instruction) * (1 + nav_reloc.reloc.label), |
| 93 | 89 | nav_reloc.reloc.addend, |
| ... | ... | @@ -97,7 +93,7 @@ pub fn emit( |
| 97 | 93 | lf, |
| 98 | 94 | zcu, |
| 99 | 95 | atom_index, |
| 100 | try lf.lowerUav( | |
| 96 | try lf.uavSymbol( | |
| 101 | 97 | pt, |
| 102 | 98 | uav_reloc.uav.val, |
| 103 | 99 | ZigType.fromInterned(uav_reloc.uav.orig_ty).ptrAlignment(zcu), |
| ... | ... | @@ -142,16 +138,11 @@ pub fn emit( |
| 142 | 138 | ) catch |err| |
| 143 | 139 | return zcu.codegenFail(func.owner_nav, "emit reloc failed: {t}", .{err}); |
| 144 | 140 | |
| 145 | const func_nav = try @import("../../codegen.zig").genNavRef( | |
| 146 | lf, | |
| 147 | pt, | |
| 148 | func.owner_nav, | |
| 149 | ); | |
| 150 | 141 | for (mir.internal_relocs) |internal_reloc| emitReloc( |
| 151 | 142 | lf, |
| 152 | 143 | zcu, |
| 153 | 144 | atom_index, |
| 154 | func_nav, | |
| 145 | try lf.navSymbol(func.owner_nav), | |
| 155 | 146 | internal_reloc.reloc.type, |
| 156 | 147 | body_end - @sizeOf(Instruction) * (1 + internal_reloc.reloc.label), |
| 157 | 148 | @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 { |
| 8160 | 8160 | const lf = func.bin_file; |
| 8161 | 8161 | |
| 8162 | 8162 | 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) } | |
| 8164 | 8164 | else |
| 8165 | 8165 | try codegen.genTypedValue(lf, pt, val, func.target); |
| 8166 | 8166 | const mcv: MCValue = switch (result) { |
src/codegen/x86_64/Emit.zig+4-8| ... | ... | @@ -100,11 +100,7 @@ pub fn emitMir(emit: *Emit) Error!void { |
| 100 | 100 | .inst => |inst| .{ .inst = inst }, |
| 101 | 101 | .table => .table, |
| 102 | 102 | .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); | |
| 108 | 104 | const target_symbol: RelocInfo.Target.Symbol = if (ip.getNav(nav).getExtern(ip)) |@"extern"| .{ |
| 109 | 105 | .symbol = symbol_id, |
| 110 | 106 | .is_extern = switch (@"extern".visibility) { |
| ... | ... | @@ -124,7 +120,7 @@ pub fn emitMir(emit: *Emit) Error!void { |
| 124 | 120 | } |
| 125 | 121 | }, |
| 126 | 122 | .uav => |uav| .{ .symbol = .{ |
| 127 | .symbol = try emit.bin_file.lowerUav( | |
| 123 | .symbol = try emit.bin_file.uavSymbol( | |
| 128 | 124 | emit.pt, |
| 129 | 125 | uav.val, |
| 130 | 126 | Type.fromInterned(uav.orig_ty).ptrAlignment(emit.pt.zcu), |
| ... | ... | @@ -597,12 +593,12 @@ pub fn emitMir(emit: *Emit) Error!void { |
| 597 | 593 | .nav => |nav| @unionInit( |
| 598 | 594 | DwarfLoc, |
| 599 | 595 | addr_loc, |
| 600 | try codegen.genNavRef(emit.bin_file, emit.pt, nav), | |
| 596 | try emit.bin_file.navSymbol(nav), | |
| 601 | 597 | ), |
| 602 | 598 | .uav => |uav| @unionInit( |
| 603 | 599 | DwarfLoc, |
| 604 | 600 | addr_loc, |
| 605 | try emit.bin_file.lowerUav( | |
| 601 | try emit.bin_file.uavSymbol( | |
| 606 | 602 | emit.pt, |
| 607 | 603 | uav.val, |
| 608 | 604 | Type.fromInterned(uav.orig_ty) |
src/link.zig+10-18| ... | ... | @@ -1039,6 +1039,7 @@ pub const File = struct { |
| 1039 | 1039 | pub const RelocInfo = struct { |
| 1040 | 1040 | parent: Parent, |
| 1041 | 1041 | offset: u64, |
| 1042 | target: SymbolId, | |
| 1042 | 1043 | addend: u32, |
| 1043 | 1044 | |
| 1044 | 1045 | pub const Parent = union(enum) { |
| ... | ... | @@ -1048,16 +1049,9 @@ pub const File = struct { |
| 1048 | 1049 | }; |
| 1049 | 1050 | }; |
| 1050 | 1051 | |
| 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. | |
| 1057 | 1052 | /// 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); | |
| 1061 | 1055 | switch (base.tag) { |
| 1062 | 1056 | .lld => unreachable, |
| 1063 | 1057 | .c => unreachable, |
| ... | ... | @@ -1067,20 +1061,19 @@ pub const File = struct { |
| 1067 | 1061 | .spork8 => unreachable, |
| 1068 | 1062 | inline else => |tag| { |
| 1069 | 1063 | 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); | |
| 1071 | 1065 | }, |
| 1072 | 1066 | } |
| 1073 | 1067 | } |
| 1074 | 1068 | |
| 1075 | 1069 | /// Never called when LLVM is codegenning the ZCU. |
| 1076 | pub fn lowerUav( | |
| 1070 | pub fn uavSymbol( | |
| 1077 | 1071 | base: *File, |
| 1078 | 1072 | pt: Zcu.PerThread, |
| 1079 | decl_val: InternPool.Index, | |
| 1080 | decl_align: InternPool.Alignment, | |
| 1073 | uav_val: InternPool.Index, | |
| 1074 | uav_align: InternPool.Alignment, | |
| 1081 | 1075 | ) Error!SymbolId { |
| 1082 | 1076 | assert(pt.zcu.llvm_object == null); |
| 1083 | ||
| 1084 | 1077 | switch (base.tag) { |
| 1085 | 1078 | .lld => unreachable, |
| 1086 | 1079 | .c => unreachable, |
| ... | ... | @@ -1090,15 +1083,14 @@ pub const File = struct { |
| 1090 | 1083 | .spork8 => unreachable, |
| 1091 | 1084 | inline else => |tag| { |
| 1092 | 1085 | 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); | |
| 1094 | 1087 | }, |
| 1095 | 1088 | } |
| 1096 | 1089 | } |
| 1097 | 1090 | |
| 1098 | 1091 | /// 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 { | |
| 1100 | 1093 | assert(base.comp.zcu.?.llvm_object == null); |
| 1101 | ||
| 1102 | 1094 | switch (base.tag) { |
| 1103 | 1095 | .lld => unreachable, |
| 1104 | 1096 | .c => unreachable, |
| ... | ... | @@ -1108,7 +1100,7 @@ pub const File = struct { |
| 1108 | 1100 | .spork8 => unreachable, |
| 1109 | 1101 | inline else => |tag| { |
| 1110 | 1102 | 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); | |
| 1112 | 1104 | }, |
| 1113 | 1105 | } |
| 1114 | 1106 | } |
src/link/Coff.zig+13-34| ... | ... | @@ -2935,18 +2935,19 @@ fn navMapIndex(coff: *Coff, zcu: *Zcu, nav_index: InternPool.Nav.Index) !Node.Na |
| 2935 | 2935 | if (!sym_gop.found_existing) sym_gop.value_ptr.* = coff.addSymbolAssumeCapacity(); |
| 2936 | 2936 | return @fromBackingInt(@intCast(sym_gop.index)); |
| 2937 | 2937 | } |
| 2938 | pub fn navSymbol(coff: *Coff, zcu: *Zcu, nav_index: InternPool.Nav.Index) !Symbol.Index { | |
| 2938 | pub fn navSymbol(coff: *Coff, nav_index: InternPool.Nav.Index) link.Error!link.File.SymbolId { | |
| 2939 | const zcu = coff.base.comp.zcu.?; | |
| 2939 | 2940 | const ip = &zcu.intern_pool; |
| 2940 | 2941 | 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(.{ | |
| 2942 | 2943 | .name = @"extern".name.toSlice(ip), |
| 2943 | 2944 | .lib_name = @"extern".lib_name.toSlice(ip), |
| 2944 | 2945 | // TODO: Threadlocal as well? |
| 2945 | 2946 | .type = if (ip.isFunctionType(nav.resolved.?.type)) .code else .data, |
| 2946 | 2947 | .dll_storage_class = if (@"extern".is_dll_import) .dllimport else .default, |
| 2947 | }); | |
| 2948 | })); | |
| 2948 | 2949 | const nmi = try coff.navMapIndex(zcu, nav_index); |
| 2949 | return nmi.symbol(coff); | |
| 2950 | return @bitCast(nmi.symbol(coff)); | |
| 2950 | 2951 | } |
| 2951 | 2952 | |
| 2952 | 2953 | fn uavMapIndex(coff: *Coff, uav_val: InternPool.Index) !Node.UavMapIndex { |
| ... | ... | @@ -2956,10 +2957,6 @@ fn uavMapIndex(coff: *Coff, uav_val: InternPool.Index) !Node.UavMapIndex { |
| 2956 | 2957 | if (!sym_gop.found_existing) sym_gop.value_ptr.* = coff.addSymbolAssumeCapacity(); |
| 2957 | 2958 | return @fromBackingInt(@intCast(sym_gop.index)); |
| 2958 | 2959 | } |
| 2959 | pub fn uavSymbol(coff: *Coff, uav_val: InternPool.Index) !Symbol.Index { | |
| 2960 | const umi = try coff.uavMapIndex(uav_val); | |
| 2961 | return umi.symbol(coff); | |
| 2962 | } | |
| 2963 | 2960 | |
| 2964 | 2961 | pub fn lazySymbol(coff: *Coff, lazy: link.File.LazySymbol) !Symbol.Index { |
| 2965 | 2962 | const gpa = coff.base.comp.gpa; |
| ... | ... | @@ -2972,24 +2969,8 @@ pub fn lazySymbol(coff: *Coff, lazy: link.File.LazySymbol) !Symbol.Index { |
| 2972 | 2969 | return sym_gop.value_ptr.*; |
| 2973 | 2970 | } |
| 2974 | 2971 | |
| 2975 | pub 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 | ||
| 2984 | pub 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 | ||
| 2992 | pub fn getVAddr(coff: *Coff, reloc_info: link.File.RelocInfo, target_si: Symbol.Index) link.Error!u64 { | |
| 2972 | pub fn relocSymAddr(coff: *Coff, reloc_info: link.File.RelocInfo) link.Error!void { | |
| 2973 | const target_si: Symbol.Index = @bitCast(reloc_info.target); | |
| 2993 | 2974 | try coff.addReloc( |
| 2994 | 2975 | @fromBackingInt(@intCast(@backingInt(reloc_info.parent.atom_index))), |
| 2995 | 2976 | reloc_info.offset, |
| ... | ... | @@ -3001,10 +2982,6 @@ pub fn getVAddr(coff: *Coff, reloc_info: link.File.RelocInfo, target_si: Symbol. |
| 3001 | 2982 | .I386 => .{ .I386 = .DIR32 }, |
| 3002 | 2983 | }, |
| 3003 | 2984 | ); |
| 3004 | ||
| 3005 | var vaddr: u64 = target_si.get(coff).rva; | |
| 3006 | if (coff.isImage()) vaddr += coff.optionalHeaderField(.image_base); | |
| 3007 | return vaddr; | |
| 3008 | 2985 | } |
| 3009 | 2986 | |
| 3010 | 2987 | /// Caller guarantees there is capacity for one member and two nodes |
| ... | ... | @@ -5580,13 +5557,15 @@ pub fn updateContainerType( |
| 5580 | 5557 | }; |
| 5581 | 5558 | } |
| 5582 | 5559 | |
| 5583 | pub fn lowerUav( | |
| 5560 | pub fn uavSymbol( | |
| 5584 | 5561 | coff: *Coff, |
| 5585 | 5562 | pt: Zcu.PerThread, |
| 5586 | 5563 | uav_val: InternPool.Index, |
| 5587 | 5564 | uav_align: InternPool.Alignment, |
| 5588 | 5565 | ) link.Error!link.File.SymbolId { |
| 5589 | const zcu = pt.zcu; | |
| 5566 | _ = pt; | |
| 5567 | ||
| 5568 | const zcu = coff.base.comp.zcu.?; | |
| 5590 | 5569 | const gpa = zcu.gpa; |
| 5591 | 5570 | |
| 5592 | 5571 | try coff.pending_uavs.ensureUnusedCapacity(gpa, 1); |
| ... | ... | @@ -7471,8 +7450,8 @@ fn updateExportInner( |
| 7471 | 7450 | |
| 7472 | 7451 | try coff.symbols.ensureUnusedCapacity(gpa, 1); |
| 7473 | 7452 | 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( | |
| 7476 | 7455 | pt, |
| 7477 | 7456 | uav, |
| 7478 | 7457 | Type.fromInterned(ip.typeOf(uav)).abiAlignment(zcu), |
src/link/Elf.zig+8-8| ... | ... | @@ -463,21 +463,21 @@ pub fn deinit(self: *Elf) void { |
| 463 | 463 | self.dump_argv_list.deinit(gpa); |
| 464 | 464 | } |
| 465 | 465 | |
| 466 | pub 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); | |
| 466 | pub fn navSymbol(self: *Elf, nav: InternPool.Nav.Index) link.Error!link.File.SymbolId { | |
| 467 | return self.zigObjectPtr().?.navSymbol(self, nav); | |
| 468 | 468 | } |
| 469 | 469 | |
| 470 | pub fn lowerUav( | |
| 470 | pub fn relocSymAddr(self: *Elf, reloc_info: link.File.RelocInfo) !void { | |
| 471 | return self.zigObjectPtr().?.relocSymAddr(self, reloc_info); | |
| 472 | } | |
| 473 | ||
| 474 | pub fn uavSymbol( | |
| 471 | 475 | self: *Elf, |
| 472 | 476 | pt: Zcu.PerThread, |
| 473 | 477 | uav: InternPool.Index, |
| 474 | 478 | explicit_alignment: InternPool.Alignment, |
| 475 | 479 | ) !link.File.SymbolId { |
| 476 | return self.zigObjectPtr().?.lowerUav(self, pt, uav, explicit_alignment); | |
| 477 | } | |
| 478 | ||
| 479 | pub 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); | |
| 481 | 481 | } |
| 482 | 482 | |
| 483 | 483 | /// 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 |
| 917 | 917 | return code; |
| 918 | 918 | } |
| 919 | 919 | |
| 920 | pub fn getNavVAddr( | |
| 921 | self: *ZigObject, | |
| 920 | pub fn navSymbol( | |
| 921 | zo: *ZigObject, | |
| 922 | 922 | elf_file: *Elf, |
| 923 | pt: Zcu.PerThread, | |
| 924 | 923 | 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.?; | |
| 928 | 926 | const ip = &zcu.intern_pool; |
| 929 | 927 | 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); | |
| 954 | 947 | } |
| 955 | return @intCast(vaddr); | |
| 956 | 948 | } |
| 957 | 949 | |
| 958 | pub fn getUavVAddr( | |
| 950 | pub fn relocSymAddr( | |
| 959 | 951 | self: *ZigObject, |
| 960 | 952 | elf_file: *Elf, |
| 961 | uav: InternPool.Index, | |
| 962 | 953 | 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); | |
| 967 | 956 | switch (reloc_info.parent) { |
| 968 | 957 | .none => unreachable, |
| 969 | 958 | .atom_index => |atom_index| { |
| ... | ... | @@ -971,20 +960,19 @@ pub fn getUavVAddr( |
| 971 | 960 | const r_type = relocation.encode(.abs, elf_file.getTarget().cpu.arch); |
| 972 | 961 | try parent_atom.addReloc(elf_file.base.comp.gpa, .{ |
| 973 | 962 | .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, | |
| 975 | 964 | .r_addend = reloc_info.addend, |
| 976 | 965 | }, self); |
| 977 | 966 | }, |
| 978 | 967 | .debug_output => |debug_output| try debug_output.dwarf.infoExternalReloc(.{ |
| 979 | 968 | .source_off = @intCast(reloc_info.offset), |
| 980 | .target_sym = @fromBackingInt(@intCast(sym_index)), | |
| 969 | .target_sym = @fromBackingInt(@intCast(this_sym_index)), | |
| 981 | 970 | .target_off = reloc_info.addend, |
| 982 | 971 | }), |
| 983 | 972 | } |
| 984 | return @intCast(vaddr); | |
| 985 | 973 | } |
| 986 | 974 | |
| 987 | pub fn lowerUav( | |
| 975 | pub fn uavSymbol( | |
| 988 | 976 | self: *ZigObject, |
| 989 | 977 | elf_file: *Elf, |
| 990 | 978 | pt: Zcu.PerThread, |
| ... | ... | @@ -1889,7 +1877,7 @@ pub fn updateExports( |
| 1889 | 1877 | break :blk self.navs.getPtr(nav).?; |
| 1890 | 1878 | }, |
| 1891 | 1879 | .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); | |
| 1893 | 1881 | break :blk self.uavs.getPtr(uav).?; |
| 1894 | 1882 | }, |
| 1895 | 1883 | }; |
src/link/Elf2.zig+3-33| ... | ... | @@ -4324,36 +4324,7 @@ pub fn navSymbol(elf: *Elf, nav_index: InternPool.Nav.Index) link.Error!link.Fil |
| 4324 | 4324 | const s: Symbol.Id = .local(nmi.symbol(elf)); |
| 4325 | 4325 | return s.toTypeErased(); |
| 4326 | 4326 | } |
| 4327 | pub fn uavSymbol( | |
| 4328 | elf: *Elf, | |
| 4329 | uav_val: InternPool.Index, | |
| 4330 | uav_align: InternPool.Alignment, | |
| 4331 | ) link.Error!link.File.SymbolId { | |
| 4332 | const diags = &elf.base.comp.link_diags; | |
| 4333 | const umi = elf.uavMapIndex(uav_val, uav_align) catch |err| switch (err) { | |
| 4334 | else => |e| return e, | |
| 4335 | error.MappedFileIo => return diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}), | |
| 4336 | }; | |
| 4337 | const s: Symbol.Id = .local(umi.symbol(elf)); | |
| 4338 | return s.toTypeErased(); | |
| 4339 | } | |
| 4340 | pub fn getNavVAddr( | |
| 4341 | elf: *Elf, | |
| 4342 | pt: Zcu.PerThread, | |
| 4343 | nav: InternPool.Nav.Index, | |
| 4344 | reloc_info: link.File.RelocInfo, | |
| 4345 | ) link.Error!u64 { | |
| 4346 | _ = pt; | |
| 4347 | return elf.getVAddr(reloc_info, try elf.navSymbol(nav)); | |
| 4348 | } | |
| 4349 | pub fn getUavVAddr( | |
| 4350 | elf: *Elf, | |
| 4351 | uav_val: InternPool.Index, | |
| 4352 | reloc_info: link.File.RelocInfo, | |
| 4353 | ) link.Error!u64 { | |
| 4354 | return elf.getVAddr(reloc_info, try elf.uavSymbol(uav_val, .none)); | |
| 4355 | } | |
| 4356 | pub fn getVAddr(elf: *Elf, reloc_info: link.File.RelocInfo, target: link.File.SymbolId) link.Error!u64 { | |
| 4327 | pub fn relocSymAddr(elf: *Elf, reloc_info: link.File.RelocInfo) link.Error!void { | |
| 4357 | 4328 | try elf.addReloc( |
| 4358 | 4329 | switch (reloc_info.parent) { |
| 4359 | 4330 | .none => unreachable, |
| ... | ... | @@ -4361,13 +4332,12 @@ pub fn getVAddr(elf: *Elf, reloc_info: link.File.RelocInfo, target: link.File.Sy |
| 4361 | 4332 | .debug_output => |debug_output| Node.toAtom(debug_output.dwarf2.info_writer.ni), |
| 4362 | 4333 | }, |
| 4363 | 4334 | reloc_info.offset, |
| 4364 | target, | |
| 4335 | reloc_info.target, | |
| 4365 | 4336 | reloc_info.addend, |
| 4366 | 4337 | .absAddr(elf), |
| 4367 | 4338 | ); |
| 4368 | return Symbol.Id.fromTypeErased(target).value(elf); | |
| 4369 | 4339 | } |
| 4370 | pub fn lowerUav( | |
| 4340 | pub fn uavSymbol( | |
| 4371 | 4341 | elf: *Elf, |
| 4372 | 4342 | pt: Zcu.PerThread, |
| 4373 | 4343 | uav_val: InternPool.Index, |
src/link/MachO.zig+8-8| ... | ... | @@ -3124,21 +3124,21 @@ pub fn freeNav(self: *MachO, nav: InternPool.Nav.Index) void { |
| 3124 | 3124 | return self.getZigObject().?.freeNav(nav); |
| 3125 | 3125 | } |
| 3126 | 3126 | |
| 3127 | pub 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); | |
| 3127 | pub fn navSymbol(self: *MachO, nav: InternPool.Nav.Index) link.Error!link.File.SymbolId { | |
| 3128 | return self.getZigObject().?.navSymbol(self, nav); | |
| 3129 | 3129 | } |
| 3130 | 3130 | |
| 3131 | pub fn lowerUav( | |
| 3131 | pub fn relocSymAddr(self: *MachO, reloc_info: link.File.RelocInfo) link.Error!void { | |
| 3132 | return self.getZigObject().?.relocSymAddr(self, reloc_info); | |
| 3133 | } | |
| 3134 | ||
| 3135 | pub fn uavSymbol( | |
| 3132 | 3136 | self: *MachO, |
| 3133 | 3137 | pt: Zcu.PerThread, |
| 3134 | 3138 | uav: InternPool.Index, |
| 3135 | 3139 | explicit_alignment: InternPool.Alignment, |
| 3136 | 3140 | ) !link.File.SymbolId { |
| 3137 | return self.getZigObject().?.lowerUav(self, pt, uav, explicit_alignment); | |
| 3138 | } | |
| 3139 | ||
| 3140 | pub 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); | |
| 3142 | 3142 | } |
| 3143 | 3143 | |
| 3144 | 3144 | pub 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 |
| 611 | 611 | assert(!self.debug_strtab_dirty); |
| 612 | 612 | } |
| 613 | 613 | |
| 614 | pub fn getNavVAddr( | |
| 615 | self: *ZigObject, | |
| 614 | pub fn navSymbol( | |
| 615 | zo: *ZigObject, | |
| 616 | 616 | macho_file: *MachO, |
| 617 | pt: Zcu.PerThread, | |
| 618 | 617 | 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.?; | |
| 622 | 620 | const ip = &zcu.intern_pool; |
| 623 | 621 | 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); | |
| 655 | 641 | } |
| 656 | return vaddr; | |
| 657 | 642 | } |
| 658 | 643 | |
| 659 | pub fn getUavVAddr( | |
| 644 | pub fn relocSymAddr( | |
| 660 | 645 | self: *ZigObject, |
| 661 | 646 | macho_file: *MachO, |
| 662 | uav: InternPool.Index, | |
| 663 | 647 | 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); | |
| 666 | 650 | const sym = self.symbols.items[sym_index]; |
| 667 | const vaddr = sym.getAddress(.{}, macho_file); | |
| 668 | 651 | switch (reloc_info.parent) { |
| 669 | 652 | .none => unreachable, |
| 670 | 653 | .atom_index => |atom_index| { |
| ... | ... | @@ -689,10 +672,9 @@ pub fn getUavVAddr( |
| 689 | 672 | .target_off = reloc_info.addend, |
| 690 | 673 | }), |
| 691 | 674 | } |
| 692 | return vaddr; | |
| 693 | 675 | } |
| 694 | 676 | |
| 695 | pub fn lowerUav( | |
| 677 | pub fn uavSymbol( | |
| 696 | 678 | self: *ZigObject, |
| 697 | 679 | macho_file: *MachO, |
| 698 | 680 | pt: Zcu.PerThread, |
| ... | ... | @@ -1281,7 +1263,7 @@ pub fn updateExports( |
| 1281 | 1263 | break :blk self.navs.getPtr(nav).?; |
| 1282 | 1264 | }, |
| 1283 | 1265 | .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); | |
| 1285 | 1267 | break :blk self.uavs.getPtr(uav).?; |
| 1286 | 1268 | }, |
| 1287 | 1269 | }; |