mirror of
https://github.com/ziglang/zig.git
synced 2026-02-13 21:08:36 +00:00
x86_64: implement coff relocations
This commit is contained in:
parent
746137034e
commit
afa07f723f
@ -85269,11 +85269,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
|
||||
.ret => try cg.airRet(inst, false),
|
||||
.ret_safe => try cg.airRet(inst, true),
|
||||
.ret_load => try cg.airRetLoad(inst),
|
||||
.store, .store_safe => |air_tag| if (use_old) try cg.airStore(inst, switch (air_tag) {
|
||||
else => unreachable,
|
||||
.store => false,
|
||||
.store_safe => true,
|
||||
}) else fallback: {
|
||||
.store, .store_safe => |air_tag| fallback: {
|
||||
const bin_op = air_datas[@intFromEnum(inst)].bin_op;
|
||||
const ptr_ty = cg.typeOf(bin_op.lhs);
|
||||
const ptr_info = ptr_ty.ptrInfo(zcu);
|
||||
|
||||
@ -107,10 +107,7 @@ pub fn emitMir(emit: *Emit) Error!void {
|
||||
nav,
|
||||
emit.lower.target.*,
|
||||
)) {
|
||||
.mcv => |mcv| switch (mcv) {
|
||||
else => std.debug.panic("{s}: {}\n", .{ @src().fn_name, mcv }),
|
||||
.lea_symbol => |sym_index| sym_index,
|
||||
},
|
||||
.mcv => |mcv| mcv.lea_symbol,
|
||||
.fail => |em| {
|
||||
assert(emit.lower.err_msg == null);
|
||||
emit.lower.err_msg = em;
|
||||
@ -154,10 +151,7 @@ pub fn emitMir(emit: *Emit) Error!void {
|
||||
Type.fromInterned(uav.orig_ty).ptrAlignment(emit.pt.zcu),
|
||||
emit.lower.src_loc,
|
||||
)) {
|
||||
.mcv => |mcv| switch (mcv) {
|
||||
else => std.debug.panic("{s}: {}\n", .{ @src().fn_name, mcv }),
|
||||
.load_direct, .load_symbol => |sym_index| sym_index,
|
||||
},
|
||||
.mcv => |mcv| mcv.load_symbol,
|
||||
.fail => |em| {
|
||||
assert(emit.lower.err_msg == null);
|
||||
emit.lower.err_msg = em;
|
||||
@ -207,7 +201,9 @@ pub fn emitMir(emit: *Emit) Error!void {
|
||||
switch (lowered_inst.encoding.mnemonic) {
|
||||
.call => {
|
||||
reloc.target.type = .branch;
|
||||
try emit.encodeInst(lowered_inst, reloc_info);
|
||||
if (emit.bin_file.cast(.coff)) |_| try emit.encodeInst(try .new(.none, .call, &.{
|
||||
.{ .mem = .initRip(.ptr, 0) },
|
||||
}, emit.lower.target), reloc_info) else try emit.encodeInst(lowered_inst, reloc_info);
|
||||
continue :lowered_inst;
|
||||
},
|
||||
else => {},
|
||||
@ -284,6 +280,37 @@ pub fn emitMir(emit: *Emit) Error!void {
|
||||
}, emit.lower.target), reloc_info),
|
||||
else => unreachable,
|
||||
}
|
||||
} else if (emit.bin_file.cast(.coff)) |_| {
|
||||
if (reloc.target.is_extern) switch (lowered_inst.encoding.mnemonic) {
|
||||
.lea => try emit.encodeInst(try .new(.none, .mov, &.{
|
||||
lowered_inst.ops[0],
|
||||
.{ .mem = .initRip(.ptr, 0) },
|
||||
}, emit.lower.target), reloc_info),
|
||||
.mov => {
|
||||
const dst_reg = lowered_inst.ops[0].reg.to64();
|
||||
try emit.encodeInst(try .new(.none, .mov, &.{
|
||||
.{ .reg = dst_reg },
|
||||
.{ .mem = .initRip(.ptr, 0) },
|
||||
}, emit.lower.target), reloc_info);
|
||||
try emit.encodeInst(try .new(.none, .mov, &.{
|
||||
lowered_inst.ops[0],
|
||||
.{ .mem = .initSib(lowered_inst.ops[reloc.op_index].mem.sib.ptr_size, .{ .base = .{
|
||||
.reg = dst_reg,
|
||||
} }) },
|
||||
}, emit.lower.target), &.{});
|
||||
},
|
||||
else => unreachable,
|
||||
} else switch (lowered_inst.encoding.mnemonic) {
|
||||
.lea => try emit.encodeInst(try .new(.none, .lea, &.{
|
||||
lowered_inst.ops[0],
|
||||
.{ .mem = .initRip(.none, 0) },
|
||||
}, emit.lower.target), reloc_info),
|
||||
.mov => try emit.encodeInst(try .new(.none, .mov, &.{
|
||||
lowered_inst.ops[0],
|
||||
.{ .mem = .initRip(lowered_inst.ops[reloc.op_index].mem.sib.ptr_size, 0) },
|
||||
}, emit.lower.target), reloc_info),
|
||||
else => unreachable,
|
||||
}
|
||||
} else return emit.fail("TODO implement relocs for {s}", .{
|
||||
@tagName(emit.bin_file.tag),
|
||||
});
|
||||
@ -751,6 +778,21 @@ fn encodeInst(emit: *Emit, lowered_inst: Instruction, reloc_info: []const RelocI
|
||||
.symbolnum = @intCast(reloc.target.index),
|
||||
},
|
||||
});
|
||||
} else if (emit.bin_file.cast(.coff)) |coff_file| {
|
||||
const atom_index = coff_file.getAtomIndexForSymbol(
|
||||
.{ .sym_index = emit.atom_index, .file = null },
|
||||
).?;
|
||||
try coff_file.addRelocation(atom_index, .{
|
||||
.type = if (reloc.target.is_extern) .got else .direct,
|
||||
.target = if (reloc.target.is_extern)
|
||||
coff_file.getGlobalByIndex(reloc.target.index)
|
||||
else
|
||||
.{ .sym_index = reloc.target.index, .file = null },
|
||||
.offset = end_offset - 4,
|
||||
.addend = @intCast(reloc.off),
|
||||
.pcrel = true,
|
||||
.length = 2,
|
||||
});
|
||||
} else unreachable,
|
||||
.branch => if (emit.bin_file.cast(.elf)) |elf_file| {
|
||||
const zo = elf_file.zigObjectPtr().?;
|
||||
@ -781,13 +823,12 @@ fn encodeInst(emit: *Emit, lowered_inst: Instruction, reloc_info: []const RelocI
|
||||
const atom_index = coff_file.getAtomIndexForSymbol(
|
||||
.{ .sym_index = emit.atom_index, .file = null },
|
||||
).?;
|
||||
const target: link.File.Coff.SymbolWithLoc = if (link.File.Coff.global_symbol_bit & reloc.target.index != 0)
|
||||
coff_file.getGlobalByIndex(link.File.Coff.global_symbol_mask & reloc.target.index)
|
||||
else
|
||||
.{ .sym_index = reloc.target.index, .file = null };
|
||||
try coff_file.addRelocation(atom_index, .{
|
||||
.type = .direct,
|
||||
.target = target,
|
||||
.type = if (reloc.target.is_extern) .import else .got,
|
||||
.target = if (reloc.target.is_extern)
|
||||
coff_file.getGlobalByIndex(reloc.target.index)
|
||||
else
|
||||
.{ .sym_index = reloc.target.index, .file = null },
|
||||
.offset = end_offset - 4,
|
||||
.addend = @intCast(reloc.off),
|
||||
.pcrel = true,
|
||||
|
||||
@ -1015,12 +1015,12 @@ pub fn genNavRef(
|
||||
.internal => {
|
||||
const atom_index = try coff_file.getOrCreateAtomForNav(nav_index);
|
||||
const sym_index = coff_file.getAtom(atom_index).getSymbolIndex().?;
|
||||
return .{ .mcv = .{ .load_got = sym_index } };
|
||||
return .{ .mcv = .{ .lea_symbol = sym_index } };
|
||||
},
|
||||
.strong, .weak => {
|
||||
const global_index = try coff_file.getGlobalSymbol(nav.name.toSlice(ip), lib_name.toSlice(ip));
|
||||
try coff_file.need_got_table.put(zcu.gpa, global_index, {}); // needs GOT
|
||||
return .{ .mcv = .{ .load_got = link.File.Coff.global_symbol_bit | global_index } };
|
||||
return .{ .mcv = .{ .lea_symbol = global_index } };
|
||||
},
|
||||
.link_once => unreachable,
|
||||
}
|
||||
|
||||
@ -1767,7 +1767,7 @@ pub fn lowerUav(
|
||||
const atom = coff.getAtom(metadata.atom);
|
||||
const existing_addr = atom.getSymbol(coff).value;
|
||||
if (uav_alignment.check(existing_addr))
|
||||
return .{ .mcv = .{ .load_direct = atom.getSymbolIndex().? } };
|
||||
return .{ .mcv = .{ .load_symbol = atom.getSymbolIndex().? } };
|
||||
}
|
||||
|
||||
var name_buf: [32]u8 = undefined;
|
||||
@ -1799,7 +1799,7 @@ pub fn lowerUav(
|
||||
.section = coff.rdata_section_index.?,
|
||||
});
|
||||
return .{ .mcv = .{
|
||||
.load_direct = coff.getAtom(atom_index).getSymbolIndex().?,
|
||||
.load_symbol = coff.getAtom(atom_index).getSymbolIndex().?,
|
||||
} };
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user