mirror of
https://github.com/ziglang/zig.git
synced 2025-12-19 04:33:09 +00:00
x86_64: rewrite .got.zig movs to standard loads when emitting objects
This commit is contained in:
parent
ccb2afacc0
commit
d2c4597eb5
@ -85,14 +85,15 @@ pub fn emitMir(emit: *Emit) Error!void {
|
|||||||
@tagName(emit.lower.bin_file.tag),
|
@tagName(emit.lower.bin_file.tag),
|
||||||
}),
|
}),
|
||||||
.linker_reloc => |data| if (emit.lower.bin_file.cast(link.File.Elf)) |elf_file| {
|
.linker_reloc => |data| if (emit.lower.bin_file.cast(link.File.Elf)) |elf_file| {
|
||||||
|
const is_obj = emit.lower.bin_file.options.effectiveOutputMode() == .Obj;
|
||||||
const atom = elf_file.symbol(data.atom_index).atom(elf_file).?;
|
const atom = elf_file.symbol(data.atom_index).atom(elf_file).?;
|
||||||
const sym_index = elf_file.zigObjectPtr().?.symbol(data.sym_index);
|
const sym_index = elf_file.zigObjectPtr().?.symbol(data.sym_index);
|
||||||
const sym = elf_file.symbol(sym_index);
|
const sym = elf_file.symbol(sym_index);
|
||||||
if (sym.flags.needs_zig_got and emit.lower.bin_file.options.effectiveOutputMode() != .Obj) {
|
if (sym.flags.needs_zig_got and !is_obj) {
|
||||||
_ = try sym.getOrCreateZigGotEntry(sym_index, elf_file);
|
_ = try sym.getOrCreateZigGotEntry(sym_index, elf_file);
|
||||||
}
|
}
|
||||||
if (emit.lower.bin_file.options.pic) {
|
if (emit.lower.bin_file.options.pic) {
|
||||||
const r_type: u32 = if (sym.flags.needs_zig_got)
|
const r_type: u32 = if (sym.flags.needs_zig_got and !is_obj)
|
||||||
link.File.Elf.R_X86_64_ZIG_GOTPCREL
|
link.File.Elf.R_X86_64_ZIG_GOTPCREL
|
||||||
else if (sym.flags.needs_got)
|
else if (sym.flags.needs_got)
|
||||||
std.elf.R_X86_64_GOTPCREL
|
std.elf.R_X86_64_GOTPCREL
|
||||||
@ -104,7 +105,7 @@ pub fn emitMir(emit: *Emit) Error!void {
|
|||||||
.r_addend = -4,
|
.r_addend = -4,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
const r_type: u32 = if (sym.flags.needs_zig_got)
|
const r_type: u32 = if (sym.flags.needs_zig_got and !is_obj)
|
||||||
link.File.Elf.R_X86_64_ZIG_GOT32
|
link.File.Elf.R_X86_64_ZIG_GOT32
|
||||||
else if (sym.flags.needs_got)
|
else if (sym.flags.needs_got)
|
||||||
std.elf.R_X86_64_GOT32
|
std.elf.R_X86_64_GOT32
|
||||||
|
|||||||
@ -319,6 +319,15 @@ fn reloc(lower: *Lower, target: Reloc.Target) Immediate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn emit(lower: *Lower, prefix: Prefix, mnemonic: Mnemonic, ops: []const Operand) Error!void {
|
fn emit(lower: *Lower, prefix: Prefix, mnemonic: Mnemonic, ops: []const Operand) Error!void {
|
||||||
|
const needsZigGot = struct {
|
||||||
|
fn needsZigGot(sym: bits.Symbol, ctx: *link.File) bool {
|
||||||
|
const elf_file = ctx.cast(link.File.Elf).?;
|
||||||
|
const sym_index = elf_file.zigObjectPtr().?.symbol(sym.sym_index);
|
||||||
|
return elf_file.symbol(sym_index).flags.needs_zig_got;
|
||||||
|
}
|
||||||
|
}.needsZigGot;
|
||||||
|
|
||||||
|
const is_obj = lower.bin_file.options.effectiveOutputMode() == .Obj;
|
||||||
var emit_prefix = prefix;
|
var emit_prefix = prefix;
|
||||||
var emit_mnemonic = mnemonic;
|
var emit_mnemonic = mnemonic;
|
||||||
var emit_ops_storage: [4]Operand = undefined;
|
var emit_ops_storage: [4]Operand = undefined;
|
||||||
@ -334,7 +343,13 @@ fn emit(lower: *Lower, prefix: Prefix, mnemonic: Mnemonic, ops: []const Operand)
|
|||||||
assert(mem_op.sib.scale_index.scale == 0);
|
assert(mem_op.sib.scale_index.scale == 0);
|
||||||
_ = lower.reloc(.{ .linker_reloc = sym });
|
_ = lower.reloc(.{ .linker_reloc = sym });
|
||||||
break :op if (lower.bin_file.options.pic) switch (mnemonic) {
|
break :op if (lower.bin_file.options.pic) switch (mnemonic) {
|
||||||
.mov, .lea => .{ .mem = Memory.rip(mem_op.sib.ptr_size, 0) },
|
.lea => {
|
||||||
|
break :op .{ .mem = Memory.rip(mem_op.sib.ptr_size, 0) };
|
||||||
|
},
|
||||||
|
.mov => {
|
||||||
|
if (is_obj and needsZigGot(sym, lower.bin_file)) emit_mnemonic = .lea;
|
||||||
|
break :op .{ .mem = Memory.rip(mem_op.sib.ptr_size, 0) };
|
||||||
|
},
|
||||||
else => unreachable,
|
else => unreachable,
|
||||||
} else switch (mnemonic) {
|
} else switch (mnemonic) {
|
||||||
.call => .{ .mem = Memory.sib(mem_op.sib.ptr_size, .{
|
.call => .{ .mem = Memory.sib(mem_op.sib.ptr_size, .{
|
||||||
@ -344,9 +359,12 @@ fn emit(lower: *Lower, prefix: Prefix, mnemonic: Mnemonic, ops: []const Operand)
|
|||||||
emit_mnemonic = .mov;
|
emit_mnemonic = .mov;
|
||||||
break :op .{ .imm = Immediate.s(0) };
|
break :op .{ .imm = Immediate.s(0) };
|
||||||
},
|
},
|
||||||
.mov => .{ .mem = Memory.sib(mem_op.sib.ptr_size, .{
|
.mov => {
|
||||||
.base = .{ .reg = .ds },
|
if (is_obj and needsZigGot(sym, lower.bin_file)) emit_mnemonic = .lea;
|
||||||
}) },
|
break :op .{ .mem = Memory.sib(mem_op.sib.ptr_size, .{
|
||||||
|
.base = .{ .reg = .ds },
|
||||||
|
}) };
|
||||||
|
},
|
||||||
else => unreachable,
|
else => unreachable,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user