Commit 53a9661c1a
src/arch/aarch64/Emit.zig
@@ -674,13 +674,14 @@ fn mirCallExtern(emit: *Emit, inst: Mir.Inst.Index) !void {
assert(emit.mir.instructions.items(.tag)[inst] == .call_extern);
const relocation = emit.mir.instructions.items(.data)[inst].relocation;
+ const offset = blk: {
+ const offset = @intCast(u32, emit.code.items.len);
+ // bl
+ try emit.writeInstruction(Instruction.bl(0));
+ break :blk offset;
+ };
+
if (emit.bin_file.cast(link.File.MachO)) |macho_file| {
- const offset = blk: {
- const offset = @intCast(u32, emit.code.items.len);
- // bl
- try emit.writeInstruction(Instruction.bl(0));
- break :blk offset;
- };
// Add relocation to the decl.
const atom = macho_file.getAtomForSymbol(.{ .sym_index = relocation.atom_index, .file = null }).?;
const target = macho_file.getGlobalByIndex(relocation.sym_index);
@@ -692,8 +693,20 @@ fn mirCallExtern(emit: *Emit, inst: Mir.Inst.Index) !void {
.pcrel = true,
.length = 2,
});
+ } else if (emit.bin_file.cast(link.File.Coff)) |coff_file| {
+ // Add relocation to the decl.
+ const atom = coff_file.getAtomForSymbol(.{ .sym_index = relocation.atom_index, .file = null }).?;
+ const target = coff_file.getGlobalByIndex(relocation.sym_index);
+ try atom.addRelocation(coff_file, .{
+ .@"type" = .branch_26,
+ .target = target,
+ .offset = offset,
+ .addend = 0,
+ .pcrel = true,
+ .length = 2,
+ });
} else {
- return emit.fail("Implement call_extern for linking backends != MachO", .{});
+ return emit.fail("Implement call_extern for linking backends != {{ COFF, MachO }}", .{});
}
}
@@ -926,6 +939,40 @@ fn mirLoadMemoryPie(emit: *Emit, inst: Mir.Inst.Index) !void {
else => unreachable,
},
});
+ } else if (emit.bin_file.cast(link.File.Coff)) |coff_file| {
+ const atom = coff_file.getAtomForSymbol(.{ .sym_index = data.atom_index, .file = null }).?;
+ try atom.addRelocation(coff_file, .{
+ .target = .{ .sym_index = data.sym_index, .file = null },
+ .offset = offset,
+ .addend = 0,
+ .pcrel = true,
+ .length = 2,
+ .@"type" = switch (tag) {
+ .load_memory_got,
+ .load_memory_ptr_got,
+ => .got_page,
+ .load_memory_direct,
+ .load_memory_ptr_direct,
+ => .page,
+ else => unreachable,
+ },
+ });
+ try atom.addRelocation(coff_file, .{
+ .target = .{ .sym_index = data.sym_index, .file = null },
+ .offset = offset + 4,
+ .addend = 0,
+ .pcrel = false,
+ .length = 2,
+ .@"type" = switch (tag) {
+ .load_memory_got,
+ .load_memory_ptr_got,
+ => .got_pageoff,
+ .load_memory_direct,
+ .load_memory_ptr_direct,
+ => .pageoff,
+ else => unreachable,
+ },
+ });
} else {
return emit.fail("TODO implement load_memory for PIE GOT indirection on this platform", .{});
}
src/link/Coff.zig
@@ -125,9 +125,17 @@ const Entry = struct {
pub const Reloc = struct {
@"type": enum {
+ // x86, x86_64
got,
direct,
import,
+
+ // aarch64
+ branch_26,
+ got_page,
+ got_pageoff,
+ page,
+ pageoff,
},
target: SymbolWithLoc,
offset: u32,
@@ -139,8 +147,17 @@ pub const Reloc = struct {
/// Returns an Atom which is the target node of this relocation edge (if any).
fn getTargetAtom(self: Reloc, coff_file: *Coff) ?*Atom {
switch (self.@"type") {
- .got => return coff_file.getGotAtomForSymbol(self.target),
- .direct => return coff_file.getAtomForSymbol(self.target),
+ .got,
+ .got_page,
+ .got_pageoff,
+ => return coff_file.getGotAtomForSymbol(self.target),
+
+ .direct,
+ .branch_26,
+ .page,
+ .pageoff,
+ => return coff_file.getAtomForSymbol(self.target),
+
.import => return coff_file.getImportAtomForSymbol(self.target),
}
}
@@ -878,6 +895,15 @@ fn resolveRelocs(self: *Coff, atom: *Atom) !void {
file_offset + reloc.offset,
});
+ switch (reloc.@"type") {
+ .branch_26 => @panic("TODO branch26"),
+ .got_page => @panic("TODO got_page"),
+ .got_pageoff => @panic("TODO got_pageoff"),
+ .page => @panic("TODO page"),
+ .pageoff => @panic("TODO pageoff"),
+ else => {},
+ }
+
reloc.dirty = false;
if (reloc.pcrel) {