| ... | ... | @@ -107,10 +107,7 @@ pub fn emitMir(emit: *Emit) Error!void { |
| 107 | 107 | nav, |
| 108 | 108 | emit.lower.target.*, |
| 109 | 109 | )) { |
| 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, |
| 114 | 111 | .fail => |em| { |
| 115 | 112 | assert(emit.lower.err_msg == null); |
| 116 | 113 | emit.lower.err_msg = em; |
| ... | ... | @@ -154,10 +151,7 @@ pub fn emitMir(emit: *Emit) Error!void { |
| 154 | 151 | Type.fromInterned(uav.orig_ty).ptrAlignment(emit.pt.zcu), |
| 155 | 152 | emit.lower.src_loc, |
| 156 | 153 | )) { |
| 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, |
| 161 | 155 | .fail => |em| { |
| 162 | 156 | assert(emit.lower.err_msg == null); |
| 163 | 157 | emit.lower.err_msg = em; |
| ... | ... | @@ -207,7 +201,9 @@ pub fn emitMir(emit: *Emit) Error!void { |
| 207 | 201 | switch (lowered_inst.encoding.mnemonic) { |
| 208 | 202 | .call => { |
| 209 | 203 | 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); |
| 211 | 207 | continue :lowered_inst; |
| 212 | 208 | }, |
| 213 | 209 | else => {}, |
| ... | ... | @@ -284,6 +280,37 @@ pub fn emitMir(emit: *Emit) Error!void { |
| 284 | 280 | }, emit.lower.target), reloc_info), |
| 285 | 281 | else => unreachable, |
| 286 | 282 | } |
| 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 | } |
| 287 | 314 | } else return emit.fail("TODO implement relocs for {s}", .{ |
| 288 | 315 | @tagName(emit.bin_file.tag), |
| 289 | 316 | }); |
| ... | ... | @@ -751,6 +778,21 @@ fn encodeInst(emit: *Emit, lowered_inst: Instruction, reloc_info: []const RelocI |
| 751 | 778 | .symbolnum = @intCast(reloc.target.index), |
| 752 | 779 | }, |
| 753 | 780 | }); |
| 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 | }); |
| 754 | 796 | } else unreachable, |
| 755 | 797 | .branch => if (emit.bin_file.cast(.elf)) |elf_file| { |
| 756 | 798 | const zo = elf_file.zigObjectPtr().?; |
| ... | ... | @@ -781,13 +823,12 @@ fn encodeInst(emit: *Emit, lowered_inst: Instruction, reloc_info: []const RelocI |
| 781 | 823 | const atom_index = coff_file.getAtomIndexForSymbol( |
| 782 | 824 | .{ .sym_index = emit.atom_index, .file = null }, |
| 783 | 825 | ).?; |
| 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 }; |
| 788 | 826 | 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 }, |
| 791 | 832 | .offset = end_offset - 4, |
| 792 | 833 | .addend = @intCast(reloc.off), |
| 793 | 834 | .pcrel = true, |