From 53a9661c1a0e03c629725d898c43ae1f5b1e4eff Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Fri, 4 Nov 2022 13:29:05 +0100 Subject: [PATCH] coff: generate relocations for branch, GOT, direct refs --- src/arch/aarch64/Emit.zig | 61 ++++++++++++++++++++++++++++++++++----- src/link/Coff.zig | 30 +++++++++++++++++-- 2 files changed, 82 insertions(+), 9 deletions(-) diff --git a/src/arch/aarch64/Emit.zig b/src/arch/aarch64/Emit.zig index 8794890e9e..d8b35cd2b4 100644 --- a/src/arch/aarch64/Emit.zig +++ b/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", .{}); } diff --git a/src/link/Coff.zig b/src/link/Coff.zig index ee5804b79a..f21289001e 100644 --- a/src/link/Coff.zig +++ b/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) {