elf: only apply zig jump table indirection to function calls (PLT32)
This commit is contained in:
@@ -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) {
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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)) {
|
||||
|
||||
@@ -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),
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user