| ... | @@ -760,7 +760,9 @@ pub fn getOrCreateMetadataForLazySymbol( | ... | @@ -760,7 +760,9 @@ pub fn getOrCreateMetadataForLazySymbol( |
| 760 | const gpa = elf_file.base.comp.gpa; | 760 | const gpa = elf_file.base.comp.gpa; |
| 761 | const symbol_index = try self.newSymbolWithAtom(gpa, 0); | 761 | const symbol_index = try self.newSymbolWithAtom(gpa, 0); |
| 762 | const sym = self.symbol(symbol_index); | 762 | const sym = self.symbol(symbol_index); |
| 763 | sym.flags.needs_zig_got = true; | 763 | if (lazy_sym.kind != .code) { |
| | 764 | sym.flags.needs_zig_got = true; |
| | 765 | } |
| 764 | symbol_index_ptr.* = symbol_index; | 766 | symbol_index_ptr.* = symbol_index; |
| 765 | }, | 767 | }, |
| 766 | .pending_flush => return symbol_index_ptr.*, | 768 | .pending_flush => return symbol_index_ptr.*, |
| ... | @@ -816,7 +818,7 @@ pub fn getOrCreateMetadataForNav( | ... | @@ -816,7 +818,7 @@ pub fn getOrCreateMetadataForNav( |
| 816 | sym.flags.is_tls = true; | 818 | sym.flags.is_tls = true; |
| 817 | } | 819 | } |
| 818 | } | 820 | } |
| 819 | if (!sym.flags.is_tls) { | 821 | if (!sym.flags.is_tls and nav_val.typeOf(zcu).zigTypeTag(zcu) != .Fn) { |
| 820 | sym.flags.needs_zig_got = true; | 822 | sym.flags.needs_zig_got = true; |
| 821 | } | 823 | } |
| 822 | gop.value_ptr.* = .{ .symbol_index = symbol_index }; | 824 | gop.value_ptr.* = .{ .symbol_index = symbol_index }; |
| ... | @@ -919,16 +921,19 @@ fn updateNavCode( | ... | @@ -919,16 +921,19 @@ fn updateNavCode( |
| 919 | sym.value = 0; | 921 | sym.value = 0; |
| 920 | esym.st_value = 0; | 922 | esym.st_value = 0; |
| 921 | | 923 | |
| 922 | if (!elf_file.base.isRelocatable()) { | 924 | if (stt_bits != elf.STT_FUNC) { |
| 923 | log.debug(" (writing new offset table entry)", .{}); | 925 | if (!elf_file.base.isRelocatable()) { |
| 924 | assert(sym.flags.has_zig_got); | 926 | log.debug(" (writing new offset table entry)", .{}); |
| 925 | const extra = sym.extra(elf_file); | 927 | assert(sym.flags.has_zig_got); |
| 926 | try elf_file.zig_got.writeOne(elf_file, extra.zig_got); | 928 | const extra = sym.extra(elf_file); |
| 927 | if (stt_bits == elf.STT_FUNC) { | 929 | try elf_file.zig_got.writeOne(elf_file, extra.zig_got); |
| 928 | const offset_table = self.offsetTablePtr().?; | | |
| 929 | offset_table.entries.items(.dirty)[extra.zig_offset_table] = true; | | |
| 930 | } | 930 | } |
| 931 | } | 931 | } |
| | 932 | if (stt_bits == elf.STT_FUNC) { |
| | 933 | const extra = sym.extra(elf_file); |
| | 934 | const offset_table = self.offsetTablePtr().?; |
| | 935 | offset_table.entries.items(.dirty)[extra.zig_offset_table] = true; |
| | 936 | } |
| 932 | } | 937 | } |
| 933 | } else if (code.len < old_size) { | 938 | } else if (code.len < old_size) { |
| 934 | atom_ptr.shrink(elf_file); | 939 | atom_ptr.shrink(elf_file); |
| ... | @@ -938,12 +943,13 @@ fn updateNavCode( | ... | @@ -938,12 +943,13 @@ fn updateNavCode( |
| 938 | errdefer self.freeNavMetadata(elf_file, sym_index); | 943 | errdefer self.freeNavMetadata(elf_file, sym_index); |
| 939 | | 944 | |
| 940 | sym.value = 0; | 945 | sym.value = 0; |
| 941 | sym.flags.needs_zig_got = true; | | |
| 942 | esym.st_value = 0; | 946 | esym.st_value = 0; |
| 943 | | 947 | if (stt_bits != elf.STT_FUNC) { |
| 944 | if (!elf_file.base.isRelocatable()) { | 948 | sym.flags.needs_zig_got = true; |
| 945 | const gop = try sym.getOrCreateZigGotEntry(sym_index, elf_file); | 949 | if (!elf_file.base.isRelocatable()) { |
| 946 | try elf_file.zig_got.writeOne(elf_file, gop.index); | 950 | const gop = try sym.getOrCreateZigGotEntry(sym_index, elf_file); |
| | 951 | try elf_file.zig_got.writeOne(elf_file, gop.index); |
| | 952 | } |
| 947 | } | 953 | } |
| 948 | } | 954 | } |
| 949 | | 955 | |
| ... | @@ -1061,7 +1067,12 @@ pub fn updateFunc( | ... | @@ -1061,7 +1067,12 @@ pub fn updateFunc( |
| 1061 | sym.flags.zig_offset_table = true; | 1067 | sym.flags.zig_offset_table = true; |
| 1062 | sym.addExtra(.{ .zig_offset_table = index }, elf_file); | 1068 | sym.addExtra(.{ .zig_offset_table = index }, elf_file); |
| 1063 | try offset_table.updateSize(self, elf_file); | 1069 | try offset_table.updateSize(self, elf_file); |
| | 1070 | const old_vaddr = offset_table.address(self, elf_file); |
| 1064 | try self.symbol(offset_table.sym_index).atom(elf_file).?.allocate(elf_file); | 1071 | try self.symbol(offset_table.sym_index).atom(elf_file).?.allocate(elf_file); |
| | 1072 | const new_vaddr = offset_table.address(self, elf_file); |
| | 1073 | if (old_vaddr != new_vaddr) { |
| | 1074 | offset_table.dirty = true; |
| | 1075 | } |
| 1065 | } | 1076 | } |
| 1066 | } | 1077 | } |
| 1067 | | 1078 | |
| ... | @@ -1106,7 +1117,13 @@ pub fn updateFunc( | ... | @@ -1106,7 +1117,13 @@ pub fn updateFunc( |
| 1106 | | 1117 | |
| 1107 | // Exports will be updated by `Zcu.processExports` after the update. | 1118 | // Exports will be updated by `Zcu.processExports` after the update. |
| 1108 | | 1119 | |
| 1109 | { | 1120 | if (offset_table.dirty) { |
| | 1121 | // TODO write in bulk |
| | 1122 | for (offset_table.entries.items(.dirty), 0..) |*dirty, i| { |
| | 1123 | try offset_table.writeEntry(@intCast(i), self, elf_file); |
| | 1124 | dirty.* = false; |
| | 1125 | } |
| | 1126 | } else { |
| 1110 | const sym = self.symbol(sym_index); | 1127 | const sym = self.symbol(sym_index); |
| 1111 | const ot_index = sym.extra(elf_file).zig_offset_table; | 1128 | const ot_index = sym.extra(elf_file).zig_offset_table; |
| 1112 | var ot_entry = offset_table.entries.get(ot_index); | 1129 | var ot_entry = offset_table.entries.get(ot_index); |
| ... | @@ -1261,7 +1278,9 @@ fn updateLazySymbol( | ... | @@ -1261,7 +1278,9 @@ fn updateLazySymbol( |
| 1261 | errdefer self.freeNavMetadata(elf_file, symbol_index); | 1278 | errdefer self.freeNavMetadata(elf_file, symbol_index); |
| 1262 | | 1279 | |
| 1263 | local_sym.value = 0; | 1280 | local_sym.value = 0; |
| 1264 | local_sym.flags.needs_zig_got = true; | 1281 | if (sym.kind != .code) { |
| | 1282 | local_sym.flags.needs_zig_got = true; |
| | 1283 | } |
| 1265 | local_esym.st_value = 0; | 1284 | local_esym.st_value = 0; |
| 1266 | | 1285 | |
| 1267 | if (!elf_file.base.isRelocatable()) { | 1286 | if (!elf_file.base.isRelocatable()) { |
| ... | @@ -1476,7 +1495,7 @@ pub fn getGlobalSymbol(self: *ZigObject, elf_file: *Elf, name: []const u8, lib_n | ... | @@ -1476,7 +1495,7 @@ pub fn getGlobalSymbol(self: *ZigObject, elf_file: *Elf, name: []const u8, lib_n |
| 1476 | return lookup_gop.value_ptr.*; | 1495 | return lookup_gop.value_ptr.*; |
| 1477 | } | 1496 | } |
| 1478 | | 1497 | |
| 1479 | fn offsetTablePtr(self: *ZigObject) ?*OffsetTable { | 1498 | pub fn offsetTablePtr(self: *ZigObject) ?*OffsetTable { |
| 1480 | return if (self.offset_table) |*ot| ot else null; | 1499 | return if (self.offset_table) |*ot| ot else null; |
| 1481 | } | 1500 | } |
| 1482 | | 1501 | |
| ... | @@ -1747,6 +1766,7 @@ const TlsTable = std.AutoArrayHashMapUnmanaged(Atom.Index, TlsVariable); | ... | @@ -1747,6 +1766,7 @@ const TlsTable = std.AutoArrayHashMapUnmanaged(Atom.Index, TlsVariable); |
| 1747 | pub const OffsetTable = struct { | 1766 | pub const OffsetTable = struct { |
| 1748 | sym_index: Symbol.Index, | 1767 | sym_index: Symbol.Index, |
| 1749 | entries: std.MultiArrayList(Entry) = .{}, | 1768 | entries: std.MultiArrayList(Entry) = .{}, |
| | 1769 | dirty: bool = false, |
| 1750 | | 1770 | |
| 1751 | pub fn deinit(ot: *OffsetTable, allocator: Allocator) void { | 1771 | pub fn deinit(ot: *OffsetTable, allocator: Allocator) void { |
| 1752 | ot.entries.deinit(allocator); | 1772 | ot.entries.deinit(allocator); |