diff --git a/src/arch/x86_64/Emit.zig b/src/arch/x86_64/Emit.zig index b6c1fbb968..b7d0a29c2d 100644 --- a/src/arch/x86_64/Emit.zig +++ b/src/arch/x86_64/Emit.zig @@ -110,21 +110,11 @@ pub fn emitMir(emit: *Emit) Error!void { }); }, .linker_reloc => |data| if (emit.lower.bin_file.cast(.elf)) |elf_file| { - const is_obj_or_static_lib = switch (emit.lower.output_mode) { - .Exe => false, - .Obj => true, - .Lib => emit.lower.link_mode == .static, - }; const zo = elf_file.zigObjectPtr().?; const atom = zo.symbol(data.atom_index).atom(elf_file).?; const sym = zo.symbol(data.sym_index); - if (sym.flags.needs_zig_got and !is_obj_or_static_lib) { - _ = try sym.getOrCreateZigGotEntry(data.sym_index, elf_file); - } if (emit.lower.pic) { - const r_type: u32 = if (sym.flags.needs_zig_got and !is_obj_or_static_lib) - link.File.Elf.R_ZIG_GOTPCREL - else if (sym.flags.needs_got) + const r_type: u32 = if (sym.flags.needs_got) @intFromEnum(std.elf.R_X86_64.GOTPCREL) else @intFromEnum(std.elf.R_X86_64.PC32); @@ -134,28 +124,17 @@ pub fn emitMir(emit: *Emit) Error!void { .r_addend = -4, }); } else { - if (lowered_inst.encoding.mnemonic == .call and sym.flags.needs_zig_got and is_obj_or_static_lib) { - const r_type = @intFromEnum(std.elf.R_X86_64.PC32); - try atom.addReloc(elf_file, .{ - .r_offset = end_offset - 4, - .r_info = (@as(u64, @intCast(data.sym_index)) << 32) | r_type, - .r_addend = -4, - }); - } else { - const r_type: u32 = if (sym.flags.needs_zig_got and !is_obj_or_static_lib) - link.File.Elf.R_ZIG_GOT32 - else if (sym.flags.needs_got) - @intFromEnum(std.elf.R_X86_64.GOT32) - else if (sym.flags.is_tls) - @intFromEnum(std.elf.R_X86_64.TPOFF32) - else - @intFromEnum(std.elf.R_X86_64.@"32"); - try atom.addReloc(elf_file, .{ - .r_offset = end_offset - 4, - .r_info = (@as(u64, @intCast(data.sym_index)) << 32) | r_type, - .r_addend = 0, - }); - } + const r_type: u32 = if (sym.flags.needs_got) + @intFromEnum(std.elf.R_X86_64.GOT32) + else if (sym.flags.is_tls) + @intFromEnum(std.elf.R_X86_64.TPOFF32) + else + @intFromEnum(std.elf.R_X86_64.@"32"); + try atom.addReloc(elf_file, .{ + .r_offset = end_offset - 4, + .r_info = (@as(u64, @intCast(data.sym_index)) << 32) | r_type, + .r_addend = 0, + }); } } else if (emit.lower.bin_file.cast(.macho)) |macho_file| { const is_obj_or_static_lib = switch (emit.lower.output_mode) { diff --git a/src/arch/x86_64/Lower.zig b/src/arch/x86_64/Lower.zig index 11fe279dd9..9ad1579ecc 100644 --- a/src/arch/x86_64/Lower.zig +++ b/src/arch/x86_64/Lower.zig @@ -398,30 +398,20 @@ fn emit(lower: *Lower, prefix: Prefix, mnemonic: Mnemonic, ops: []const Operand) _ = lower.reloc(.{ .linker_reloc = sym }); break :op if (lower.pic) switch (mnemonic) { - .lea => { - break :op .{ .mem = Memory.rip(mem_op.sib.ptr_size, 0) }; - }, - .mov => { - if (is_obj_or_static_lib and elf_sym.flags.needs_zig_got) emit_mnemonic = .lea; - break :op .{ .mem = Memory.rip(mem_op.sib.ptr_size, 0) }; - }, + .lea => break :op .{ .mem = Memory.rip(mem_op.sib.ptr_size, 0) }, + .mov => break :op .{ .mem = Memory.rip(mem_op.sib.ptr_size, 0) }, else => unreachable, } else switch (mnemonic) { - .call => break :op if (is_obj_or_static_lib and elf_sym.flags.needs_zig_got) .{ - .imm = Immediate.s(0), - } else .{ .mem = Memory.sib(mem_op.sib.ptr_size, .{ + .call => break :op .{ .mem = Memory.sib(mem_op.sib.ptr_size, .{ .base = .{ .reg = .ds }, }) }, .lea => { emit_mnemonic = .mov; break :op .{ .imm = Immediate.s(0) }; }, - .mov => { - if (is_obj_or_static_lib and elf_sym.flags.needs_zig_got) emit_mnemonic = .lea; - break :op .{ .mem = Memory.sib(mem_op.sib.ptr_size, .{ - .base = .{ .reg = .ds }, - }) }; - }, + .mov => break :op .{ .mem = Memory.sib(mem_op.sib.ptr_size, .{ + .base = .{ .reg = .ds }, + }) }, else => unreachable, }; } else if (lower.bin_file.cast(.macho)) |macho_file| { diff --git a/src/link/Elf.zig b/src/link/Elf.zig index ffba511e87..ebafd16d6d 100644 --- a/src/link/Elf.zig +++ b/src/link/Elf.zig @@ -64,9 +64,6 @@ phdrs: std.ArrayListUnmanaged(elf.Elf64_Phdr) = .{}, /// Tracked loadable segments during incremental linking. /// The index into the program headers of a PT_LOAD program header with Read and Execute flags phdr_zig_load_re_index: ?u16 = null, -/// The index into the program headers of the global offset table. -/// It needs PT_LOAD and Read flags. -phdr_zig_got_index: ?u16 = null, /// The index into the program headers of a PT_LOAD program header with Read flag phdr_zig_load_ro_index: ?u16 = null, /// The index into the program headers of a PT_LOAD program header with Write flag @@ -130,8 +127,6 @@ plt_got: PltGotSection = .{}, copy_rel: CopyRelSection = .{}, /// .rela.plt section rela_plt: std.ArrayListUnmanaged(elf.Elf64_Rela) = .{}, -/// .got.zig section -zig_got: ZigGotSection = .{}, /// SHT_GROUP sections /// Applies only to a relocatable. comdat_group_sections: std.ArrayListUnmanaged(ComdatGroupSection) = .{}, @@ -142,7 +137,6 @@ zig_text_section_index: ?u32 = null, zig_data_rel_ro_section_index: ?u32 = null, zig_data_section_index: ?u32 = null, zig_bss_section_index: ?u32 = null, -zig_got_section_index: ?u32 = null, debug_info_section_index: ?u32 = null, debug_abbrev_section_index: ?u32 = null, @@ -474,7 +468,6 @@ pub fn deinit(self: *Elf) void { self.copy_rel.deinit(gpa); self.rela_dyn.deinit(gpa); self.rela_plt.deinit(gpa); - self.zig_got.deinit(gpa); self.comdat_group_sections.deinit(gpa); } @@ -618,21 +611,6 @@ pub fn initMetadata(self: *Elf, options: InitMetadataOptions) !void { }); } - if (self.phdr_zig_got_index == null) { - const alignment = self.page_size; - const filesz = @as(u64, ptr_size) * options.symbol_count_hint; - const off = self.findFreeSpace(filesz, alignment); - self.phdr_zig_got_index = try self.addPhdr(.{ - .type = elf.PT_LOAD, - .offset = off, - .filesz = filesz, - .addr = if (ptr_bit_width >= 32) 0x4000000 else 0x4000, - .memsz = filesz, - .@"align" = alignment, - .flags = elf.PF_R | elf.PF_W, - }); - } - if (self.phdr_zig_load_ro_index == null) { const alignment = self.page_size; const filesz: u64 = 1024; @@ -701,27 +679,6 @@ pub fn initMetadata(self: *Elf, options: InitMetadataOptions) !void { try self.last_atom_and_free_list_table.putNoClobber(gpa, self.zig_text_section_index.?, .{}); } - if (self.zig_got_section_index == null and !self.base.isRelocatable()) { - self.zig_got_section_index = try self.addSection(.{ - .name = try self.insertShString(".got.zig"), - .type = elf.SHT_PROGBITS, - .addralign = ptr_size, - .flags = elf.SHF_ALLOC | elf.SHF_WRITE, - .offset = std.math.maxInt(u64), - }); - const shdr = &self.shdrs.items[self.zig_got_section_index.?]; - const phndx = self.phdr_zig_got_index.?; - const phdr = self.phdrs.items[phndx]; - shdr.sh_addr = phdr.p_vaddr; - shdr.sh_offset = phdr.p_offset; - shdr.sh_size = phdr.p_memsz; - try self.phdr_to_shdr_table.putNoClobber( - gpa, - self.zig_got_section_index.?, - self.phdr_zig_got_index.?, - ); - } - if (self.zig_data_rel_ro_section_index == null) { self.zig_data_rel_ro_section_index = try self.addSection(.{ .name = try self.insertShString(".data.rel.ro.zig"), @@ -3156,8 +3113,8 @@ fn initSyntheticSections(self: *Elf) !void { }); const needs_rela_dyn = blk: { - if (self.got.flags.needs_rela or self.got.flags.needs_tlsld or - self.zig_got.flags.needs_rela or self.copy_rel.symbols.items.len > 0) break :blk true; + if (self.got.flags.needs_rela or self.got.flags.needs_tlsld or self.copy_rel.symbols.items.len > 0) + break :blk true; if (self.zigObjectPtr()) |zig_object| { if (zig_object.num_dynrelocs > 0) break :blk true; } @@ -3562,7 +3519,6 @@ fn sortPhdrs(self: *Elf) error{OutOfMemory}!void { for (&[_]*?u16{ &self.phdr_zig_load_re_index, - &self.phdr_zig_got_index, &self.phdr_zig_load_ro_index, &self.phdr_zig_load_zerofill_index, &self.phdr_table_index, @@ -3694,7 +3650,6 @@ fn resetShdrIndexes(self: *Elf, backlinks: []const u32) !void { &self.versym_section_index, &self.verneed_section_index, &self.zig_text_section_index, - &self.zig_got_section_index, &self.zig_data_rel_ro_section_index, &self.zig_data_section_index, &self.zig_bss_section_index, @@ -3893,7 +3848,7 @@ fn updateSectionSizes(self: *Elf) !void { } if (self.rela_dyn_section_index) |shndx| { - var num = self.got.numRela(self) + self.copy_rel.numRela() + self.zig_got.numRela(); + var num = self.got.numRela(self) + self.copy_rel.numRela(); if (self.zigObjectPtr()) |zig_object| { num += zig_object.num_dynrelocs; } @@ -4431,15 +4386,6 @@ pub fn updateSymtabSize(self: *Elf) !void { strsize += ctx.strsize; } - if (self.zigObjectPtr()) |_| { - if (self.zig_got_section_index) |_| { - self.zig_got.output_symtab_ctx.ilocal = nlocals + 1; - self.zig_got.updateSymtabSize(self); - nlocals += self.zig_got.output_symtab_ctx.nlocals; - strsize += self.zig_got.output_symtab_ctx.strsize; - } - } - if (self.got_section_index) |_| { self.got.output_symtab_ctx.ilocal = nlocals + 1; self.got.updateSymtabSize(self); @@ -4576,9 +4522,6 @@ fn writeSyntheticSections(self: *Elf) !void { const shdr = self.shdrs.items[shndx]; try self.got.addRela(self); try self.copy_rel.addRela(self); - if (self.zigObjectPtr()) |_| { - try self.zig_got.addRela(self); - } self.sortRelaDyn(); try self.base.file.?.pwriteAll(mem.sliceAsBytes(self.rela_dyn.items), shdr.sh_offset); } @@ -4674,10 +4617,6 @@ pub fn writeSymtab(self: *Elf) !void { obj.asFile().writeSymtab(self); } - if (self.zig_got_section_index) |_| { - self.zig_got.writeSymtab(self); - } - if (self.got_section_index) |_| { self.got.writeSymtab(self); } @@ -5085,7 +5024,6 @@ pub fn isZigSection(self: Elf, shndx: u32) bool { self.zig_data_rel_ro_section_index, self.zig_data_section_index, self.zig_bss_section_index, - self.zig_got_section_index, }) |maybe_index| { if (maybe_index) |index| { if (index == shndx) return true; @@ -5704,7 +5642,6 @@ fn fmtDumpState( } } - try writer.print("{}\n", .{self.zig_got.fmt(self)}); try writer.print("{}\n", .{self.got.fmt(self)}); try writer.print("{}\n", .{self.plt.fmt(self)}); @@ -5995,20 +5932,12 @@ const RelaSection = struct { }; const RelaSectionTable = std.AutoArrayHashMapUnmanaged(u32, RelaSection); -pub const R_ZIG_GOT32: u32 = 0xff00; -pub const R_ZIG_GOTPCREL: u32 = 0xff01; -pub const R_ZIG_GOT_HI20: u32 = 0xff02; -pub const R_ZIG_GOT_LO12: u32 = 0xff03; pub const R_GOT_HI20_STATIC: u32 = 0xff04; pub const R_GOT_LO12_I_STATIC: u32 = 0xff05; // Comptime asserts that no Zig relocs overlap with another ISA's reloc number comptime { const zig_relocs = .{ - R_ZIG_GOT32, - R_ZIG_GOT_HI20, - R_ZIG_GOT_LO12, - R_ZIG_GOTPCREL, R_GOT_HI20_STATIC, R_GOT_LO12_I_STATIC, }; @@ -6099,6 +6028,5 @@ const StringTable = @import("StringTable.zig"); const Thunk = thunks.Thunk; const Value = @import("../Value.zig"); const VerneedSection = synthetic_sections.VerneedSection; -const ZigGotSection = synthetic_sections.ZigGotSection; const ZigObject = @import("Elf/ZigObject.zig"); const riscv = @import("riscv.zig"); diff --git a/src/link/Elf/Atom.zig b/src/link/Elf/Atom.zig index b5db642c40..cb505b19e3 100644 --- a/src/link/Elf/Atom.zig +++ b/src/link/Elf/Atom.zig @@ -750,8 +750,8 @@ pub fn resolveRelocsAlloc(self: Atom, elf_file: *Elf, code: []u8) RelocError!voi const S = target.address(.{}, elf_file); // Address of the global offset table. const GOT = elf_file.gotAddress(); - // Address of the .zig.got table entry if any. - const ZIG_GOT = target.zigGotAddress(elf_file); + // Address of the offset table entry if any. + const ZIG_GOT = target.zigOffsetTableAddress(elf_file); // Relative offset to the start of the global offset table. const G = target.gotAddress(elf_file) - GOT; // // Address of the thread pointer. @@ -759,14 +759,13 @@ pub fn resolveRelocsAlloc(self: Atom, elf_file: *Elf, code: []u8) RelocError!voi // Address of the dynamic thread pointer. const DTP = elf_file.dtpAddress(); - relocs_log.debug(" {s}: {x}: [{x} => {x}] G({x}) ZG({x}) ZG2({x}) ({s})", .{ + relocs_log.debug(" {s}: {x}: [{x} => {x}] G({x}) ZG({x}) ({s})", .{ relocation.fmtRelocType(rel.r_type(), cpu_arch), r_offset, P, S + A, G + GOT + A, ZIG_GOT + A, - target.zigOffsetTableAddress(elf_file) + A, target.name(elf_file), }); @@ -1181,16 +1180,7 @@ const x86_64 = struct { .TLSDESC_CALL, => {}, - else => |x| switch (@intFromEnum(x)) { - // Zig custom relocations - Elf.R_ZIG_GOT32, - Elf.R_ZIG_GOTPCREL, - => { - assert(symbol.flags.has_zig_got); - }, - - else => try atom.reportUnhandledRelocError(rel, elf_file), - }, + else => try atom.reportUnhandledRelocError(rel, elf_file), } } @@ -1228,7 +1218,7 @@ const x86_64 = struct { .PLT32 => try cwriter.writeInt(i32, @as(i32, @intCast(S + A - P)), .little), .PC32 => { - const S_ = if (target.flags.zig_offset_table) target.zigOffsetTableAddress(elf_file) else S; + const S_ = if (target.flags.zig_offset_table) ZIG_GOT else S; try cwriter.writeInt(i32, @as(i32, @intCast(S_ + A - P)), .little); }, @@ -1255,7 +1245,7 @@ const x86_64 = struct { }, .@"32" => { - const S_ = if (target.flags.zig_offset_table) target.zigOffsetTableAddress(elf_file) else S; + const S_ = if (target.flags.zig_offset_table) ZIG_GOT else S; try cwriter.writeInt(u32, @as(u32, @truncate(@as(u64, @intCast(S_ + A)))), .little); }, .@"32S" => try cwriter.writeInt(i32, @as(i32, @truncate(S + A)), .little), @@ -1336,13 +1326,7 @@ const x86_64 = struct { .GOT32 => try cwriter.writeInt(i32, @as(i32, @intCast(G + GOT + A)), .little), - else => |x| switch (@intFromEnum(x)) { - // Zig custom relocations - Elf.R_ZIG_GOT32 => try cwriter.writeInt(u32, @as(u32, @intCast(ZIG_GOT + A)), .little), - Elf.R_ZIG_GOTPCREL => try cwriter.writeInt(i32, @as(i32, @intCast(ZIG_GOT + A - P)), .little), - - else => try atom.reportUnhandledRelocError(rel, elf_file), - }, + else => try atom.reportUnhandledRelocError(rel, elf_file), } } @@ -2006,12 +1990,6 @@ const riscv = struct { => {}, else => |x| switch (@intFromEnum(x)) { - Elf.R_ZIG_GOT_HI20, - Elf.R_ZIG_GOT_LO12, - => { - assert(symbol.flags.has_zig_got); - }, - Elf.R_GOT_HI20_STATIC, Elf.R_GOT_LO12_I_STATIC, => symbol.flags.needs_got = true, @@ -2038,6 +2016,7 @@ const riscv = struct { const P, const A, const S, const GOT, const G, const TP, const DTP, const ZIG_GOT = args; _ = TP; _ = DTP; + _ = ZIG_GOT; switch (r_type) { .NONE => unreachable, @@ -2156,18 +2135,6 @@ const riscv = struct { else => |x| switch (@intFromEnum(x)) { // Zig custom relocations - Elf.R_ZIG_GOT_HI20 => { - assert(target.flags.has_zig_got); - const disp: u32 = @bitCast(math.cast(i32, ZIG_GOT + A) orelse return error.Overflow); - riscv_util.writeInstU(code[r_offset..][0..4], disp); - }, - - Elf.R_ZIG_GOT_LO12 => { - assert(target.flags.has_zig_got); - const value: u32 = @bitCast(math.cast(i32, ZIG_GOT + A) orelse return error.Overflow); - riscv_util.writeInstI(code[r_offset..][0..4], value); - }, - Elf.R_GOT_HI20_STATIC => { assert(target.flags.has_got); const disp: u32 = @bitCast(math.cast(i32, G + GOT + A) orelse return error.Overflow); diff --git a/src/link/Elf/Symbol.zig b/src/link/Elf/Symbol.zig index cf285b12d0..20697a0426 100644 --- a/src/link/Elf/Symbol.zig +++ b/src/link/Elf/Symbol.zig @@ -217,25 +217,6 @@ pub fn tlsDescAddress(symbol: Symbol, elf_file: *Elf) i64 { return entry.address(elf_file); } -const GetOrCreateZigGotEntryResult = struct { - found_existing: bool, - index: ZigGotSection.Index, -}; - -pub fn getOrCreateZigGotEntry(symbol: *Symbol, symbol_index: Index, elf_file: *Elf) !GetOrCreateZigGotEntryResult { - assert(!elf_file.base.isRelocatable()); - assert(symbol.flags.needs_zig_got); - if (symbol.flags.has_zig_got) return .{ .found_existing = true, .index = symbol.extra(elf_file).zig_got }; - const index = try elf_file.zig_got.addSymbol(symbol_index, elf_file); - return .{ .found_existing = false, .index = index }; -} - -pub fn zigGotAddress(symbol: Symbol, elf_file: *Elf) i64 { - if (!symbol.flags.has_zig_got) return 0; - const extras = symbol.extra(elf_file); - return elf_file.zig_got.entryAddress(extras.zig_got, elf_file); -} - pub fn zigOffsetTableAddress(symbol: Symbol, elf_file: *Elf) i64 { if (!symbol.flags.zig_offset_table) return 0; const zo = elf_file.zigObjectPtr().?; @@ -267,7 +248,6 @@ const AddExtraOpts = struct { tlsgd: ?u32 = null, gottp: ?u32 = null, tlsdesc: ?u32 = null, - zig_got: ?u32 = null, zig_offset_table: ?u32 = null, }; @@ -465,10 +445,6 @@ pub const Flags = packed struct { needs_tlsdesc: bool = false, has_tlsdesc: bool = false, - /// Whether the symbol contains .zig.got indirection. - needs_zig_got: bool = false, - has_zig_got: bool = false, - /// Whether the symbol is a TLS variable. /// TODO this is really not needed if only we operated on esyms between /// codegen and ZigObject. @@ -491,7 +467,6 @@ pub const Extra = struct { tlsgd: u32 = 0, gottp: u32 = 0, tlsdesc: u32 = 0, - zig_got: u32 = 0, merge_section: u32 = 0, zig_offset_table: u32 = 0, }; diff --git a/src/link/Elf/ZigObject.zig b/src/link/Elf/ZigObject.zig index f426e43c0a..107ab78385 100644 --- a/src/link/Elf/ZigObject.zig +++ b/src/link/Elf/ZigObject.zig @@ -756,15 +756,7 @@ pub fn getOrCreateMetadataForLazySymbol( .const_data => .{ &gop.value_ptr.rodata_symbol_index, &gop.value_ptr.rodata_state }, }; switch (state_ptr.*) { - .unused => { - const gpa = elf_file.base.comp.gpa; - const symbol_index = try self.newSymbolWithAtom(gpa, 0); - const sym = self.symbol(symbol_index); - if (lazy_sym.kind != .code) { - sym.flags.needs_zig_got = true; - } - symbol_index_ptr.* = symbol_index; - }, + .unused => symbol_index_ptr.* = try self.newSymbolWithAtom(pt.zcu.gpa, 0), .pending_flush => return symbol_index_ptr.*, .flushed => {}, } @@ -818,9 +810,6 @@ pub fn getOrCreateMetadataForNav( sym.flags.is_tls = true; } } - if (!sym.flags.is_tls and nav_val.typeOf(zcu).zigTypeTag(zcu) != .Fn) { - sym.flags.needs_zig_got = true; - } gop.value_ptr.* = .{ .symbol_index = symbol_index }; } return gop.value_ptr.symbol_index; @@ -921,14 +910,6 @@ fn updateNavCode( sym.value = 0; esym.st_value = 0; - if (stt_bits != elf.STT_FUNC) { - if (!elf_file.base.isRelocatable()) { - log.debug(" (writing new offset table entry)", .{}); - assert(sym.flags.has_zig_got); - const extra = sym.extra(elf_file); - try elf_file.zig_got.writeOne(elf_file, extra.zig_got); - } - } if (stt_bits == elf.STT_FUNC) { const extra = sym.extra(elf_file); const offset_table = self.offsetTablePtr().?; @@ -944,13 +925,6 @@ fn updateNavCode( sym.value = 0; esym.st_value = 0; - if (stt_bits != elf.STT_FUNC) { - sym.flags.needs_zig_got = true; - if (!elf_file.base.isRelocatable()) { - const gop = try sym.getOrCreateZigGotEntry(sym_index, elf_file); - try elf_file.zig_got.writeOne(elf_file, gop.index); - } - } } if (elf_file.base.child_pid) |pid| { @@ -1278,16 +1252,8 @@ fn updateLazySymbol( errdefer self.freeNavMetadata(elf_file, symbol_index); local_sym.value = 0; - if (sym.kind != .code) { - local_sym.flags.needs_zig_got = true; - } local_esym.st_value = 0; - if (!elf_file.base.isRelocatable()) { - const gop = try local_sym.getOrCreateZigGotEntry(symbol_index, elf_file); - try elf_file.zig_got.writeOne(elf_file, gop.index); - } - const shdr = elf_file.shdrs.items[output_section_index]; const file_offset = shdr.sh_offset + @as(u64, @intCast(atom_ptr.value)); try elf_file.base.file.?.pwriteAll(code, file_offset); diff --git a/src/link/Elf/relocation.zig b/src/link/Elf/relocation.zig index 5f6810d6f9..887aece8bc 100644 --- a/src/link/Elf/relocation.zig +++ b/src/link/Elf/relocation.zig @@ -113,10 +113,6 @@ fn formatRelocType( _ = options; const r_type = ctx.r_type; switch (r_type) { - Elf.R_ZIG_GOT32 => try writer.writeAll("R_ZIG_GOT32"), - Elf.R_ZIG_GOTPCREL => try writer.writeAll("R_ZIG_GOTPCREL"), - Elf.R_ZIG_GOT_HI20 => try writer.writeAll("R_ZIG_GOT_HI20"), - Elf.R_ZIG_GOT_LO12 => try writer.writeAll("R_ZIG_GOT_LO12"), Elf.R_GOT_HI20_STATIC => try writer.writeAll("R_GOT_HI20_STATIC"), Elf.R_GOT_LO12_I_STATIC => try writer.writeAll("R_GOT_LO12_I_STATIC"), else => switch (ctx.cpu_arch) { diff --git a/src/link/Elf/synthetic_sections.zig b/src/link/Elf/synthetic_sections.zig index e1ec90139e..40cb37b967 100644 --- a/src/link/Elf/synthetic_sections.zig +++ b/src/link/Elf/synthetic_sections.zig @@ -223,215 +223,6 @@ pub const DynamicSection = struct { } }; -pub const ZigGotSection = struct { - entries: std.ArrayListUnmanaged(Symbol.Index) = .{}, - output_symtab_ctx: Elf.SymtabCtx = .{}, - flags: Flags = .{}, - - const Flags = packed struct { - needs_rela: bool = false, - dirty: bool = false, - }; - - pub const Index = u32; - - pub fn deinit(zig_got: *ZigGotSection, allocator: Allocator) void { - zig_got.entries.deinit(allocator); - } - - fn allocateEntry(zig_got: *ZigGotSection, allocator: Allocator) !Index { - try zig_got.entries.ensureUnusedCapacity(allocator, 1); - // TODO add free list - const index = @as(Index, @intCast(zig_got.entries.items.len)); - _ = zig_got.entries.addOneAssumeCapacity(); - zig_got.flags.dirty = true; - return index; - } - - pub fn addSymbol(zig_got: *ZigGotSection, sym_index: Symbol.Index, elf_file: *Elf) !Index { - const comp = elf_file.base.comp; - const gpa = comp.gpa; - const zo = elf_file.zigObjectPtr().?; - const index = try zig_got.allocateEntry(gpa); - const entry = &zig_got.entries.items[index]; - entry.* = sym_index; - const symbol = zo.symbol(sym_index); - symbol.flags.has_zig_got = true; - if (elf_file.isEffectivelyDynLib() or (elf_file.base.isExe() and comp.config.pie)) { - zig_got.flags.needs_rela = true; - } - symbol.addExtra(.{ .zig_got = index }, elf_file); - return index; - } - - pub fn entryOffset(zig_got: ZigGotSection, index: Index, elf_file: *Elf) u64 { - _ = zig_got; - const entry_size = elf_file.archPtrWidthBytes(); - const shdr = elf_file.shdrs.items[elf_file.zig_got_section_index.?]; - return shdr.sh_offset + @as(u64, entry_size) * index; - } - - pub fn entryAddress(zig_got: ZigGotSection, index: Index, elf_file: *Elf) i64 { - _ = zig_got; - const entry_size = elf_file.archPtrWidthBytes(); - const shdr = elf_file.shdrs.items[elf_file.zig_got_section_index.?]; - return @as(i64, @intCast(shdr.sh_addr)) + entry_size * index; - } - - pub fn size(zig_got: ZigGotSection, elf_file: *Elf) usize { - return elf_file.archPtrWidthBytes() * zig_got.entries.items.len; - } - - pub fn writeOne(zig_got: *ZigGotSection, elf_file: *Elf, index: Index) !void { - const zo = elf_file.zigObjectPtr().?; - if (zig_got.flags.dirty) { - const needed_size = zig_got.size(elf_file); - try elf_file.growAllocSection(elf_file.zig_got_section_index.?, needed_size); - zig_got.flags.dirty = false; - } - const entry_size: u16 = elf_file.archPtrWidthBytes(); - const target = elf_file.getTarget(); - const endian = target.cpu.arch.endian(); - const off = zig_got.entryOffset(index, elf_file); - const vaddr: u64 = @intCast(zig_got.entryAddress(index, elf_file)); - const entry = zig_got.entries.items[index]; - const value = zo.symbol(entry).address(.{}, elf_file); - switch (entry_size) { - 2 => { - var buf: [2]u8 = undefined; - std.mem.writeInt(u16, &buf, @intCast(value), endian); - try elf_file.base.file.?.pwriteAll(&buf, off); - }, - 4 => { - var buf: [4]u8 = undefined; - std.mem.writeInt(u32, &buf, @intCast(value), endian); - try elf_file.base.file.?.pwriteAll(&buf, off); - }, - 8 => { - var buf: [8]u8 = undefined; - std.mem.writeInt(u64, &buf, @intCast(value), endian); - try elf_file.base.file.?.pwriteAll(&buf, off); - - if (elf_file.base.child_pid) |pid| { - switch (builtin.os.tag) { - .linux => { - var local_vec: [1]std.posix.iovec_const = .{.{ - .base = &buf, - .len = buf.len, - }}; - var remote_vec: [1]std.posix.iovec_const = .{.{ - .base = @as([*]u8, @ptrFromInt(@as(usize, @intCast(vaddr)))), - .len = buf.len, - }}; - const rc = std.os.linux.process_vm_writev(pid, &local_vec, &remote_vec, 0); - switch (std.os.linux.E.init(rc)) { - .SUCCESS => assert(rc == buf.len), - else => |errno| log.warn("process_vm_writev failure: {s}", .{@tagName(errno)}), - } - }, - else => return error.HotSwapUnavailableOnHostOperatingSystem, - } - } - }, - else => unreachable, - } - } - - pub fn writeAll(zig_got: ZigGotSection, elf_file: *Elf, writer: anytype) !void { - const zo = elf_file.zigObjectPtr().?; - for (zig_got.entries.items) |entry| { - const symbol = zo.symbol(entry); - const value = symbol.address(.{ .plt = false }, elf_file); - try writeInt(value, elf_file, writer); - } - } - - pub fn numRela(zig_got: ZigGotSection) usize { - return zig_got.entries.items.len; - } - - pub fn addRela(zig_got: ZigGotSection, elf_file: *Elf) !void { - const comp = elf_file.base.comp; - const gpa = comp.gpa; - const cpu_arch = elf_file.getTarget().cpu.arch; - const zo = elf_file.zigObjectPtr().?; - try elf_file.rela_dyn.ensureUnusedCapacity(gpa, zig_got.numRela()); - for (zig_got.entries.items) |entry| { - const symbol = zo.symbol(entry); - const offset = symbol.zigGotAddress(elf_file); - elf_file.addRelaDynAssumeCapacity(.{ - .offset = @intCast(offset), - .type = relocation.encode(.rel, cpu_arch), - .addend = symbol.address(.{ .plt = false }, elf_file), - }); - } - } - - pub fn updateSymtabSize(zig_got: *ZigGotSection, elf_file: *Elf) void { - const zo = elf_file.zigObjectPtr().?; - zig_got.output_symtab_ctx.nlocals = @as(u32, @intCast(zig_got.entries.items.len)); - for (zig_got.entries.items) |entry| { - const name = zo.symbol(entry).name(elf_file); - zig_got.output_symtab_ctx.strsize += @as(u32, @intCast(name.len + "$ziggot".len)) + 1; - } - } - - pub fn writeSymtab(zig_got: ZigGotSection, elf_file: *Elf) void { - const zo = elf_file.zigObjectPtr().?; - for (zig_got.entries.items, zig_got.output_symtab_ctx.ilocal.., 0..) |entry, ilocal, index| { - const symbol = zo.symbol(entry); - const symbol_name = symbol.name(elf_file); - const st_name = @as(u32, @intCast(elf_file.strtab.items.len)); - elf_file.strtab.appendSliceAssumeCapacity(symbol_name); - elf_file.strtab.appendSliceAssumeCapacity("$ziggot"); - elf_file.strtab.appendAssumeCapacity(0); - const st_value = zig_got.entryAddress(@intCast(index), elf_file); - const st_size = elf_file.archPtrWidthBytes(); - elf_file.symtab.items[ilocal] = .{ - .st_name = st_name, - .st_info = elf.STT_OBJECT, - .st_other = 0, - .st_shndx = @intCast(elf_file.zig_got_section_index.?), - .st_value = @intCast(st_value), - .st_size = st_size, - }; - } - } - - const FormatCtx = struct { - zig_got: ZigGotSection, - elf_file: *Elf, - }; - - pub fn fmt(zig_got: ZigGotSection, elf_file: *Elf) std.fmt.Formatter(format2) { - return .{ .data = .{ .zig_got = zig_got, .elf_file = elf_file } }; - } - - pub fn format2( - ctx: FormatCtx, - comptime unused_fmt_string: []const u8, - options: std.fmt.FormatOptions, - writer: anytype, - ) !void { - _ = options; - _ = unused_fmt_string; - const zig_got = ctx.zig_got; - const elf_file = ctx.elf_file; - try writer.writeAll(".zig.got\n"); - for (zig_got.entries.items, 0..) |entry, index| { - const zo = elf_file.zigObjectPtr().?; - const symbol = zo.symbol(entry); - try writer.print(" {d}@0x{x} => {d}@0x{x} ({s})\n", .{ - index, - zig_got.entryAddress(@intCast(index), elf_file), - entry, - symbol.address(.{}, elf_file), - symbol.name(elf_file), - }); - } - } -}; - pub const GotSection = struct { entries: std.ArrayListUnmanaged(Entry) = .{}, output_symtab_ctx: Elf.SymtabCtx = .{},