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) {...@@ -12311,33 +12311,25 @@ fn genCall(self: *Self, info: union(enum) {
12311 const zo = elf_file.zigObjectPtr().?;12311 const zo = elf_file.zigObjectPtr().?;
12312 const sym_index = try zo.getOrCreateMetadataForNav(elf_file, func.owner_nav);12312 const sym_index = try zo.getOrCreateMetadataForNav(elf_file, func.owner_nav);
12313 if (self.mod.pic) {12313 if (self.mod.pic) {
12314 // const callee_reg: Register = switch (resolved_cc) {12314 const callee_reg: Register = switch (resolved_cc) {
12315 // .SysV => callee: {12315 .SysV => callee: {
12316 // if (!fn_info.is_var_args) break :callee .rax;12316 if (!fn_info.is_var_args) break :callee .rax;
12317 // const param_regs = abi.getCAbiIntParamRegs(resolved_cc);12317 const param_regs = abi.getCAbiIntParamRegs(resolved_cc);
12318 // break :callee if (call_info.gp_count < param_regs.len)12318 break :callee if (call_info.gp_count < param_regs.len)
12319 // param_regs[call_info.gp_count]12319 param_regs[call_info.gp_count]
12320 // else12320 else
12321 // .r10;12321 .r10;
12322 // },12322 },
12323 // .Win64 => .rax,12323 .Win64 => .rax,
12324 // else => unreachable,12324 else => unreachable,
12325 // };12325 };
12326 // TODO convert to near jump12326 try self.genSetReg(
12327 try self.asmMemory(.{ ._, .call }, .{12327 callee_reg,
12328 .base = .{ .reloc = .{12328 Type.usize,
12329 .atom_index = try self.owner.getSymbolIndex(self),12329 .{ .lea_symbol = .{ .sym = sym_index } },
12330 .sym_index = sym_index,12330 .{},
12331 } },12331 );
12332 .mod = .{ .rm = .{ .size = .qword } },12332 try self.asmRegister(.{ ._, .call }, callee_reg);
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);
12341 } else try self.asmMemory(.{ ._, .call }, .{12333 } else try self.asmMemory(.{ ._, .call }, .{
12342 .base = .{ .reloc = .{12334 .base = .{ .reloc = .{
12343 .atom_index = try self.owner.getSymbolIndex(self),12335 .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 {...@@ -107,23 +107,17 @@ pub fn deinit(self: *ZigObject, allocator: Allocator) void {
107 }107 }
108 self.relocs.deinit(allocator);108 self.relocs.deinit(allocator);
109109
110 {110 for (self.navs.values()) |*meta| {
111 var it = self.navs.iterator();111 meta.exports.deinit(allocator);
112 while (it.next()) |entry| {
113 entry.value_ptr.exports.deinit(allocator);
114 }
115 self.navs.deinit(allocator);
116 }112 }
113 self.navs.deinit(allocator);
117114
118 self.lazy_syms.deinit(allocator);115 self.lazy_syms.deinit(allocator);
119116
120 {117 for (self.uavs.values()) |*meta| {
121 var it = self.uavs.iterator();118 meta.exports.deinit(allocator);
122 while (it.next()) |entry| {
123 entry.value_ptr.exports.deinit(allocator);
124 }
125 self.uavs.deinit(allocator);
126 }119 }
120 self.uavs.deinit(allocator);
127121
128 for (self.tls_variables.values()) |*tlv| {122 for (self.tls_variables.values()) |*tlv| {
129 tlv.deinit(allocator);123 tlv.deinit(allocator);
...@@ -1721,8 +1715,8 @@ const TlsVariable = struct {...@@ -1721,8 +1715,8 @@ const TlsVariable = struct {
1721};1715};
17221716
1723const AtomList = std.ArrayListUnmanaged(Atom.Index);1717const AtomList = std.ArrayListUnmanaged(Atom.Index);
1724const NavTable = std.AutoHashMapUnmanaged(InternPool.Nav.Index, AvMetadata);1718const NavTable = std.AutoArrayHashMapUnmanaged(InternPool.Nav.Index, AvMetadata);
1725const UavTable = std.AutoHashMapUnmanaged(InternPool.Index, AvMetadata);1719const UavTable = std.AutoArrayHashMapUnmanaged(InternPool.Index, AvMetadata);
1726const LazySymbolTable = std.AutoArrayHashMapUnmanaged(InternPool.Index, LazySymbolMetadata);1720const LazySymbolTable = std.AutoArrayHashMapUnmanaged(InternPool.Index, LazySymbolMetadata);
1727const TlsTable = std.AutoArrayHashMapUnmanaged(Atom.Index, TlsVariable);1721const TlsTable = std.AutoArrayHashMapUnmanaged(Atom.Index, TlsVariable);
17281722
...@@ -1874,9 +1868,9 @@ pub const OffsetTable = struct {...@@ -1874,9 +1868,9 @@ pub const OffsetTable = struct {
18741868
1875 const x86_64 = struct {1869 const x86_64 = struct {
1876 fn writeEntry(source_addr: i64, target_addr: i64, buf: *[max_jump_seq_len]u8) ![]u8 {1870 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;
1878 var bytes = [_]u8{1872 var bytes = [_]u8{
1879 0xe8, 0x00, 0x00, 0x00, 0x00, // jmp rel321873 0xe9, 0x00, 0x00, 0x00, 0x00, // jmp rel32
1880 };1874 };
1881 assert(bytes.len == entrySize(.x86_64));1875 assert(bytes.len == entrySize(.x86_64));
1882 mem.writeInt(i32, bytes[1..][0..4], @intCast(disp), .little);1876 mem.writeInt(i32, bytes[1..][0..4], @intCast(disp), .little);