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 {...@@ -85,14 +85,15 @@ pub fn emitMir(emit: *Emit) Error!void {
85 @tagName(emit.lower.bin_file.tag),85 @tagName(emit.lower.bin_file.tag),
86 }),86 }),
87 .linker_reloc => |data| if (emit.lower.bin_file.cast(link.File.Elf)) |elf_file| {87 .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;
88 const atom = elf_file.symbol(data.atom_index).atom(elf_file).?;89 const atom = elf_file.symbol(data.atom_index).atom(elf_file).?;
89 const sym_index = elf_file.zigObjectPtr().?.symbol(data.sym_index);90 const sym_index = elf_file.zigObjectPtr().?.symbol(data.sym_index);
90 const sym = elf_file.symbol(sym_index);91 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) {
92 _ = try sym.getOrCreateZigGotEntry(sym_index, elf_file);93 _ = try sym.getOrCreateZigGotEntry(sym_index, elf_file);
93 }94 }
94 if (emit.lower.bin_file.options.pic) {95 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)
96 link.File.Elf.R_X86_64_ZIG_GOTPCREL97 link.File.Elf.R_X86_64_ZIG_GOTPCREL
97 else if (sym.flags.needs_got)98 else if (sym.flags.needs_got)
98 std.elf.R_X86_64_GOTPCREL99 std.elf.R_X86_64_GOTPCREL
...@@ -104,7 +105,7 @@ pub fn emitMir(emit: *Emit) Error!void {...@@ -104,7 +105,7 @@ pub fn emitMir(emit: *Emit) Error!void {
104 .r_addend = -4,105 .r_addend = -4,
105 });106 });
106 } else {107 } 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)
108 link.File.Elf.R_X86_64_ZIG_GOT32109 link.File.Elf.R_X86_64_ZIG_GOT32
109 else if (sym.flags.needs_got)110 else if (sym.flags.needs_got)
110 std.elf.R_X86_64_GOT32111 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 {...@@ -319,6 +319,15 @@ fn reloc(lower: *Lower, target: Reloc.Target) Immediate {
319}319}
320320
321fn emit(lower: *Lower, prefix: Prefix, mnemonic: Mnemonic, ops: []const Operand) Error!void {321fn 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;
322 var emit_prefix = prefix;331 var emit_prefix = prefix;
323 var emit_mnemonic = mnemonic;332 var emit_mnemonic = mnemonic;
324 var emit_ops_storage: [4]Operand = undefined;333 var emit_ops_storage: [4]Operand = undefined;
...@@ -334,7 +343,13 @@ fn emit(lower: *Lower, prefix: Prefix, mnemonic: Mnemonic, ops: []const Operand)...@@ -334,7 +343,13 @@ fn emit(lower: *Lower, prefix: Prefix, mnemonic: Mnemonic, ops: []const Operand)
334 assert(mem_op.sib.scale_index.scale == 0);343 assert(mem_op.sib.scale_index.scale == 0);
335 _ = lower.reloc(.{ .linker_reloc = sym });344 _ = lower.reloc(.{ .linker_reloc = sym });
336 break :op if (lower.bin_file.options.pic) switch (mnemonic) {345 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 },
338 else => unreachable,353 else => unreachable,
339 } else switch (mnemonic) {354 } else switch (mnemonic) {
340 .call => .{ .mem = Memory.sib(mem_op.sib.ptr_size, .{355 .call => .{ .mem = Memory.sib(mem_op.sib.ptr_size, .{
...@@ -344,9 +359,12 @@ fn emit(lower: *Lower, prefix: Prefix, mnemonic: Mnemonic, ops: []const Operand)...@@ -344,9 +359,12 @@ fn emit(lower: *Lower, prefix: Prefix, mnemonic: Mnemonic, ops: []const Operand)
344 emit_mnemonic = .mov;359 emit_mnemonic = .mov;
345 break :op .{ .imm = Immediate.s(0) };360 break :op .{ .imm = Immediate.s(0) };
346 },361 },
347 .mov => .{ .mem = Memory.sib(mem_op.sib.ptr_size, .{362 .mov => {
348 .base = .{ .reg = .ds },363 if (is_obj and needsZigGot(sym, lower.bin_file)) emit_mnemonic = .lea;
349 }) },364 break :op .{ .mem = Memory.sib(mem_op.sib.ptr_size, .{
365 .base = .{ .reg = .ds },
366 }) };
367 },
350 else => unreachable,368 else => unreachable,
351 };369 };
352 },370 },