diff --git a/src/link/Elf.zig b/src/link/Elf.zig index ebafd16d6d5e8740543630665b758e8f85e7ee65..f4003ff38fbd94e72efb7a3220e05e909a4f83d2 100644 --- a/src/link/Elf.zig +++ b/src/link/Elf.zig @@ -5599,8 +5599,8 @@ fn fmtDumpState( zig_object.fmtAtoms(self), zig_object.fmtSymtab(self), }); - if (zig_object.offset_table) |ot| { - try writer.print("{}", .{ot.fmt(zig_object, self)}); + if (zig_object.jump_table) |jt| { + try writer.print("{}", .{jt.fmt(zig_object, self)}); } try writer.writeByte('\n'); } diff --git a/src/link/Elf/Atom.zig b/src/link/Elf/Atom.zig index cb505b19e39551cea89b8a23863445d2a166ad3d..31ba0d642e22cf79bd140b487575ce40484c2c37 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 offset table entry if any. - const ZIG_GOT = target.zigOffsetTableAddress(elf_file); + // Address of the zig jump table entry if any. + const ZJT = target.zigJumpTableAddress(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,19 +759,19 @@ 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}) ({s})", .{ + relocs_log.debug(" {s}: {x}: [{x} => {x}] GOT({x}) ZJT({x}) ({s})", .{ relocation.fmtRelocType(rel.r_type(), cpu_arch), r_offset, P, S + A, G + GOT + A, - ZIG_GOT + A, + ZJT + A, target.name(elf_file), }); try stream.seekTo(r_offset); - const args = ResolveArgs{ P, A, S, GOT, G, TP, DTP, ZIG_GOT }; + const args = ResolveArgs{ P, A, S, GOT, G, TP, DTP, ZJT }; switch (cpu_arch) { .x86_64 => x86_64.resolveRelocAlloc(self, elf_file, rel, target, args, &it, code, &stream) catch |err| switch (err) { @@ -1200,7 +1200,7 @@ const x86_64 = struct { const cwriter = stream.writer(); - const P, const A, const S, const GOT, const G, const TP, const DTP, const ZIG_GOT = args; + const P, const A, const S, const GOT, const G, const TP, const DTP, const ZJT = args; switch (r_type) { .NONE => unreachable, @@ -1218,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) ZIG_GOT else S; + const S_ = if (target.flags.zig_jump_table) ZJT else S; try cwriter.writeInt(i32, @as(i32, @intCast(S_ + A - P)), .little); }, @@ -1245,7 +1245,7 @@ const x86_64 = struct { }, .@"32" => { - const S_ = if (target.flags.zig_offset_table) ZIG_GOT else S; + const S_ = if (target.flags.zig_jump_table) ZJT 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), @@ -1729,9 +1729,9 @@ const aarch64 = struct { const code = code_buffer[r_offset..][0..4]; const file_ptr = atom.file(elf_file).?; - const P, const A, const S, const GOT, const G, const TP, const DTP, const ZIG_GOT = args; + const P, const A, const S, const GOT, const G, const TP, const DTP, const ZJT = args; _ = DTP; - _ = ZIG_GOT; + _ = ZJT; switch (r_type) { .NONE => unreachable, @@ -2013,10 +2013,10 @@ const riscv = struct { const r_offset = std.math.cast(usize, rel.r_offset) orelse return error.Overflow; const cwriter = stream.writer(); - const P, const A, const S, const GOT, const G, const TP, const DTP, const ZIG_GOT = args; + const P, const A, const S, const GOT, const G, const TP, const DTP, const ZJT = args; _ = TP; _ = DTP; - _ = ZIG_GOT; + _ = ZJT; switch (r_type) { .NONE => unreachable, diff --git a/src/link/Elf/Symbol.zig b/src/link/Elf/Symbol.zig index 20697a0426b26e6c3f10ead4054519357281091a..38ef6bb8f7826483bd2e6093884f1c748fac9469 100644 --- a/src/link/Elf/Symbol.zig +++ b/src/link/Elf/Symbol.zig @@ -217,12 +217,12 @@ pub fn tlsDescAddress(symbol: Symbol, elf_file: *Elf) i64 { return entry.address(elf_file); } -pub fn zigOffsetTableAddress(symbol: Symbol, elf_file: *Elf) i64 { - if (!symbol.flags.zig_offset_table) return 0; +pub fn zigJumpTableAddress(symbol: Symbol, elf_file: *Elf) i64 { + if (!symbol.flags.zig_jump_table) return 0; const zo = elf_file.zigObjectPtr().?; - const offset_table = zo.offsetTablePtr().?; - const ot_index = symbol.extra(elf_file).zig_offset_table; - return offset_table.entryAddress(ot_index, zo, elf_file); + const jump_table = zo.jumpTablePtr().?; + const jt_index = symbol.extra(elf_file).zig_jump_table; + return jump_table.entryAddress(jt_index, zo, elf_file); } pub fn dsoAlignment(symbol: Symbol, elf_file: *Elf) !u64 { @@ -248,7 +248,7 @@ const AddExtraOpts = struct { tlsgd: ?u32 = null, gottp: ?u32 = null, tlsdesc: ?u32 = null, - zig_offset_table: ?u32 = null, + zig_jump_table: ?u32 = null, }; pub fn addExtra(symbol: *Symbol, opts: AddExtraOpts, elf_file: *Elf) void { @@ -453,8 +453,8 @@ pub const Flags = packed struct { /// Whether the symbol is a merge subsection. merge_subsection: bool = false, - /// Whether the symbol has __zig_offset_table indirection. - zig_offset_table: bool = false, + /// Whether the symbol has __zig_jump_table indirection. + zig_jump_table: bool = false, }; pub const Extra = struct { @@ -468,7 +468,7 @@ pub const Extra = struct { gottp: u32 = 0, tlsdesc: u32 = 0, merge_section: u32 = 0, - zig_offset_table: u32 = 0, + zig_jump_table: u32 = 0, }; pub const Index = u32; diff --git a/src/link/Elf/ZigObject.zig b/src/link/Elf/ZigObject.zig index 441518059784787e793e026a4cd6921f2c34a7c1..596ed781ca96deccb89b3db64653267488364a96 100644 --- a/src/link/Elf/ZigObject.zig +++ b/src/link/Elf/ZigObject.zig @@ -55,10 +55,10 @@ debug_str_section_zig_size: u64 = 0, debug_aranges_section_zig_size: u64 = 0, debug_line_section_zig_size: u64 = 0, -/// Function offset table containing pointers to Zig generated functions. +/// Function jump table containing trampolines to Zcu functions. /// The table is used for Zig's incremental compilation and is embedded with /// the machine code section. -offset_table: ?OffsetTable = null, +jump_table: ?JumpTable = null, pub const global_symbol_bit: u32 = 0x80000000; pub const symbol_mask: u32 = 0x7fffffff; @@ -128,8 +128,8 @@ pub fn deinit(self: *ZigObject, allocator: Allocator) void { dw.deinit(); } - if (self.offset_table) |*ot| { - ot.deinit(allocator); + if (self.jump_table) |*jt| { + jt.deinit(allocator); } } @@ -917,8 +917,8 @@ fn updateNavCode( if (stt_bits == elf.STT_FUNC) { const extra = sym.extra(elf_file); - const offset_table = self.offsetTablePtr().?; - offset_table.entries.items(.dirty)[extra.zig_offset_table] = true; + const jump_table = self.jumpTablePtr().?; + jump_table.entries.items(.dirty)[extra.zig_jump_table] = true; } } } else if (code.len < old_size) { @@ -1036,7 +1036,7 @@ pub fn updateFunc( const ip = &zcu.intern_pool; const gpa = elf_file.base.comp.gpa; const func = zcu.funcInfo(func_index); - const offset_table = self.offsetTablePtr() orelse try self.initOffsetTable(gpa, elf_file); + const jump_table = self.jumpTablePtr() orelse try self.initJumpTable(gpa, elf_file); log.debug("updateFunc {}({d})", .{ ip.getNav(func.owner_nav).fqn.fmt(ip), func.owner_nav }); @@ -1045,16 +1045,16 @@ pub fn updateFunc( { const sym = self.symbol(sym_index); - if (!sym.flags.zig_offset_table) { - const index = try offset_table.addSymbol(gpa, sym_index); - sym.flags.zig_offset_table = true; - sym.addExtra(.{ .zig_offset_table = index }, elf_file); - try offset_table.updateSize(self, elf_file); - const old_vaddr = offset_table.address(self, elf_file); - try self.symbol(offset_table.sym_index).atom(elf_file).?.allocate(elf_file); - const new_vaddr = offset_table.address(self, elf_file); + if (!sym.flags.zig_jump_table) { + const index = try jump_table.addSymbol(gpa, sym_index); + sym.flags.zig_jump_table = true; + sym.addExtra(.{ .zig_jump_table = index }, elf_file); + try jump_table.updateSize(self, elf_file); + const old_vaddr = jump_table.address(self, elf_file); + try self.symbol(jump_table.sym_index).atom(elf_file).?.allocate(elf_file); + const new_vaddr = jump_table.address(self, elf_file); if (old_vaddr != new_vaddr) { - offset_table.dirty = true; + jump_table.dirty = true; } } } @@ -1100,21 +1100,21 @@ pub fn updateFunc( // Exports will be updated by `Zcu.processExports` after the update. - if (offset_table.dirty) { + if (jump_table.dirty) { // TODO write in bulk - for (offset_table.entries.items(.dirty), 0..) |*dirty, i| { - try offset_table.writeEntry(@intCast(i), self, elf_file); + for (jump_table.entries.items(.dirty), 0..) |*dirty, i| { + try jump_table.writeEntry(@intCast(i), self, elf_file); dirty.* = false; } } else { const sym = self.symbol(sym_index); - const ot_index = sym.extra(elf_file).zig_offset_table; - var ot_entry = offset_table.entries.get(ot_index); - if (ot_entry.dirty) { - try offset_table.writeEntry(ot_index, self, elf_file); - ot_entry.dirty = false; + const jt_index = sym.extra(elf_file).zig_jump_table; + var jt_entry = jump_table.entries.get(jt_index); + if (jt_entry.dirty) { + try jump_table.writeEntry(jt_index, self, elf_file); + jt_entry.dirty = false; } - offset_table.entries.set(ot_index, ot_entry); + jump_table.entries.set(jt_index, jt_entry); } } @@ -1470,22 +1470,22 @@ pub fn getGlobalSymbol(self: *ZigObject, elf_file: *Elf, name: []const u8, lib_n return lookup_gop.value_ptr.*; } -pub fn offsetTablePtr(self: *ZigObject) ?*OffsetTable { - return if (self.offset_table) |*ot| ot else null; +pub fn jumpTablePtr(self: *ZigObject) ?*JumpTable { + return if (self.jump_table) |*jt| jt else null; } -fn initOffsetTable(self: *ZigObject, allocator: Allocator, elf_file: *Elf) error{OutOfMemory}!*OffsetTable { - const name_off = try self.addString(allocator, "__zig_offset_table"); +fn initJumpTable(self: *ZigObject, allocator: Allocator, elf_file: *Elf) error{OutOfMemory}!*JumpTable { + const name_off = try self.addString(allocator, "__zig_jump_table"); const sym_index = try self.newSymbolWithAtom(allocator, name_off); const sym = self.symbol(sym_index); const esym = &self.symtab.items(.elf_sym)[sym.esym_index]; esym.st_info |= elf.STT_OBJECT; const atom_ptr = sym.atom(elf_file).?; atom_ptr.alive = true; - atom_ptr.alignment = Atom.Alignment.fromNonzeroByteUnits(OffsetTable.alignment(elf_file.getTarget().cpu.arch)); + atom_ptr.alignment = Atom.Alignment.fromNonzeroByteUnits(JumpTable.alignment(elf_file.getTarget().cpu.arch)); atom_ptr.output_section_index = elf_file.zig_text_section_index.?; - self.offset_table = OffsetTable{ .sym_index = sym_index }; - return &(self.offset_table.?); + self.jump_table = JumpTable{ .sym_index = sym_index }; + return &(self.jump_table.?); } pub fn asFile(self: *ZigObject) File { @@ -1763,28 +1763,28 @@ const UavTable = std.AutoArrayHashMapUnmanaged(InternPool.Index, AvMetadata); const LazySymbolTable = std.AutoArrayHashMapUnmanaged(InternPool.Index, LazySymbolMetadata); const TlsTable = std.AutoArrayHashMapUnmanaged(Atom.Index, TlsVariable); -pub const OffsetTable = struct { +pub const JumpTable = struct { sym_index: Symbol.Index, entries: std.MultiArrayList(Entry) = .{}, dirty: bool = false, - pub fn deinit(ot: *OffsetTable, allocator: Allocator) void { - ot.entries.deinit(allocator); + pub fn deinit(jt: *JumpTable, allocator: Allocator) void { + jt.entries.deinit(allocator); } - pub fn addSymbol(ot: *OffsetTable, allocator: Allocator, sym_index: Symbol.Index) !Index { - const index: Index = @intCast(try ot.entries.addOne(allocator)); - ot.entries.set(index, .{ .sym_index = sym_index }); + pub fn addSymbol(jt: *JumpTable, allocator: Allocator, sym_index: Symbol.Index) !Index { + const index: Index = @intCast(try jt.entries.addOne(allocator)); + jt.entries.set(index, .{ .sym_index = sym_index }); return index; } - pub fn address(ot: OffsetTable, zo: *ZigObject, elf_file: *Elf) i64 { - const sym = zo.symbol(ot.sym_index); + pub fn address(jt: JumpTable, zo: *ZigObject, elf_file: *Elf) i64 { + const sym = zo.symbol(jt.sym_index); return sym.address(.{}, elf_file); } - pub fn size(ot: OffsetTable, zo: *ZigObject, elf_file: *Elf) u64 { - const sym = zo.symbol(ot.sym_index); + pub fn size(jt: JumpTable, zo: *ZigObject, elf_file: *Elf) u64 { + const sym = zo.symbol(jt.sym_index); return sym.atom(elf_file).?.size; } @@ -1795,12 +1795,12 @@ pub const OffsetTable = struct { }; } - pub fn entryAddress(ot: OffsetTable, index: Index, zo: *ZigObject, elf_file: *Elf) i64 { - return ot.address(zo, elf_file) + @as(i64, @intCast(index * entrySize(elf_file.getTarget().cpu.arch))); + pub fn entryAddress(jt: JumpTable, index: Index, zo: *ZigObject, elf_file: *Elf) i64 { + return jt.address(zo, elf_file) + @as(i64, @intCast(index * entrySize(elf_file.getTarget().cpu.arch))); } - pub fn entryOffset(ot: OffsetTable, index: Index, zo: *ZigObject, elf_file: *Elf) u64 { - const sym = zo.symbol(ot.sym_index); + pub fn entryOffset(jt: JumpTable, index: Index, zo: *ZigObject, elf_file: *Elf) u64 { + const sym = zo.symbol(jt.sym_index); const atom_ptr = sym.atom(elf_file).?; const shdr = elf_file.shdrs.items[atom_ptr.output_section_index]; return shdr.sh_offset + @as(u64, @intCast(atom_ptr.value)) + index * entrySize(elf_file.getTarget().cpu.arch); @@ -1815,17 +1815,17 @@ pub const OffsetTable = struct { return seq_len; } - pub fn targetAddress(ot: OffsetTable, index: Index, zo: *ZigObject, elf_file: *Elf) i64 { - const sym_index = ot.entries.items(.sym_index)[index]; + pub fn targetAddress(jt: JumpTable, index: Index, zo: *ZigObject, elf_file: *Elf) i64 { + const sym_index = jt.entries.items(.sym_index)[index]; return zo.symbol(sym_index).address(.{}, elf_file); } const max_jump_seq_len = 12; - pub fn writeEntry(ot: OffsetTable, index: Index, zo: *ZigObject, elf_file: *Elf) !void { - const fileoff = ot.entryOffset(index, zo, elf_file); - const source_addr = ot.entryAddress(index, zo, elf_file); - const target_addr = @as(i64, @intCast(ot.targetAddress(index, zo, elf_file))); + pub fn writeEntry(jt: JumpTable, index: Index, zo: *ZigObject, elf_file: *Elf) !void { + const fileoff = jt.entryOffset(index, zo, elf_file); + const source_addr = jt.entryAddress(index, zo, elf_file); + const target_addr = @as(i64, @intCast(jt.targetAddress(index, zo, elf_file))); var buf: [max_jump_seq_len]u8 = undefined; const out = switch (elf_file.getTarget().cpu.arch) { .x86_64 => try x86_64.writeEntry(source_addr, target_addr, &buf), @@ -1855,46 +1855,46 @@ pub const OffsetTable = struct { } } - pub fn updateSize(ot: OffsetTable, zo: *ZigObject, elf_file: *Elf) !void { - const ot_size: u64 = @intCast(ot.entries.items(.sym_index).len * entrySize(elf_file.getTarget().cpu.arch)); - const sym = zo.symbol(ot.sym_index); + pub fn updateSize(jt: JumpTable, zo: *ZigObject, elf_file: *Elf) !void { + const jt_size: u64 = @intCast(jt.entries.items(.sym_index).len * entrySize(elf_file.getTarget().cpu.arch)); + const sym = zo.symbol(jt.sym_index); const esym = &zo.symtab.items(.elf_sym)[sym.esym_index]; - esym.st_size = ot_size; + esym.st_size = jt_size; const atom_ptr = sym.atom(elf_file).?; - atom_ptr.size = ot_size; + atom_ptr.size = jt_size; } - const OffsetTableFormatContext = struct { OffsetTable, *ZigObject, *Elf }; + const JumpTableFormatContext = struct { JumpTable, *ZigObject, *Elf }; pub fn format( - ot: OffsetTable, + jt: JumpTable, comptime unused_fmt_string: []const u8, options: std.fmt.FormatOptions, writer: anytype, ) !void { - _ = ot; + _ = jt; _ = unused_fmt_string; _ = options; _ = writer; - @compileError("do not format OffsetTable directly"); + @compileError("do not format JumpTable directly"); } - pub fn fmt(ot: OffsetTable, zo: *ZigObject, elf_file: *Elf) std.fmt.Formatter(format2) { - return .{ .data = .{ ot, zo, elf_file } }; + pub fn fmt(jt: JumpTable, zo: *ZigObject, elf_file: *Elf) std.fmt.Formatter(format2) { + return .{ .data = .{ jt, zo, elf_file } }; } fn format2( - ctx: OffsetTableFormatContext, + ctx: JumpTableFormatContext, comptime unused_fmt_string: []const u8, options: std.fmt.FormatOptions, writer: anytype, ) !void { _ = options; _ = unused_fmt_string; - const ot, const zo, const ef = ctx; - try writer.writeAll("offset table\n"); - try writer.print(" @{x} : size({x})\n", .{ ot.address(zo, ef), ot.size(zo, ef) }); - for (ot.entries.items(.sym_index), ot.entries.items(.dirty)) |sym_index, dirty| { + const jt, const zo, const ef = ctx; + try writer.writeAll("__zig_jump_table\n"); + try writer.print(" @{x} : size({x})\n", .{ jt.address(zo, ef), jt.size(zo, ef) }); + for (jt.entries.items(.sym_index), jt.entries.items(.dirty)) |sym_index, dirty| { const sym = zo.symbol(sym_index); try writer.print(" %{d} : {s} : @{x}", .{ sym_index, sym.name(ef), sym.address(.{}, ef) }); if (dirty) try writer.writeAll(" : [!]");