authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2025-06-09 09:05:58-04:00
committergravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2025-06-12 17:51:30+01:00
logafa07f723f956d78a4bd4c4be10ef04e86e50521
tree727dad717c38267a3ee2de671f4bffac65cf25fe
parent746137034e244d863a022b821ae0a1952d9d93c1
signaturelock-open Commit is signed but in an unrecognized format.

x86_64: implement coff relocations


4 files changed, 61 insertions(+), 24 deletions(-)

src/arch/x86_64/CodeGen.zig+1-5
......@@ -85269,11 +85269,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
8526985269 .ret => try cg.airRet(inst, false),
8527085270 .ret_safe => try cg.airRet(inst, true),
8527185271 .ret_load => try cg.airRetLoad(inst),
85272 .store, .store_safe => |air_tag| if (use_old) try cg.airStore(inst, switch (air_tag) {
85273 else => unreachable,
85274 .store => false,
85275 .store_safe => true,
85276 }) else fallback: {
85272 .store, .store_safe => |air_tag| fallback: {
8527785273 const bin_op = air_datas[@intFromEnum(inst)].bin_op;
8527885274 const ptr_ty = cg.typeOf(bin_op.lhs);
8527985275 const ptr_info = ptr_ty.ptrInfo(zcu);
src/arch/x86_64/Emit.zig+56-15
......@@ -107,10 +107,7 @@ pub fn emitMir(emit: *Emit) Error!void {
107107 nav,
108108 emit.lower.target.*,
109109 )) {
110 .mcv => |mcv| switch (mcv) {
111 else => std.debug.panic("{s}: {}\n", .{ @src().fn_name, mcv }),
112 .lea_symbol => |sym_index| sym_index,
113 },
110 .mcv => |mcv| mcv.lea_symbol,
114111 .fail => |em| {
115112 assert(emit.lower.err_msg == null);
116113 emit.lower.err_msg = em;
......@@ -154,10 +151,7 @@ pub fn emitMir(emit: *Emit) Error!void {
154151 Type.fromInterned(uav.orig_ty).ptrAlignment(emit.pt.zcu),
155152 emit.lower.src_loc,
156153 )) {
157 .mcv => |mcv| switch (mcv) {
158 else => std.debug.panic("{s}: {}\n", .{ @src().fn_name, mcv }),
159 .load_direct, .load_symbol => |sym_index| sym_index,
160 },
154 .mcv => |mcv| mcv.load_symbol,
161155 .fail => |em| {
162156 assert(emit.lower.err_msg == null);
163157 emit.lower.err_msg = em;
......@@ -207,7 +201,9 @@ pub fn emitMir(emit: *Emit) Error!void {
207201 switch (lowered_inst.encoding.mnemonic) {
208202 .call => {
209203 reloc.target.type = .branch;
210 try emit.encodeInst(lowered_inst, reloc_info);
204 if (emit.bin_file.cast(.coff)) |_| try emit.encodeInst(try .new(.none, .call, &.{
205 .{ .mem = .initRip(.ptr, 0) },
206 }, emit.lower.target), reloc_info) else try emit.encodeInst(lowered_inst, reloc_info);
211207 continue :lowered_inst;
212208 },
213209 else => {},
......@@ -284,6 +280,37 @@ pub fn emitMir(emit: *Emit) Error!void {
284280 }, emit.lower.target), reloc_info),
285281 else => unreachable,
286282 }
283 } else if (emit.bin_file.cast(.coff)) |_| {
284 if (reloc.target.is_extern) switch (lowered_inst.encoding.mnemonic) {
285 .lea => try emit.encodeInst(try .new(.none, .mov, &.{
286 lowered_inst.ops[0],
287 .{ .mem = .initRip(.ptr, 0) },
288 }, emit.lower.target), reloc_info),
289 .mov => {
290 const dst_reg = lowered_inst.ops[0].reg.to64();
291 try emit.encodeInst(try .new(.none, .mov, &.{
292 .{ .reg = dst_reg },
293 .{ .mem = .initRip(.ptr, 0) },
294 }, emit.lower.target), reloc_info);
295 try emit.encodeInst(try .new(.none, .mov, &.{
296 lowered_inst.ops[0],
297 .{ .mem = .initSib(lowered_inst.ops[reloc.op_index].mem.sib.ptr_size, .{ .base = .{
298 .reg = dst_reg,
299 } }) },
300 }, emit.lower.target), &.{});
301 },
302 else => unreachable,
303 } else switch (lowered_inst.encoding.mnemonic) {
304 .lea => try emit.encodeInst(try .new(.none, .lea, &.{
305 lowered_inst.ops[0],
306 .{ .mem = .initRip(.none, 0) },
307 }, emit.lower.target), reloc_info),
308 .mov => try emit.encodeInst(try .new(.none, .mov, &.{
309 lowered_inst.ops[0],
310 .{ .mem = .initRip(lowered_inst.ops[reloc.op_index].mem.sib.ptr_size, 0) },
311 }, emit.lower.target), reloc_info),
312 else => unreachable,
313 }
287314 } else return emit.fail("TODO implement relocs for {s}", .{
288315 @tagName(emit.bin_file.tag),
289316 });
......@@ -751,6 +778,21 @@ fn encodeInst(emit: *Emit, lowered_inst: Instruction, reloc_info: []const RelocI
751778 .symbolnum = @intCast(reloc.target.index),
752779 },
753780 });
781 } else if (emit.bin_file.cast(.coff)) |coff_file| {
782 const atom_index = coff_file.getAtomIndexForSymbol(
783 .{ .sym_index = emit.atom_index, .file = null },
784 ).?;
785 try coff_file.addRelocation(atom_index, .{
786 .type = if (reloc.target.is_extern) .got else .direct,
787 .target = if (reloc.target.is_extern)
788 coff_file.getGlobalByIndex(reloc.target.index)
789 else
790 .{ .sym_index = reloc.target.index, .file = null },
791 .offset = end_offset - 4,
792 .addend = @intCast(reloc.off),
793 .pcrel = true,
794 .length = 2,
795 });
754796 } else unreachable,
755797 .branch => if (emit.bin_file.cast(.elf)) |elf_file| {
756798 const zo = elf_file.zigObjectPtr().?;
......@@ -781,13 +823,12 @@ fn encodeInst(emit: *Emit, lowered_inst: Instruction, reloc_info: []const RelocI
781823 const atom_index = coff_file.getAtomIndexForSymbol(
782824 .{ .sym_index = emit.atom_index, .file = null },
783825 ).?;
784 const target: link.File.Coff.SymbolWithLoc = if (link.File.Coff.global_symbol_bit & reloc.target.index != 0)
785 coff_file.getGlobalByIndex(link.File.Coff.global_symbol_mask & reloc.target.index)
786 else
787 .{ .sym_index = reloc.target.index, .file = null };
788826 try coff_file.addRelocation(atom_index, .{
789 .type = .direct,
790 .target = target,
827 .type = if (reloc.target.is_extern) .import else .got,
828 .target = if (reloc.target.is_extern)
829 coff_file.getGlobalByIndex(reloc.target.index)
830 else
831 .{ .sym_index = reloc.target.index, .file = null },
791832 .offset = end_offset - 4,
792833 .addend = @intCast(reloc.off),
793834 .pcrel = true,
src/codegen.zig+2-2
......@@ -1015,12 +1015,12 @@ pub fn genNavRef(
10151015 .internal => {
10161016 const atom_index = try coff_file.getOrCreateAtomForNav(nav_index);
10171017 const sym_index = coff_file.getAtom(atom_index).getSymbolIndex().?;
1018 return .{ .mcv = .{ .load_got = sym_index } };
1018 return .{ .mcv = .{ .lea_symbol = sym_index } };
10191019 },
10201020 .strong, .weak => {
10211021 const global_index = try coff_file.getGlobalSymbol(nav.name.toSlice(ip), lib_name.toSlice(ip));
10221022 try coff_file.need_got_table.put(zcu.gpa, global_index, {}); // needs GOT
1023 return .{ .mcv = .{ .load_got = link.File.Coff.global_symbol_bit | global_index } };
1023 return .{ .mcv = .{ .lea_symbol = global_index } };
10241024 },
10251025 .link_once => unreachable,
10261026 }
src/link/Coff.zig+2-2
......@@ -1767,7 +1767,7 @@ pub fn lowerUav(
17671767 const atom = coff.getAtom(metadata.atom);
17681768 const existing_addr = atom.getSymbol(coff).value;
17691769 if (uav_alignment.check(existing_addr))
1770 return .{ .mcv = .{ .load_direct = atom.getSymbolIndex().? } };
1770 return .{ .mcv = .{ .load_symbol = atom.getSymbolIndex().? } };
17711771 }
17721772
17731773 var name_buf: [32]u8 = undefined;
......@@ -1799,7 +1799,7 @@ pub fn lowerUav(
17991799 .section = coff.rdata_section_index.?,
18001800 });
18011801 return .{ .mcv = .{
1802 .load_direct = coff.getAtom(atom_index).getSymbolIndex().?,
1802 .load_symbol = coff.getAtom(atom_index).getSymbolIndex().?,
18031803 } };
18041804}
18051805