authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-08-13 12:50:53+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-08-13 13:30:24+02:00
log49d78cc793f6dd987d2a51c7a96333713264691f
tree127e008da37979688c4694c037599514f7a62113
parent9daf5e81c4bdc413a3bb11c1bab207c19e6ba547

elf: only apply zig jump table indirection to function calls (PLT32)


4 files changed, 17 insertions(+), 14 deletions(-)

src/link/Elf.zig+1-1
......@@ -2798,7 +2798,7 @@ pub fn writeElfHeader(self: *Elf) !void {
27982798
27992799 const e_entry: u64 = if (self.linkerDefinedPtr()) |obj| blk: {
28002800 const entry_sym = obj.entrySymbol(self) orelse break :blk 0;
2801 break :blk @intCast(entry_sym.address(.{}, self));
2801 break :blk @intCast(entry_sym.address(.{ .zjt = true }, self));
28022802 } else 0;
28032803 const phdr_table_offset = if (self.phdr_table_index) |phndx| self.phdrs.items[phndx].p_offset else 0;
28042804 switch (self.ptr_width) {
src/link/Elf/Atom.zig+5-2
......@@ -747,7 +747,7 @@ pub fn resolveRelocsAlloc(self: Atom, elf_file: *Elf, code: []u8) RelocError!voi
747747 // Addend from the relocation.
748748 const A = rel.r_addend;
749749 // Address of the target symbol - can be address of the symbol within an atom or address of PLT stub.
750 const S = target.address(.{}, elf_file);
750 const S = target.address(.{ .zjt = false }, elf_file);
751751 // Address of the global offset table.
752752 const GOT = elf_file.gotAddress();
753753 // Relative offset to the start of the global offset table.
......@@ -1212,7 +1212,10 @@ const x86_64 = struct {
12121212 );
12131213 },
12141214
1215 .PLT32 => try cwriter.writeInt(i32, @as(i32, @intCast(S + A - P)), .little),
1215 .PLT32 => {
1216 const S_ = if (target.flags.has_zjt) target.address(.{ .zjt = true }, elf_file) else S;
1217 try cwriter.writeInt(i32, @as(i32, @intCast(S_ + A - P)), .little);
1218 },
12161219 .PC32 => try cwriter.writeInt(i32, @as(i32, @intCast(S + A - P)), .little),
12171220
12181221 .GOTPCREL => try cwriter.writeInt(i32, @as(i32, @intCast(G + GOT + A - P)), .little),
src/link/Elf/Symbol.zig+5-5
......@@ -101,7 +101,7 @@ pub fn symbolRank(symbol: Symbol, elf_file: *Elf) u32 {
101101 return file_ptr.symbolRank(sym, in_archive);
102102}
103103
104pub fn address(symbol: Symbol, opts: struct { plt: bool = true, zjt: bool = true }, elf_file: *Elf) i64 {
104pub fn address(symbol: Symbol, opts: struct { plt: bool = true, zjt: bool = false }, elf_file: *Elf) i64 {
105105 if (symbol.mergeSubsection(elf_file)) |msub| {
106106 if (!msub.alive) return 0;
107107 return msub.address(elf_file) + symbol.value;
......@@ -300,11 +300,11 @@ pub fn setOutputSym(symbol: Symbol, elf_file: *Elf, out: *elf.Elf64_Sym) void {
300300 if (symbol.flags.is_canonical) break :blk symbol.address(.{}, elf_file);
301301 break :blk 0;
302302 }
303 if (st_shndx == elf.SHN_ABS or st_shndx == elf.SHN_COMMON) break :blk symbol.address(.{ .plt = false, .zjt = false }, elf_file);
303 if (st_shndx == elf.SHN_ABS or st_shndx == elf.SHN_COMMON) break :blk symbol.address(.{ .plt = false }, elf_file);
304304 const shdr = elf_file.shdrs.items[st_shndx];
305305 if (shdr.sh_flags & elf.SHF_TLS != 0 and file_ptr != .linker_defined)
306 break :blk symbol.address(.{ .plt = false, .zjt = false }, elf_file) - elf_file.tlsAddress();
307 break :blk symbol.address(.{ .plt = false, .zjt = false }, elf_file);
306 break :blk symbol.address(.{ .plt = false }, elf_file) - elf_file.tlsAddress();
307 break :blk symbol.address(.{ .plt = false }, elf_file);
308308 };
309309 out.st_info = (st_bind << 4) | st_type;
310310 out.st_other = esym.st_other;
......@@ -380,7 +380,7 @@ fn format2(
380380 try writer.print("%{d} : {s} : @{x}", .{
381381 symbol.esym_index,
382382 symbol.fmtName(elf_file),
383 symbol.address(.{ .plt = false, .zjt = false }, elf_file),
383 symbol.address(.{ .plt = false }, elf_file),
384384 });
385385 if (symbol.file(elf_file)) |file_ptr| {
386386 if (symbol.isAbs(elf_file)) {
src/link/Elf/ZigObject.zig+6-6
......@@ -665,7 +665,7 @@ pub fn getNavVAddr(
665665 else => try self.getOrCreateMetadataForNav(elf_file, nav_index),
666666 };
667667 const this_sym = self.symbol(this_sym_index);
668 const vaddr = this_sym.address(.{}, elf_file);
668 const vaddr = this_sym.address(.{ .zjt = true }, elf_file);
669669 const parent_atom = self.symbol(reloc_info.parent_atom_index).atom(elf_file).?;
670670 const r_type = relocation.encode(.abs, elf_file.getTarget().cpu.arch);
671671 try parent_atom.addReloc(elf_file, .{
......@@ -942,7 +942,7 @@ fn updateNavCode(
942942 .len = code.len,
943943 }};
944944 var remote_vec: [1]std.posix.iovec_const = .{.{
945 .base = @as([*]u8, @ptrFromInt(@as(usize, @intCast(sym.address(.{}, elf_file))))),
945 .base = @as([*]u8, @ptrFromInt(@as(usize, @intCast(sym.address(.{ .zjt = true }, elf_file))))),
946946 .len = code.len,
947947 }};
948948 const rc = std.os.linux.process_vm_writev(pid, &code_vec, &remote_vec, 0);
......@@ -1092,7 +1092,7 @@ pub fn updateFunc(
10921092 try self.dwarf.?.commitNavState(
10931093 pt,
10941094 func.owner_nav,
1095 @intCast(sym.address(.{}, elf_file)),
1095 @intCast(sym.address(.{ .zjt = true }, elf_file)),
10961096 sym.atom(elf_file).?.size,
10971097 ds,
10981098 );
......@@ -1189,7 +1189,7 @@ pub fn updateNav(
11891189 try self.dwarf.?.commitNavState(
11901190 pt,
11911191 nav_index,
1192 @intCast(sym.address(.{}, elf_file)),
1192 @intCast(sym.address(.{ .zjt = true }, elf_file)),
11931193 sym.atom(elf_file).?.size,
11941194 ns,
11951195 );
......@@ -1817,7 +1817,7 @@ pub const JumpTable = struct {
18171817
18181818 pub fn targetAddress(jt: JumpTable, index: Index, zo: *ZigObject, elf_file: *Elf) i64 {
18191819 const sym_index = jt.entries.items(.sym_index)[index];
1820 return zo.symbol(sym_index).address(.{ .zjt = false }, elf_file);
1820 return zo.symbol(sym_index).address(.{}, elf_file);
18211821 }
18221822
18231823 const max_jump_seq_len = 12;
......@@ -1897,8 +1897,8 @@ pub const JumpTable = struct {
18971897 for (jt.entries.items(.sym_index), jt.entries.items(.dirty)) |sym_index, dirty| {
18981898 const sym = zo.symbol(sym_index);
18991899 try writer.print(" {x} => {x} : %{d} : {s}", .{
1900 sym.address(.{ .zjt = true }, ef),
19001901 sym.address(.{}, ef),
1901 sym.address(.{ .zjt = false }, ef),
19021902 sym_index,
19031903 sym.name(ef),
19041904 });