authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-11-02 13:21:25+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-11-04 09:11:37+01:00
logd2c4597eb5fcaba07f15c22092fc8c42c8b70ee3
tree9f2909dba23d0bdb715ecdcb7e0889be3a5170ac
parentccb2afacc00264897cc474befc13f36239c91b03

x86_64: rewrite .got.zig movs to standard loads when emitting objects


2 files changed, 26 insertions(+), 7 deletions(-)

src/arch/x86_64/Emit.zig+4-3
......@@ -85,14 +85,15 @@ pub fn emitMir(emit: *Emit) Error!void {
8585 @tagName(emit.lower.bin_file.tag),
8686 }),
8787 .linker_reloc => |data| if (emit.lower.bin_file.cast(link.File.Elf)) |elf_file| {
88 const is_obj = emit.lower.bin_file.options.effectiveOutputMode() == .Obj;
8889 const atom = elf_file.symbol(data.atom_index).atom(elf_file).?;
8990 const sym_index = elf_file.zigObjectPtr().?.symbol(data.sym_index);
9091 const sym = elf_file.symbol(sym_index);
91 if (sym.flags.needs_zig_got and emit.lower.bin_file.options.effectiveOutputMode() != .Obj) {
92 if (sym.flags.needs_zig_got and !is_obj) {
9293 _ = try sym.getOrCreateZigGotEntry(sym_index, elf_file);
9394 }
9495 if (emit.lower.bin_file.options.pic) {
95 const r_type: u32 = if (sym.flags.needs_zig_got)
96 const r_type: u32 = if (sym.flags.needs_zig_got and !is_obj)
9697 link.File.Elf.R_X86_64_ZIG_GOTPCREL
9798 else if (sym.flags.needs_got)
9899 std.elf.R_X86_64_GOTPCREL
......@@ -104,7 +105,7 @@ pub fn emitMir(emit: *Emit) Error!void {
104105 .r_addend = -4,
105106 });
106107 } else {
107 const r_type: u32 = if (sym.flags.needs_zig_got)
108 const r_type: u32 = if (sym.flags.needs_zig_got and !is_obj)
108109 link.File.Elf.R_X86_64_ZIG_GOT32
109110 else if (sym.flags.needs_got)
110111 std.elf.R_X86_64_GOT32
src/arch/x86_64/Lower.zig+22-4
......@@ -319,6 +319,15 @@ fn reloc(lower: *Lower, target: Reloc.Target) Immediate {
319319}
320320
321321fn emit(lower: *Lower, prefix: Prefix, mnemonic: Mnemonic, ops: []const Operand) Error!void {
322 const needsZigGot = struct {
323 fn needsZigGot(sym: bits.Symbol, ctx: *link.File) bool {
324 const elf_file = ctx.cast(link.File.Elf).?;
325 const sym_index = elf_file.zigObjectPtr().?.symbol(sym.sym_index);
326 return elf_file.symbol(sym_index).flags.needs_zig_got;
327 }
328 }.needsZigGot;
329
330 const is_obj = lower.bin_file.options.effectiveOutputMode() == .Obj;
322331 var emit_prefix = prefix;
323332 var emit_mnemonic = mnemonic;
324333 var emit_ops_storage: [4]Operand = undefined;
......@@ -334,7 +343,13 @@ fn emit(lower: *Lower, prefix: Prefix, mnemonic: Mnemonic, ops: []const Operand)
334343 assert(mem_op.sib.scale_index.scale == 0);
335344 _ = lower.reloc(.{ .linker_reloc = sym });
336345 break :op if (lower.bin_file.options.pic) switch (mnemonic) {
337 .mov, .lea => .{ .mem = Memory.rip(mem_op.sib.ptr_size, 0) },
346 .lea => {
347 break :op .{ .mem = Memory.rip(mem_op.sib.ptr_size, 0) };
348 },
349 .mov => {
350 if (is_obj and needsZigGot(sym, lower.bin_file)) emit_mnemonic = .lea;
351 break :op .{ .mem = Memory.rip(mem_op.sib.ptr_size, 0) };
352 },
338353 else => unreachable,
339354 } else switch (mnemonic) {
340355 .call => .{ .mem = Memory.sib(mem_op.sib.ptr_size, .{
......@@ -344,9 +359,12 @@ fn emit(lower: *Lower, prefix: Prefix, mnemonic: Mnemonic, ops: []const Operand)
344359 emit_mnemonic = .mov;
345360 break :op .{ .imm = Immediate.s(0) };
346361 },
347 .mov => .{ .mem = Memory.sib(mem_op.sib.ptr_size, .{
348 .base = .{ .reg = .ds },
349 }) },
362 .mov => {
363 if (is_obj and needsZigGot(sym, lower.bin_file)) emit_mnemonic = .lea;
364 break :op .{ .mem = Memory.sib(mem_op.sib.ptr_size, .{
365 .base = .{ .reg = .ds },
366 }) };
367 },
350368 else => unreachable,
351369 };
352370 },