Skip to content

Commit e972916

Browse files
jacobly0mlugg
authored andcommitted
x86_64: implement coff relocations
1 parent 55468a8 commit e972916

File tree

4 files changed

+61
-24
lines changed

4 files changed

+61
-24
lines changed

src/arch/x86_64/CodeGen.zig

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Lines changed: 56 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -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

0 commit comments

Comments
 (0)