authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-08-09 09:10:59+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-08-13 13:30:24+02:00
logd328140858ab7f0f3eeb5d53b50bae32ab331686
tree63881cfb19195a7629ae5ae891837bb96eebbffc
parent4c2b34e8abd1fc2091eeb10798658bd9bb3910f5

elf: nuke ZigGotSection from existence


8 files changed, 30 insertions(+), 438 deletions(-)

src/arch/x86_64/Emit.zig+12-33
......@@ -110,21 +110,11 @@ pub fn emitMir(emit: *Emit) Error!void {
110110 });
111111 },
112112 .linker_reloc => |data| if (emit.lower.bin_file.cast(.elf)) |elf_file| {
113 const is_obj_or_static_lib = switch (emit.lower.output_mode) {
114 .Exe => false,
115 .Obj => true,
116 .Lib => emit.lower.link_mode == .static,
117 };
118113 const zo = elf_file.zigObjectPtr().?;
119114 const atom = zo.symbol(data.atom_index).atom(elf_file).?;
120115 const sym = zo.symbol(data.sym_index);
121 if (sym.flags.needs_zig_got and !is_obj_or_static_lib) {
122 _ = try sym.getOrCreateZigGotEntry(data.sym_index, elf_file);
123 }
124116 if (emit.lower.pic) {
125 const r_type: u32 = if (sym.flags.needs_zig_got and !is_obj_or_static_lib)
126 link.File.Elf.R_ZIG_GOTPCREL
127 else if (sym.flags.needs_got)
117 const r_type: u32 = if (sym.flags.needs_got)
128118 @intFromEnum(std.elf.R_X86_64.GOTPCREL)
129119 else
130120 @intFromEnum(std.elf.R_X86_64.PC32);
......@@ -134,28 +124,17 @@ pub fn emitMir(emit: *Emit) Error!void {
134124 .r_addend = -4,
135125 });
136126 } else {
137 if (lowered_inst.encoding.mnemonic == .call and sym.flags.needs_zig_got and is_obj_or_static_lib) {
138 const r_type = @intFromEnum(std.elf.R_X86_64.PC32);
139 try atom.addReloc(elf_file, .{
140 .r_offset = end_offset - 4,
141 .r_info = (@as(u64, @intCast(data.sym_index)) << 32) | r_type,
142 .r_addend = -4,
143 });
144 } else {
145 const r_type: u32 = if (sym.flags.needs_zig_got and !is_obj_or_static_lib)
146 link.File.Elf.R_ZIG_GOT32
147 else if (sym.flags.needs_got)
148 @intFromEnum(std.elf.R_X86_64.GOT32)
149 else if (sym.flags.is_tls)
150 @intFromEnum(std.elf.R_X86_64.TPOFF32)
151 else
152 @intFromEnum(std.elf.R_X86_64.@"32");
153 try atom.addReloc(elf_file, .{
154 .r_offset = end_offset - 4,
155 .r_info = (@as(u64, @intCast(data.sym_index)) << 32) | r_type,
156 .r_addend = 0,
157 });
158 }
127 const r_type: u32 = if (sym.flags.needs_got)
128 @intFromEnum(std.elf.R_X86_64.GOT32)
129 else if (sym.flags.is_tls)
130 @intFromEnum(std.elf.R_X86_64.TPOFF32)
131 else
132 @intFromEnum(std.elf.R_X86_64.@"32");
133 try atom.addReloc(elf_file, .{
134 .r_offset = end_offset - 4,
135 .r_info = (@as(u64, @intCast(data.sym_index)) << 32) | r_type,
136 .r_addend = 0,
137 });
159138 }
160139 } else if (emit.lower.bin_file.cast(.macho)) |macho_file| {
161140 const is_obj_or_static_lib = switch (emit.lower.output_mode) {
src/arch/x86_64/Lower.zig+6-16
......@@ -398,30 +398,20 @@ fn emit(lower: *Lower, prefix: Prefix, mnemonic: Mnemonic, ops: []const Operand)
398398
399399 _ = lower.reloc(.{ .linker_reloc = sym });
400400 break :op if (lower.pic) switch (mnemonic) {
401 .lea => {
402 break :op .{ .mem = Memory.rip(mem_op.sib.ptr_size, 0) };
403 },
404 .mov => {
405 if (is_obj_or_static_lib and elf_sym.flags.needs_zig_got) emit_mnemonic = .lea;
406 break :op .{ .mem = Memory.rip(mem_op.sib.ptr_size, 0) };
407 },
401 .lea => break :op .{ .mem = Memory.rip(mem_op.sib.ptr_size, 0) },
402 .mov => break :op .{ .mem = Memory.rip(mem_op.sib.ptr_size, 0) },
408403 else => unreachable,
409404 } else switch (mnemonic) {
410 .call => break :op if (is_obj_or_static_lib and elf_sym.flags.needs_zig_got) .{
411 .imm = Immediate.s(0),
412 } else .{ .mem = Memory.sib(mem_op.sib.ptr_size, .{
405 .call => break :op .{ .mem = Memory.sib(mem_op.sib.ptr_size, .{
413406 .base = .{ .reg = .ds },
414407 }) },
415408 .lea => {
416409 emit_mnemonic = .mov;
417410 break :op .{ .imm = Immediate.s(0) };
418411 },
419 .mov => {
420 if (is_obj_or_static_lib and elf_sym.flags.needs_zig_got) emit_mnemonic = .lea;
421 break :op .{ .mem = Memory.sib(mem_op.sib.ptr_size, .{
422 .base = .{ .reg = .ds },
423 }) };
424 },
412 .mov => break :op .{ .mem = Memory.sib(mem_op.sib.ptr_size, .{
413 .base = .{ .reg = .ds },
414 }) },
425415 else => unreachable,
426416 };
427417 } else if (lower.bin_file.cast(.macho)) |macho_file| {
src/link/Elf.zig+3-75
......@@ -64,9 +64,6 @@ phdrs: std.ArrayListUnmanaged(elf.Elf64_Phdr) = .{},
6464/// Tracked loadable segments during incremental linking.
6565/// The index into the program headers of a PT_LOAD program header with Read and Execute flags
6666phdr_zig_load_re_index: ?u16 = null,
67/// The index into the program headers of the global offset table.
68/// It needs PT_LOAD and Read flags.
69phdr_zig_got_index: ?u16 = null,
7067/// The index into the program headers of a PT_LOAD program header with Read flag
7168phdr_zig_load_ro_index: ?u16 = null,
7269/// The index into the program headers of a PT_LOAD program header with Write flag
......@@ -130,8 +127,6 @@ plt_got: PltGotSection = .{},
130127copy_rel: CopyRelSection = .{},
131128/// .rela.plt section
132129rela_plt: std.ArrayListUnmanaged(elf.Elf64_Rela) = .{},
133/// .got.zig section
134zig_got: ZigGotSection = .{},
135130/// SHT_GROUP sections
136131/// Applies only to a relocatable.
137132comdat_group_sections: std.ArrayListUnmanaged(ComdatGroupSection) = .{},
......@@ -142,7 +137,6 @@ zig_text_section_index: ?u32 = null,
142137zig_data_rel_ro_section_index: ?u32 = null,
143138zig_data_section_index: ?u32 = null,
144139zig_bss_section_index: ?u32 = null,
145zig_got_section_index: ?u32 = null,
146140
147141debug_info_section_index: ?u32 = null,
148142debug_abbrev_section_index: ?u32 = null,
......@@ -474,7 +468,6 @@ pub fn deinit(self: *Elf) void {
474468 self.copy_rel.deinit(gpa);
475469 self.rela_dyn.deinit(gpa);
476470 self.rela_plt.deinit(gpa);
477 self.zig_got.deinit(gpa);
478471 self.comdat_group_sections.deinit(gpa);
479472}
480473
......@@ -618,21 +611,6 @@ pub fn initMetadata(self: *Elf, options: InitMetadataOptions) !void {
618611 });
619612 }
620613
621 if (self.phdr_zig_got_index == null) {
622 const alignment = self.page_size;
623 const filesz = @as(u64, ptr_size) * options.symbol_count_hint;
624 const off = self.findFreeSpace(filesz, alignment);
625 self.phdr_zig_got_index = try self.addPhdr(.{
626 .type = elf.PT_LOAD,
627 .offset = off,
628 .filesz = filesz,
629 .addr = if (ptr_bit_width >= 32) 0x4000000 else 0x4000,
630 .memsz = filesz,
631 .@"align" = alignment,
632 .flags = elf.PF_R | elf.PF_W,
633 });
634 }
635
636614 if (self.phdr_zig_load_ro_index == null) {
637615 const alignment = self.page_size;
638616 const filesz: u64 = 1024;
......@@ -701,27 +679,6 @@ pub fn initMetadata(self: *Elf, options: InitMetadataOptions) !void {
701679 try self.last_atom_and_free_list_table.putNoClobber(gpa, self.zig_text_section_index.?, .{});
702680 }
703681
704 if (self.zig_got_section_index == null and !self.base.isRelocatable()) {
705 self.zig_got_section_index = try self.addSection(.{
706 .name = try self.insertShString(".got.zig"),
707 .type = elf.SHT_PROGBITS,
708 .addralign = ptr_size,
709 .flags = elf.SHF_ALLOC | elf.SHF_WRITE,
710 .offset = std.math.maxInt(u64),
711 });
712 const shdr = &self.shdrs.items[self.zig_got_section_index.?];
713 const phndx = self.phdr_zig_got_index.?;
714 const phdr = self.phdrs.items[phndx];
715 shdr.sh_addr = phdr.p_vaddr;
716 shdr.sh_offset = phdr.p_offset;
717 shdr.sh_size = phdr.p_memsz;
718 try self.phdr_to_shdr_table.putNoClobber(
719 gpa,
720 self.zig_got_section_index.?,
721 self.phdr_zig_got_index.?,
722 );
723 }
724
725682 if (self.zig_data_rel_ro_section_index == null) {
726683 self.zig_data_rel_ro_section_index = try self.addSection(.{
727684 .name = try self.insertShString(".data.rel.ro.zig"),
......@@ -3156,8 +3113,8 @@ fn initSyntheticSections(self: *Elf) !void {
31563113 });
31573114
31583115 const needs_rela_dyn = blk: {
3159 if (self.got.flags.needs_rela or self.got.flags.needs_tlsld or
3160 self.zig_got.flags.needs_rela or self.copy_rel.symbols.items.len > 0) break :blk true;
3116 if (self.got.flags.needs_rela or self.got.flags.needs_tlsld or self.copy_rel.symbols.items.len > 0)
3117 break :blk true;
31613118 if (self.zigObjectPtr()) |zig_object| {
31623119 if (zig_object.num_dynrelocs > 0) break :blk true;
31633120 }
......@@ -3562,7 +3519,6 @@ fn sortPhdrs(self: *Elf) error{OutOfMemory}!void {
35623519
35633520 for (&[_]*?u16{
35643521 &self.phdr_zig_load_re_index,
3565 &self.phdr_zig_got_index,
35663522 &self.phdr_zig_load_ro_index,
35673523 &self.phdr_zig_load_zerofill_index,
35683524 &self.phdr_table_index,
......@@ -3694,7 +3650,6 @@ fn resetShdrIndexes(self: *Elf, backlinks: []const u32) !void {
36943650 &self.versym_section_index,
36953651 &self.verneed_section_index,
36963652 &self.zig_text_section_index,
3697 &self.zig_got_section_index,
36983653 &self.zig_data_rel_ro_section_index,
36993654 &self.zig_data_section_index,
37003655 &self.zig_bss_section_index,
......@@ -3893,7 +3848,7 @@ fn updateSectionSizes(self: *Elf) !void {
38933848 }
38943849
38953850 if (self.rela_dyn_section_index) |shndx| {
3896 var num = self.got.numRela(self) + self.copy_rel.numRela() + self.zig_got.numRela();
3851 var num = self.got.numRela(self) + self.copy_rel.numRela();
38973852 if (self.zigObjectPtr()) |zig_object| {
38983853 num += zig_object.num_dynrelocs;
38993854 }
......@@ -4431,15 +4386,6 @@ pub fn updateSymtabSize(self: *Elf) !void {
44314386 strsize += ctx.strsize;
44324387 }
44334388
4434 if (self.zigObjectPtr()) |_| {
4435 if (self.zig_got_section_index) |_| {
4436 self.zig_got.output_symtab_ctx.ilocal = nlocals + 1;
4437 self.zig_got.updateSymtabSize(self);
4438 nlocals += self.zig_got.output_symtab_ctx.nlocals;
4439 strsize += self.zig_got.output_symtab_ctx.strsize;
4440 }
4441 }
4442
44434389 if (self.got_section_index) |_| {
44444390 self.got.output_symtab_ctx.ilocal = nlocals + 1;
44454391 self.got.updateSymtabSize(self);
......@@ -4576,9 +4522,6 @@ fn writeSyntheticSections(self: *Elf) !void {
45764522 const shdr = self.shdrs.items[shndx];
45774523 try self.got.addRela(self);
45784524 try self.copy_rel.addRela(self);
4579 if (self.zigObjectPtr()) |_| {
4580 try self.zig_got.addRela(self);
4581 }
45824525 self.sortRelaDyn();
45834526 try self.base.file.?.pwriteAll(mem.sliceAsBytes(self.rela_dyn.items), shdr.sh_offset);
45844527 }
......@@ -4674,10 +4617,6 @@ pub fn writeSymtab(self: *Elf) !void {
46744617 obj.asFile().writeSymtab(self);
46754618 }
46764619
4677 if (self.zig_got_section_index) |_| {
4678 self.zig_got.writeSymtab(self);
4679 }
4680
46814620 if (self.got_section_index) |_| {
46824621 self.got.writeSymtab(self);
46834622 }
......@@ -5085,7 +5024,6 @@ pub fn isZigSection(self: Elf, shndx: u32) bool {
50855024 self.zig_data_rel_ro_section_index,
50865025 self.zig_data_section_index,
50875026 self.zig_bss_section_index,
5088 self.zig_got_section_index,
50895027 }) |maybe_index| {
50905028 if (maybe_index) |index| {
50915029 if (index == shndx) return true;
......@@ -5704,7 +5642,6 @@ fn fmtDumpState(
57045642 }
57055643 }
57065644
5707 try writer.print("{}\n", .{self.zig_got.fmt(self)});
57085645 try writer.print("{}\n", .{self.got.fmt(self)});
57095646 try writer.print("{}\n", .{self.plt.fmt(self)});
57105647
......@@ -5995,20 +5932,12 @@ const RelaSection = struct {
59955932};
59965933const RelaSectionTable = std.AutoArrayHashMapUnmanaged(u32, RelaSection);
59975934
5998pub const R_ZIG_GOT32: u32 = 0xff00;
5999pub const R_ZIG_GOTPCREL: u32 = 0xff01;
6000pub const R_ZIG_GOT_HI20: u32 = 0xff02;
6001pub const R_ZIG_GOT_LO12: u32 = 0xff03;
60025935pub const R_GOT_HI20_STATIC: u32 = 0xff04;
60035936pub const R_GOT_LO12_I_STATIC: u32 = 0xff05;
60045937
60055938// Comptime asserts that no Zig relocs overlap with another ISA's reloc number
60065939comptime {
60075940 const zig_relocs = .{
6008 R_ZIG_GOT32,
6009 R_ZIG_GOT_HI20,
6010 R_ZIG_GOT_LO12,
6011 R_ZIG_GOTPCREL,
60125941 R_GOT_HI20_STATIC,
60135942 R_GOT_LO12_I_STATIC,
60145943 };
......@@ -6099,6 +6028,5 @@ const StringTable = @import("StringTable.zig");
60996028const Thunk = thunks.Thunk;
61006029const Value = @import("../Value.zig");
61016030const VerneedSection = synthetic_sections.VerneedSection;
6102const ZigGotSection = synthetic_sections.ZigGotSection;
61036031const ZigObject = @import("Elf/ZigObject.zig");
61046032const riscv = @import("riscv.zig");
src/link/Elf/Atom.zig+8-41
......@@ -750,8 +750,8 @@ pub fn resolveRelocsAlloc(self: Atom, elf_file: *Elf, code: []u8) RelocError!voi
750750 const S = target.address(.{}, elf_file);
751751 // Address of the global offset table.
752752 const GOT = elf_file.gotAddress();
753 // Address of the .zig.got table entry if any.
754 const ZIG_GOT = target.zigGotAddress(elf_file);
753 // Address of the offset table entry if any.
754 const ZIG_GOT = target.zigOffsetTableAddress(elf_file);
755755 // Relative offset to the start of the global offset table.
756756 const G = target.gotAddress(elf_file) - GOT;
757757 // // Address of the thread pointer.
......@@ -759,14 +759,13 @@ pub fn resolveRelocsAlloc(self: Atom, elf_file: *Elf, code: []u8) RelocError!voi
759759 // Address of the dynamic thread pointer.
760760 const DTP = elf_file.dtpAddress();
761761
762 relocs_log.debug(" {s}: {x}: [{x} => {x}] G({x}) ZG({x}) ZG2({x}) ({s})", .{
762 relocs_log.debug(" {s}: {x}: [{x} => {x}] G({x}) ZG({x}) ({s})", .{
763763 relocation.fmtRelocType(rel.r_type(), cpu_arch),
764764 r_offset,
765765 P,
766766 S + A,
767767 G + GOT + A,
768768 ZIG_GOT + A,
769 target.zigOffsetTableAddress(elf_file) + A,
770769 target.name(elf_file),
771770 });
772771
......@@ -1181,16 +1180,7 @@ const x86_64 = struct {
11811180 .TLSDESC_CALL,
11821181 => {},
11831182
1184 else => |x| switch (@intFromEnum(x)) {
1185 // Zig custom relocations
1186 Elf.R_ZIG_GOT32,
1187 Elf.R_ZIG_GOTPCREL,
1188 => {
1189 assert(symbol.flags.has_zig_got);
1190 },
1191
1192 else => try atom.reportUnhandledRelocError(rel, elf_file),
1193 },
1183 else => try atom.reportUnhandledRelocError(rel, elf_file),
11941184 }
11951185 }
11961186
......@@ -1228,7 +1218,7 @@ const x86_64 = struct {
12281218 .PLT32 => try cwriter.writeInt(i32, @as(i32, @intCast(S + A - P)), .little),
12291219
12301220 .PC32 => {
1231 const S_ = if (target.flags.zig_offset_table) target.zigOffsetTableAddress(elf_file) else S;
1221 const S_ = if (target.flags.zig_offset_table) ZIG_GOT else S;
12321222 try cwriter.writeInt(i32, @as(i32, @intCast(S_ + A - P)), .little);
12331223 },
12341224
......@@ -1255,7 +1245,7 @@ const x86_64 = struct {
12551245 },
12561246
12571247 .@"32" => {
1258 const S_ = if (target.flags.zig_offset_table) target.zigOffsetTableAddress(elf_file) else S;
1248 const S_ = if (target.flags.zig_offset_table) ZIG_GOT else S;
12591249 try cwriter.writeInt(u32, @as(u32, @truncate(@as(u64, @intCast(S_ + A)))), .little);
12601250 },
12611251 .@"32S" => try cwriter.writeInt(i32, @as(i32, @truncate(S + A)), .little),
......@@ -1336,13 +1326,7 @@ const x86_64 = struct {
13361326
13371327 .GOT32 => try cwriter.writeInt(i32, @as(i32, @intCast(G + GOT + A)), .little),
13381328
1339 else => |x| switch (@intFromEnum(x)) {
1340 // Zig custom relocations
1341 Elf.R_ZIG_GOT32 => try cwriter.writeInt(u32, @as(u32, @intCast(ZIG_GOT + A)), .little),
1342 Elf.R_ZIG_GOTPCREL => try cwriter.writeInt(i32, @as(i32, @intCast(ZIG_GOT + A - P)), .little),
1343
1344 else => try atom.reportUnhandledRelocError(rel, elf_file),
1345 },
1329 else => try atom.reportUnhandledRelocError(rel, elf_file),
13461330 }
13471331 }
13481332
......@@ -2006,12 +1990,6 @@ const riscv = struct {
20061990 => {},
20071991
20081992 else => |x| switch (@intFromEnum(x)) {
2009 Elf.R_ZIG_GOT_HI20,
2010 Elf.R_ZIG_GOT_LO12,
2011 => {
2012 assert(symbol.flags.has_zig_got);
2013 },
2014
20151993 Elf.R_GOT_HI20_STATIC,
20161994 Elf.R_GOT_LO12_I_STATIC,
20171995 => symbol.flags.needs_got = true,
......@@ -2038,6 +2016,7 @@ const riscv = struct {
20382016 const P, const A, const S, const GOT, const G, const TP, const DTP, const ZIG_GOT = args;
20392017 _ = TP;
20402018 _ = DTP;
2019 _ = ZIG_GOT;
20412020
20422021 switch (r_type) {
20432022 .NONE => unreachable,
......@@ -2156,18 +2135,6 @@ const riscv = struct {
21562135
21572136 else => |x| switch (@intFromEnum(x)) {
21582137 // Zig custom relocations
2159 Elf.R_ZIG_GOT_HI20 => {
2160 assert(target.flags.has_zig_got);
2161 const disp: u32 = @bitCast(math.cast(i32, ZIG_GOT + A) orelse return error.Overflow);
2162 riscv_util.writeInstU(code[r_offset..][0..4], disp);
2163 },
2164
2165 Elf.R_ZIG_GOT_LO12 => {
2166 assert(target.flags.has_zig_got);
2167 const value: u32 = @bitCast(math.cast(i32, ZIG_GOT + A) orelse return error.Overflow);
2168 riscv_util.writeInstI(code[r_offset..][0..4], value);
2169 },
2170
21712138 Elf.R_GOT_HI20_STATIC => {
21722139 assert(target.flags.has_got);
21732140 const disp: u32 = @bitCast(math.cast(i32, G + GOT + A) orelse return error.Overflow);
src/link/Elf/Symbol.zig-25
......@@ -217,25 +217,6 @@ pub fn tlsDescAddress(symbol: Symbol, elf_file: *Elf) i64 {
217217 return entry.address(elf_file);
218218}
219219
220const GetOrCreateZigGotEntryResult = struct {
221 found_existing: bool,
222 index: ZigGotSection.Index,
223};
224
225pub fn getOrCreateZigGotEntry(symbol: *Symbol, symbol_index: Index, elf_file: *Elf) !GetOrCreateZigGotEntryResult {
226 assert(!elf_file.base.isRelocatable());
227 assert(symbol.flags.needs_zig_got);
228 if (symbol.flags.has_zig_got) return .{ .found_existing = true, .index = symbol.extra(elf_file).zig_got };
229 const index = try elf_file.zig_got.addSymbol(symbol_index, elf_file);
230 return .{ .found_existing = false, .index = index };
231}
232
233pub fn zigGotAddress(symbol: Symbol, elf_file: *Elf) i64 {
234 if (!symbol.flags.has_zig_got) return 0;
235 const extras = symbol.extra(elf_file);
236 return elf_file.zig_got.entryAddress(extras.zig_got, elf_file);
237}
238
239220pub fn zigOffsetTableAddress(symbol: Symbol, elf_file: *Elf) i64 {
240221 if (!symbol.flags.zig_offset_table) return 0;
241222 const zo = elf_file.zigObjectPtr().?;
......@@ -267,7 +248,6 @@ const AddExtraOpts = struct {
267248 tlsgd: ?u32 = null,
268249 gottp: ?u32 = null,
269250 tlsdesc: ?u32 = null,
270 zig_got: ?u32 = null,
271251 zig_offset_table: ?u32 = null,
272252};
273253
......@@ -465,10 +445,6 @@ pub const Flags = packed struct {
465445 needs_tlsdesc: bool = false,
466446 has_tlsdesc: bool = false,
467447
468 /// Whether the symbol contains .zig.got indirection.
469 needs_zig_got: bool = false,
470 has_zig_got: bool = false,
471
472448 /// Whether the symbol is a TLS variable.
473449 /// TODO this is really not needed if only we operated on esyms between
474450 /// codegen and ZigObject.
......@@ -491,7 +467,6 @@ pub const Extra = struct {
491467 tlsgd: u32 = 0,
492468 gottp: u32 = 0,
493469 tlsdesc: u32 = 0,
494 zig_got: u32 = 0,
495470 merge_section: u32 = 0,
496471 zig_offset_table: u32 = 0,
497472};
src/link/Elf/ZigObject.zig+1-35
......@@ -756,15 +756,7 @@ pub fn getOrCreateMetadataForLazySymbol(
756756 .const_data => .{ &gop.value_ptr.rodata_symbol_index, &gop.value_ptr.rodata_state },
757757 };
758758 switch (state_ptr.*) {
759 .unused => {
760 const gpa = elf_file.base.comp.gpa;
761 const symbol_index = try self.newSymbolWithAtom(gpa, 0);
762 const sym = self.symbol(symbol_index);
763 if (lazy_sym.kind != .code) {
764 sym.flags.needs_zig_got = true;
765 }
766 symbol_index_ptr.* = symbol_index;
767 },
759 .unused => symbol_index_ptr.* = try self.newSymbolWithAtom(pt.zcu.gpa, 0),
768760 .pending_flush => return symbol_index_ptr.*,
769761 .flushed => {},
770762 }
......@@ -818,9 +810,6 @@ pub fn getOrCreateMetadataForNav(
818810 sym.flags.is_tls = true;
819811 }
820812 }
821 if (!sym.flags.is_tls and nav_val.typeOf(zcu).zigTypeTag(zcu) != .Fn) {
822 sym.flags.needs_zig_got = true;
823 }
824813 gop.value_ptr.* = .{ .symbol_index = symbol_index };
825814 }
826815 return gop.value_ptr.symbol_index;
......@@ -921,14 +910,6 @@ fn updateNavCode(
921910 sym.value = 0;
922911 esym.st_value = 0;
923912
924 if (stt_bits != elf.STT_FUNC) {
925 if (!elf_file.base.isRelocatable()) {
926 log.debug(" (writing new offset table entry)", .{});
927 assert(sym.flags.has_zig_got);
928 const extra = sym.extra(elf_file);
929 try elf_file.zig_got.writeOne(elf_file, extra.zig_got);
930 }
931 }
932913 if (stt_bits == elf.STT_FUNC) {
933914 const extra = sym.extra(elf_file);
934915 const offset_table = self.offsetTablePtr().?;
......@@ -944,13 +925,6 @@ fn updateNavCode(
944925
945926 sym.value = 0;
946927 esym.st_value = 0;
947 if (stt_bits != elf.STT_FUNC) {
948 sym.flags.needs_zig_got = true;
949 if (!elf_file.base.isRelocatable()) {
950 const gop = try sym.getOrCreateZigGotEntry(sym_index, elf_file);
951 try elf_file.zig_got.writeOne(elf_file, gop.index);
952 }
953 }
954928 }
955929
956930 if (elf_file.base.child_pid) |pid| {
......@@ -1278,16 +1252,8 @@ fn updateLazySymbol(
12781252 errdefer self.freeNavMetadata(elf_file, symbol_index);
12791253
12801254 local_sym.value = 0;
1281 if (sym.kind != .code) {
1282 local_sym.flags.needs_zig_got = true;
1283 }
12841255 local_esym.st_value = 0;
12851256
1286 if (!elf_file.base.isRelocatable()) {
1287 const gop = try local_sym.getOrCreateZigGotEntry(symbol_index, elf_file);
1288 try elf_file.zig_got.writeOne(elf_file, gop.index);
1289 }
1290
12911257 const shdr = elf_file.shdrs.items[output_section_index];
12921258 const file_offset = shdr.sh_offset + @as(u64, @intCast(atom_ptr.value));
12931259 try elf_file.base.file.?.pwriteAll(code, file_offset);
src/link/Elf/relocation.zig-4
......@@ -113,10 +113,6 @@ fn formatRelocType(
113113 _ = options;
114114 const r_type = ctx.r_type;
115115 switch (r_type) {
116 Elf.R_ZIG_GOT32 => try writer.writeAll("R_ZIG_GOT32"),
117 Elf.R_ZIG_GOTPCREL => try writer.writeAll("R_ZIG_GOTPCREL"),
118 Elf.R_ZIG_GOT_HI20 => try writer.writeAll("R_ZIG_GOT_HI20"),
119 Elf.R_ZIG_GOT_LO12 => try writer.writeAll("R_ZIG_GOT_LO12"),
120116 Elf.R_GOT_HI20_STATIC => try writer.writeAll("R_GOT_HI20_STATIC"),
121117 Elf.R_GOT_LO12_I_STATIC => try writer.writeAll("R_GOT_LO12_I_STATIC"),
122118 else => switch (ctx.cpu_arch) {
src/link/Elf/synthetic_sections.zig-209
......@@ -223,215 +223,6 @@ pub const DynamicSection = struct {
223223 }
224224};
225225
226pub const ZigGotSection = struct {
227 entries: std.ArrayListUnmanaged(Symbol.Index) = .{},
228 output_symtab_ctx: Elf.SymtabCtx = .{},
229 flags: Flags = .{},
230
231 const Flags = packed struct {
232 needs_rela: bool = false,
233 dirty: bool = false,
234 };
235
236 pub const Index = u32;
237
238 pub fn deinit(zig_got: *ZigGotSection, allocator: Allocator) void {
239 zig_got.entries.deinit(allocator);
240 }
241
242 fn allocateEntry(zig_got: *ZigGotSection, allocator: Allocator) !Index {
243 try zig_got.entries.ensureUnusedCapacity(allocator, 1);
244 // TODO add free list
245 const index = @as(Index, @intCast(zig_got.entries.items.len));
246 _ = zig_got.entries.addOneAssumeCapacity();
247 zig_got.flags.dirty = true;
248 return index;
249 }
250
251 pub fn addSymbol(zig_got: *ZigGotSection, sym_index: Symbol.Index, elf_file: *Elf) !Index {
252 const comp = elf_file.base.comp;
253 const gpa = comp.gpa;
254 const zo = elf_file.zigObjectPtr().?;
255 const index = try zig_got.allocateEntry(gpa);
256 const entry = &zig_got.entries.items[index];
257 entry.* = sym_index;
258 const symbol = zo.symbol(sym_index);
259 symbol.flags.has_zig_got = true;
260 if (elf_file.isEffectivelyDynLib() or (elf_file.base.isExe() and comp.config.pie)) {
261 zig_got.flags.needs_rela = true;
262 }
263 symbol.addExtra(.{ .zig_got = index }, elf_file);
264 return index;
265 }
266
267 pub fn entryOffset(zig_got: ZigGotSection, index: Index, elf_file: *Elf) u64 {
268 _ = zig_got;
269 const entry_size = elf_file.archPtrWidthBytes();
270 const shdr = elf_file.shdrs.items[elf_file.zig_got_section_index.?];
271 return shdr.sh_offset + @as(u64, entry_size) * index;
272 }
273
274 pub fn entryAddress(zig_got: ZigGotSection, index: Index, elf_file: *Elf) i64 {
275 _ = zig_got;
276 const entry_size = elf_file.archPtrWidthBytes();
277 const shdr = elf_file.shdrs.items[elf_file.zig_got_section_index.?];
278 return @as(i64, @intCast(shdr.sh_addr)) + entry_size * index;
279 }
280
281 pub fn size(zig_got: ZigGotSection, elf_file: *Elf) usize {
282 return elf_file.archPtrWidthBytes() * zig_got.entries.items.len;
283 }
284
285 pub fn writeOne(zig_got: *ZigGotSection, elf_file: *Elf, index: Index) !void {
286 const zo = elf_file.zigObjectPtr().?;
287 if (zig_got.flags.dirty) {
288 const needed_size = zig_got.size(elf_file);
289 try elf_file.growAllocSection(elf_file.zig_got_section_index.?, needed_size);
290 zig_got.flags.dirty = false;
291 }
292 const entry_size: u16 = elf_file.archPtrWidthBytes();
293 const target = elf_file.getTarget();
294 const endian = target.cpu.arch.endian();
295 const off = zig_got.entryOffset(index, elf_file);
296 const vaddr: u64 = @intCast(zig_got.entryAddress(index, elf_file));
297 const entry = zig_got.entries.items[index];
298 const value = zo.symbol(entry).address(.{}, elf_file);
299 switch (entry_size) {
300 2 => {
301 var buf: [2]u8 = undefined;
302 std.mem.writeInt(u16, &buf, @intCast(value), endian);
303 try elf_file.base.file.?.pwriteAll(&buf, off);
304 },
305 4 => {
306 var buf: [4]u8 = undefined;
307 std.mem.writeInt(u32, &buf, @intCast(value), endian);
308 try elf_file.base.file.?.pwriteAll(&buf, off);
309 },
310 8 => {
311 var buf: [8]u8 = undefined;
312 std.mem.writeInt(u64, &buf, @intCast(value), endian);
313 try elf_file.base.file.?.pwriteAll(&buf, off);
314
315 if (elf_file.base.child_pid) |pid| {
316 switch (builtin.os.tag) {
317 .linux => {
318 var local_vec: [1]std.posix.iovec_const = .{.{
319 .base = &buf,
320 .len = buf.len,
321 }};
322 var remote_vec: [1]std.posix.iovec_const = .{.{
323 .base = @as([*]u8, @ptrFromInt(@as(usize, @intCast(vaddr)))),
324 .len = buf.len,
325 }};
326 const rc = std.os.linux.process_vm_writev(pid, &local_vec, &remote_vec, 0);
327 switch (std.os.linux.E.init(rc)) {
328 .SUCCESS => assert(rc == buf.len),
329 else => |errno| log.warn("process_vm_writev failure: {s}", .{@tagName(errno)}),
330 }
331 },
332 else => return error.HotSwapUnavailableOnHostOperatingSystem,
333 }
334 }
335 },
336 else => unreachable,
337 }
338 }
339
340 pub fn writeAll(zig_got: ZigGotSection, elf_file: *Elf, writer: anytype) !void {
341 const zo = elf_file.zigObjectPtr().?;
342 for (zig_got.entries.items) |entry| {
343 const symbol = zo.symbol(entry);
344 const value = symbol.address(.{ .plt = false }, elf_file);
345 try writeInt(value, elf_file, writer);
346 }
347 }
348
349 pub fn numRela(zig_got: ZigGotSection) usize {
350 return zig_got.entries.items.len;
351 }
352
353 pub fn addRela(zig_got: ZigGotSection, elf_file: *Elf) !void {
354 const comp = elf_file.base.comp;
355 const gpa = comp.gpa;
356 const cpu_arch = elf_file.getTarget().cpu.arch;
357 const zo = elf_file.zigObjectPtr().?;
358 try elf_file.rela_dyn.ensureUnusedCapacity(gpa, zig_got.numRela());
359 for (zig_got.entries.items) |entry| {
360 const symbol = zo.symbol(entry);
361 const offset = symbol.zigGotAddress(elf_file);
362 elf_file.addRelaDynAssumeCapacity(.{
363 .offset = @intCast(offset),
364 .type = relocation.encode(.rel, cpu_arch),
365 .addend = symbol.address(.{ .plt = false }, elf_file),
366 });
367 }
368 }
369
370 pub fn updateSymtabSize(zig_got: *ZigGotSection, elf_file: *Elf) void {
371 const zo = elf_file.zigObjectPtr().?;
372 zig_got.output_symtab_ctx.nlocals = @as(u32, @intCast(zig_got.entries.items.len));
373 for (zig_got.entries.items) |entry| {
374 const name = zo.symbol(entry).name(elf_file);
375 zig_got.output_symtab_ctx.strsize += @as(u32, @intCast(name.len + "$ziggot".len)) + 1;
376 }
377 }
378
379 pub fn writeSymtab(zig_got: ZigGotSection, elf_file: *Elf) void {
380 const zo = elf_file.zigObjectPtr().?;
381 for (zig_got.entries.items, zig_got.output_symtab_ctx.ilocal.., 0..) |entry, ilocal, index| {
382 const symbol = zo.symbol(entry);
383 const symbol_name = symbol.name(elf_file);
384 const st_name = @as(u32, @intCast(elf_file.strtab.items.len));
385 elf_file.strtab.appendSliceAssumeCapacity(symbol_name);
386 elf_file.strtab.appendSliceAssumeCapacity("$ziggot");
387 elf_file.strtab.appendAssumeCapacity(0);
388 const st_value = zig_got.entryAddress(@intCast(index), elf_file);
389 const st_size = elf_file.archPtrWidthBytes();
390 elf_file.symtab.items[ilocal] = .{
391 .st_name = st_name,
392 .st_info = elf.STT_OBJECT,
393 .st_other = 0,
394 .st_shndx = @intCast(elf_file.zig_got_section_index.?),
395 .st_value = @intCast(st_value),
396 .st_size = st_size,
397 };
398 }
399 }
400
401 const FormatCtx = struct {
402 zig_got: ZigGotSection,
403 elf_file: *Elf,
404 };
405
406 pub fn fmt(zig_got: ZigGotSection, elf_file: *Elf) std.fmt.Formatter(format2) {
407 return .{ .data = .{ .zig_got = zig_got, .elf_file = elf_file } };
408 }
409
410 pub fn format2(
411 ctx: FormatCtx,
412 comptime unused_fmt_string: []const u8,
413 options: std.fmt.FormatOptions,
414 writer: anytype,
415 ) !void {
416 _ = options;
417 _ = unused_fmt_string;
418 const zig_got = ctx.zig_got;
419 const elf_file = ctx.elf_file;
420 try writer.writeAll(".zig.got\n");
421 for (zig_got.entries.items, 0..) |entry, index| {
422 const zo = elf_file.zigObjectPtr().?;
423 const symbol = zo.symbol(entry);
424 try writer.print(" {d}@0x{x} => {d}@0x{x} ({s})\n", .{
425 index,
426 zig_got.entryAddress(@intCast(index), elf_file),
427 entry,
428 symbol.address(.{}, elf_file),
429 symbol.name(elf_file),
430 });
431 }
432 }
433};
434
435226pub const GotSection = struct {
436227 entries: std.ArrayListUnmanaged(Entry) = .{},
437228 output_symtab_ctx: Elf.SymtabCtx = .{},