authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-08-12 22:51:33+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-08-13 13:30:24+02:00
loge3f6ebaea94bb11c2e990e1fa17b48e51e598b5c
treeb8114bfb6d2eef489674bcc3108480583d85ef29
parent16abf51ceef2ba2ebb38f27270af676387435f05

x86_64+elf: fix jump table indirection for functions


2 files changed, 29 insertions(+), 43 deletions(-)

src/arch/x86_64/CodeGen.zig+19-27
......@@ -12311,33 +12311,25 @@ fn genCall(self: *Self, info: union(enum) {
1231112311 const zo = elf_file.zigObjectPtr().?;
1231212312 const sym_index = try zo.getOrCreateMetadataForNav(elf_file, func.owner_nav);
1231312313 if (self.mod.pic) {
12314 // const callee_reg: Register = switch (resolved_cc) {
12315 // .SysV => callee: {
12316 // if (!fn_info.is_var_args) break :callee .rax;
12317 // const param_regs = abi.getCAbiIntParamRegs(resolved_cc);
12318 // break :callee if (call_info.gp_count < param_regs.len)
12319 // param_regs[call_info.gp_count]
12320 // else
12321 // .r10;
12322 // },
12323 // .Win64 => .rax,
12324 // else => unreachable,
12325 // };
12326 // TODO convert to near jump
12327 try self.asmMemory(.{ ._, .call }, .{
12328 .base = .{ .reloc = .{
12329 .atom_index = try self.owner.getSymbolIndex(self),
12330 .sym_index = sym_index,
12331 } },
12332 .mod = .{ .rm = .{ .size = .qword } },
12333 });
12334 // try self.genSetReg(
12335 // callee_reg,
12336 // Type.usize,
12337 // .{ .load_symbol = .{ .sym = sym_index } },
12338 // .{},
12339 // );
12340 // try self.asmRegister(.{ ._, .call }, callee_reg);
12314 const callee_reg: Register = switch (resolved_cc) {
12315 .SysV => callee: {
12316 if (!fn_info.is_var_args) break :callee .rax;
12317 const param_regs = abi.getCAbiIntParamRegs(resolved_cc);
12318 break :callee if (call_info.gp_count < param_regs.len)
12319 param_regs[call_info.gp_count]
12320 else
12321 .r10;
12322 },
12323 .Win64 => .rax,
12324 else => unreachable,
12325 };
12326 try self.genSetReg(
12327 callee_reg,
12328 Type.usize,
12329 .{ .lea_symbol = .{ .sym = sym_index } },
12330 .{},
12331 );
12332 try self.asmRegister(.{ ._, .call }, callee_reg);
1234112333 } else try self.asmMemory(.{ ._, .call }, .{
1234212334 .base = .{ .reloc = .{
1234312335 .atom_index = try self.owner.getSymbolIndex(self),
src/link/Elf/ZigObject.zig+10-16
......@@ -107,23 +107,17 @@ pub fn deinit(self: *ZigObject, allocator: Allocator) void {
107107 }
108108 self.relocs.deinit(allocator);
109109
110 {
111 var it = self.navs.iterator();
112 while (it.next()) |entry| {
113 entry.value_ptr.exports.deinit(allocator);
114 }
115 self.navs.deinit(allocator);
110 for (self.navs.values()) |*meta| {
111 meta.exports.deinit(allocator);
116112 }
113 self.navs.deinit(allocator);
117114
118115 self.lazy_syms.deinit(allocator);
119116
120 {
121 var it = self.uavs.iterator();
122 while (it.next()) |entry| {
123 entry.value_ptr.exports.deinit(allocator);
124 }
125 self.uavs.deinit(allocator);
117 for (self.uavs.values()) |*meta| {
118 meta.exports.deinit(allocator);
126119 }
120 self.uavs.deinit(allocator);
127121
128122 for (self.tls_variables.values()) |*tlv| {
129123 tlv.deinit(allocator);
......@@ -1721,8 +1715,8 @@ const TlsVariable = struct {
17211715};
17221716
17231717const AtomList = std.ArrayListUnmanaged(Atom.Index);
1724const NavTable = std.AutoHashMapUnmanaged(InternPool.Nav.Index, AvMetadata);
1725const UavTable = std.AutoHashMapUnmanaged(InternPool.Index, AvMetadata);
1718const NavTable = std.AutoArrayHashMapUnmanaged(InternPool.Nav.Index, AvMetadata);
1719const UavTable = std.AutoArrayHashMapUnmanaged(InternPool.Index, AvMetadata);
17261720const LazySymbolTable = std.AutoArrayHashMapUnmanaged(InternPool.Index, LazySymbolMetadata);
17271721const TlsTable = std.AutoArrayHashMapUnmanaged(Atom.Index, TlsVariable);
17281722
......@@ -1874,9 +1868,9 @@ pub const OffsetTable = struct {
18741868
18751869 const x86_64 = struct {
18761870 fn writeEntry(source_addr: i64, target_addr: i64, buf: *[max_jump_seq_len]u8) ![]u8 {
1877 const disp = @as(i64, @intCast(target_addr)) - source_addr - 4;
1871 const disp = @as(i64, @intCast(target_addr)) - source_addr - 5;
18781872 var bytes = [_]u8{
1879 0xe8, 0x00, 0x00, 0x00, 0x00, // jmp rel32
1873 0xe9, 0x00, 0x00, 0x00, 0x00, // jmp rel32
18801874 };
18811875 assert(bytes.len == entrySize(.x86_64));
18821876 mem.writeInt(i32, bytes[1..][0..4], @intCast(disp), .little);