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 {...@@ -2798,7 +2798,7 @@ pub fn writeElfHeader(self: *Elf) !void {
27982798
2799 const e_entry: u64 = if (self.linkerDefinedPtr()) |obj| blk: {2799 const e_entry: u64 = if (self.linkerDefinedPtr()) |obj| blk: {
2800 const entry_sym = obj.entrySymbol(self) orelse break :blk 0;2800 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));
2802 } else 0;2802 } else 0;
2803 const phdr_table_offset = if (self.phdr_table_index) |phndx| self.phdrs.items[phndx].p_offset else 0;2803 const phdr_table_offset = if (self.phdr_table_index) |phndx| self.phdrs.items[phndx].p_offset else 0;
2804 switch (self.ptr_width) {2804 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...@@ -747,7 +747,7 @@ pub fn resolveRelocsAlloc(self: Atom, elf_file: *Elf, code: []u8) RelocError!voi
747 // Addend from the relocation.747 // Addend from the relocation.
748 const A = rel.r_addend;748 const A = rel.r_addend;
749 // Address of the target symbol - can be address of the symbol within an atom or address of PLT stub.749 // 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);
751 // Address of the global offset table.751 // Address of the global offset table.
752 const GOT = elf_file.gotAddress();752 const GOT = elf_file.gotAddress();
753 // Relative offset to the start of the global offset table.753 // Relative offset to the start of the global offset table.
...@@ -1212,7 +1212,10 @@ const x86_64 = struct {...@@ -1212,7 +1212,10 @@ const x86_64 = struct {
1212 );1212 );
1213 },1213 },
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 },
1216 .PC32 => try cwriter.writeInt(i32, @as(i32, @intCast(S + A - P)), .little),1219 .PC32 => try cwriter.writeInt(i32, @as(i32, @intCast(S + A - P)), .little),
12171220
1218 .GOTPCREL => try cwriter.writeInt(i32, @as(i32, @intCast(G + GOT + A - P)), .little),1221 .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 {...@@ -101,7 +101,7 @@ pub fn symbolRank(symbol: Symbol, elf_file: *Elf) u32 {
101 return file_ptr.symbolRank(sym, in_archive);101 return file_ptr.symbolRank(sym, in_archive);
102}102}
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 {
105 if (symbol.mergeSubsection(elf_file)) |msub| {105 if (symbol.mergeSubsection(elf_file)) |msub| {
106 if (!msub.alive) return 0;106 if (!msub.alive) return 0;
107 return msub.address(elf_file) + symbol.value;107 return msub.address(elf_file) + symbol.value;
...@@ -300,11 +300,11 @@ pub fn setOutputSym(symbol: Symbol, elf_file: *Elf, out: *elf.Elf64_Sym) void {...@@ -300,11 +300,11 @@ pub fn setOutputSym(symbol: Symbol, elf_file: *Elf, out: *elf.Elf64_Sym) void {
300 if (symbol.flags.is_canonical) break :blk symbol.address(.{}, elf_file);300 if (symbol.flags.is_canonical) break :blk symbol.address(.{}, elf_file);
301 break :blk 0;301 break :blk 0;
302 }302 }
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);
304 const shdr = elf_file.shdrs.items[st_shndx];304 const shdr = elf_file.shdrs.items[st_shndx];
305 if (shdr.sh_flags & elf.SHF_TLS != 0 and file_ptr != .linker_defined)305 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();306 break :blk symbol.address(.{ .plt = false }, elf_file) - elf_file.tlsAddress();
307 break :blk symbol.address(.{ .plt = false, .zjt = false }, elf_file);307 break :blk symbol.address(.{ .plt = false }, elf_file);
308 };308 };
309 out.st_info = (st_bind << 4) | st_type;309 out.st_info = (st_bind << 4) | st_type;
310 out.st_other = esym.st_other;310 out.st_other = esym.st_other;
...@@ -380,7 +380,7 @@ fn format2(...@@ -380,7 +380,7 @@ fn format2(
380 try writer.print("%{d} : {s} : @{x}", .{380 try writer.print("%{d} : {s} : @{x}", .{
381 symbol.esym_index,381 symbol.esym_index,
382 symbol.fmtName(elf_file),382 symbol.fmtName(elf_file),
383 symbol.address(.{ .plt = false, .zjt = false }, elf_file),383 symbol.address(.{ .plt = false }, elf_file),
384 });384 });
385 if (symbol.file(elf_file)) |file_ptr| {385 if (symbol.file(elf_file)) |file_ptr| {
386 if (symbol.isAbs(elf_file)) {386 if (symbol.isAbs(elf_file)) {
src/link/Elf/ZigObject.zig+6-6
...@@ -665,7 +665,7 @@ pub fn getNavVAddr(...@@ -665,7 +665,7 @@ pub fn getNavVAddr(
665 else => try self.getOrCreateMetadataForNav(elf_file, nav_index),665 else => try self.getOrCreateMetadataForNav(elf_file, nav_index),
666 };666 };
667 const this_sym = self.symbol(this_sym_index);667 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);
669 const parent_atom = self.symbol(reloc_info.parent_atom_index).atom(elf_file).?;669 const parent_atom = self.symbol(reloc_info.parent_atom_index).atom(elf_file).?;
670 const r_type = relocation.encode(.abs, elf_file.getTarget().cpu.arch);670 const r_type = relocation.encode(.abs, elf_file.getTarget().cpu.arch);
671 try parent_atom.addReloc(elf_file, .{671 try parent_atom.addReloc(elf_file, .{
...@@ -942,7 +942,7 @@ fn updateNavCode(...@@ -942,7 +942,7 @@ fn updateNavCode(
942 .len = code.len,942 .len = code.len,
943 }};943 }};
944 var remote_vec: [1]std.posix.iovec_const = .{.{944 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))))),
946 .len = code.len,946 .len = code.len,
947 }};947 }};
948 const rc = std.os.linux.process_vm_writev(pid, &code_vec, &remote_vec, 0);948 const rc = std.os.linux.process_vm_writev(pid, &code_vec, &remote_vec, 0);
...@@ -1092,7 +1092,7 @@ pub fn updateFunc(...@@ -1092,7 +1092,7 @@ pub fn updateFunc(
1092 try self.dwarf.?.commitNavState(1092 try self.dwarf.?.commitNavState(
1093 pt,1093 pt,
1094 func.owner_nav,1094 func.owner_nav,
1095 @intCast(sym.address(.{}, elf_file)),1095 @intCast(sym.address(.{ .zjt = true }, elf_file)),
1096 sym.atom(elf_file).?.size,1096 sym.atom(elf_file).?.size,
1097 ds,1097 ds,
1098 );1098 );
...@@ -1189,7 +1189,7 @@ pub fn updateNav(...@@ -1189,7 +1189,7 @@ pub fn updateNav(
1189 try self.dwarf.?.commitNavState(1189 try self.dwarf.?.commitNavState(
1190 pt,1190 pt,
1191 nav_index,1191 nav_index,
1192 @intCast(sym.address(.{}, elf_file)),1192 @intCast(sym.address(.{ .zjt = true }, elf_file)),
1193 sym.atom(elf_file).?.size,1193 sym.atom(elf_file).?.size,
1194 ns,1194 ns,
1195 );1195 );
...@@ -1817,7 +1817,7 @@ pub const JumpTable = struct {...@@ -1817,7 +1817,7 @@ pub const JumpTable = struct {
18171817
1818 pub fn targetAddress(jt: JumpTable, index: Index, zo: *ZigObject, elf_file: *Elf) i64 {1818 pub fn targetAddress(jt: JumpTable, index: Index, zo: *ZigObject, elf_file: *Elf) i64 {
1819 const sym_index = jt.entries.items(.sym_index)[index];1819 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);
1821 }1821 }
18221822
1823 const max_jump_seq_len = 12;1823 const max_jump_seq_len = 12;
...@@ -1897,8 +1897,8 @@ pub const JumpTable = struct {...@@ -1897,8 +1897,8 @@ pub const JumpTable = struct {
1897 for (jt.entries.items(.sym_index), jt.entries.items(.dirty)) |sym_index, dirty| {1897 for (jt.entries.items(.sym_index), jt.entries.items(.dirty)) |sym_index, dirty| {
1898 const sym = zo.symbol(sym_index);1898 const sym = zo.symbol(sym_index);
1899 try writer.print(" {x} => {x} : %{d} : {s}", .{1899 try writer.print(" {x} => {x} : %{d} : {s}", .{
1900 sym.address(.{ .zjt = true }, ef),
1900 sym.address(.{}, ef),1901 sym.address(.{}, ef),
1901 sym.address(.{ .zjt = false }, ef),
1902 sym_index,1902 sym_index,
1903 sym.name(ef),1903 sym.name(ef),
1904 });1904 });