diff options
| author | Jakub Konka <kubkon@jakubkonka.com> | 2024-08-13 12:50:53 +0200 |
|---|---|---|
| committer | Jakub Konka <kubkon@jakubkonka.com> | 2024-08-13 13:30:24 +0200 |
| commit | 49d78cc793f6dd987d2a51c7a96333713264691f (patch) | |
| tree | 127e008da37979688c4694c037599514f7a62113 | |
| parent | 9daf5e81c4bdc413a3bb11c1bab207c19e6ba547 (diff) | |
| download | zig-49d78cc793f6dd987d2a51c7a96333713264691f.tar.gz zig-49d78cc793f6dd987d2a51c7a96333713264691f.zip | |
elf: only apply zig jump table indirection to function calls (PLT32)
| -rw-r--r-- | src/link/Elf.zig | 2 | ||||
| -rw-r--r-- | src/link/Elf/Atom.zig | 7 | ||||
| -rw-r--r-- | src/link/Elf/Symbol.zig | 10 | ||||
| -rw-r--r-- | src/link/Elf/ZigObject.zig | 12 |
4 files changed, 17 insertions, 14 deletions
diff --git a/src/link/Elf.zig b/src/link/Elf.zig index dce5d45c80..50dfeffa17 100644 --- a/src/link/Elf.zig +++ b/src/link/Elf.zig @@ -2798,7 +2798,7 @@ pub fn writeElfHeader(self: *Elf) !void { const e_entry: u64 = if (self.linkerDefinedPtr()) |obj| blk: { const entry_sym = obj.entrySymbol(self) orelse break :blk 0; - break :blk @intCast(entry_sym.address(.{}, self)); + break :blk @intCast(entry_sym.address(.{ .zjt = true }, self)); } else 0; const phdr_table_offset = if (self.phdr_table_index) |phndx| self.phdrs.items[phndx].p_offset else 0; switch (self.ptr_width) { diff --git a/src/link/Elf/Atom.zig b/src/link/Elf/Atom.zig index 6e68b84952..7338927ebd 100644 --- a/src/link/Elf/Atom.zig +++ b/src/link/Elf/Atom.zig @@ -747,7 +747,7 @@ pub fn resolveRelocsAlloc(self: Atom, elf_file: *Elf, code: []u8) RelocError!voi // Addend from the relocation. const A = rel.r_addend; // Address of the target symbol - can be address of the symbol within an atom or address of PLT stub. - const S = target.address(.{}, elf_file); + const S = target.address(.{ .zjt = false }, elf_file); // Address of the global offset table. const GOT = elf_file.gotAddress(); // Relative offset to the start of the global offset table. @@ -1212,7 +1212,10 @@ const x86_64 = struct { ); }, - .PLT32 => try cwriter.writeInt(i32, @as(i32, @intCast(S + A - P)), .little), + .PLT32 => { + const S_ = if (target.flags.has_zjt) target.address(.{ .zjt = true }, elf_file) else S; + try cwriter.writeInt(i32, @as(i32, @intCast(S_ + A - P)), .little); + }, .PC32 => try cwriter.writeInt(i32, @as(i32, @intCast(S + A - P)), .little), .GOTPCREL => try cwriter.writeInt(i32, @as(i32, @intCast(G + GOT + A - P)), .little), diff --git a/src/link/Elf/Symbol.zig b/src/link/Elf/Symbol.zig index 1f81b3ff98..d946e95511 100644 --- a/src/link/Elf/Symbol.zig +++ b/src/link/Elf/Symbol.zig @@ -101,7 +101,7 @@ pub fn symbolRank(symbol: Symbol, elf_file: *Elf) u32 { return file_ptr.symbolRank(sym, in_archive); } -pub fn address(symbol: Symbol, opts: struct { plt: bool = true, zjt: bool = true }, elf_file: *Elf) i64 { +pub fn address(symbol: Symbol, opts: struct { plt: bool = true, zjt: bool = false }, elf_file: *Elf) i64 { if (symbol.mergeSubsection(elf_file)) |msub| { if (!msub.alive) return 0; return msub.address(elf_file) + symbol.value; @@ -300,11 +300,11 @@ pub fn setOutputSym(symbol: Symbol, elf_file: *Elf, out: *elf.Elf64_Sym) void { if (symbol.flags.is_canonical) break :blk symbol.address(.{}, elf_file); break :blk 0; } - if (st_shndx == elf.SHN_ABS or st_shndx == elf.SHN_COMMON) break :blk symbol.address(.{ .plt = false, .zjt = false }, elf_file); + if (st_shndx == elf.SHN_ABS or st_shndx == elf.SHN_COMMON) break :blk symbol.address(.{ .plt = false }, elf_file); const shdr = elf_file.shdrs.items[st_shndx]; if (shdr.sh_flags & elf.SHF_TLS != 0 and file_ptr != .linker_defined) - break :blk symbol.address(.{ .plt = false, .zjt = false }, elf_file) - elf_file.tlsAddress(); - break :blk symbol.address(.{ .plt = false, .zjt = false }, elf_file); + break :blk symbol.address(.{ .plt = false }, elf_file) - elf_file.tlsAddress(); + break :blk symbol.address(.{ .plt = false }, elf_file); }; out.st_info = (st_bind << 4) | st_type; out.st_other = esym.st_other; @@ -380,7 +380,7 @@ fn format2( try writer.print("%{d} : {s} : @{x}", .{ symbol.esym_index, symbol.fmtName(elf_file), - symbol.address(.{ .plt = false, .zjt = false }, elf_file), + symbol.address(.{ .plt = false }, elf_file), }); if (symbol.file(elf_file)) |file_ptr| { if (symbol.isAbs(elf_file)) { diff --git a/src/link/Elf/ZigObject.zig b/src/link/Elf/ZigObject.zig index 70f6a2500d..865f4118d3 100644 --- a/src/link/Elf/ZigObject.zig +++ b/src/link/Elf/ZigObject.zig @@ -665,7 +665,7 @@ pub fn getNavVAddr( else => try self.getOrCreateMetadataForNav(elf_file, nav_index), }; const this_sym = self.symbol(this_sym_index); - const vaddr = this_sym.address(.{}, elf_file); + const vaddr = this_sym.address(.{ .zjt = true }, elf_file); const parent_atom = self.symbol(reloc_info.parent_atom_index).atom(elf_file).?; const r_type = relocation.encode(.abs, elf_file.getTarget().cpu.arch); try parent_atom.addReloc(elf_file, .{ @@ -942,7 +942,7 @@ fn updateNavCode( .len = code.len, }}; var remote_vec: [1]std.posix.iovec_const = .{.{ - .base = @as([*]u8, @ptrFromInt(@as(usize, @intCast(sym.address(.{}, elf_file))))), + .base = @as([*]u8, @ptrFromInt(@as(usize, @intCast(sym.address(.{ .zjt = true }, elf_file))))), .len = code.len, }}; const rc = std.os.linux.process_vm_writev(pid, &code_vec, &remote_vec, 0); @@ -1092,7 +1092,7 @@ pub fn updateFunc( try self.dwarf.?.commitNavState( pt, func.owner_nav, - @intCast(sym.address(.{}, elf_file)), + @intCast(sym.address(.{ .zjt = true }, elf_file)), sym.atom(elf_file).?.size, ds, ); @@ -1189,7 +1189,7 @@ pub fn updateNav( try self.dwarf.?.commitNavState( pt, nav_index, - @intCast(sym.address(.{}, elf_file)), + @intCast(sym.address(.{ .zjt = true }, elf_file)), sym.atom(elf_file).?.size, ns, ); @@ -1817,7 +1817,7 @@ pub const JumpTable = struct { 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(.{ .zjt = false }, elf_file); + return zo.symbol(sym_index).address(.{}, elf_file); } const max_jump_seq_len = 12; @@ -1897,8 +1897,8 @@ pub const JumpTable = struct { for (jt.entries.items(.sym_index), jt.entries.items(.dirty)) |sym_index, dirty| { const sym = zo.symbol(sym_index); try writer.print(" {x} => {x} : %{d} : {s}", .{ + sym.address(.{ .zjt = true }, ef), sym.address(.{}, ef), - sym.address(.{ .zjt = false }, ef), sym_index, sym.name(ef), }); |
