authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-11-04 13:29:05+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-11-05 10:15:00+01:00
log53a9661c1a0e03c629725d898c43ae1f5b1e4eff
tree25c52fbaad52dbacd0616407ffae9a9c42402903
parent62ae365308a7ff75ab1c4629c50eec31a669bc7b

coff: generate relocations for branch, GOT, direct refs


2 files changed, 82 insertions(+), 9 deletions(-)

src/arch/aarch64/Emit.zig+54-7
......@@ -674,13 +674,14 @@ fn mirCallExtern(emit: *Emit, inst: Mir.Inst.Index) !void {
674674 assert(emit.mir.instructions.items(.tag)[inst] == .call_extern);
675675 const relocation = emit.mir.instructions.items(.data)[inst].relocation;
676676
677 const offset = blk: {
678 const offset = @intCast(u32, emit.code.items.len);
679 // bl
680 try emit.writeInstruction(Instruction.bl(0));
681 break :blk offset;
682 };
683
677684 if (emit.bin_file.cast(link.File.MachO)) |macho_file| {
678 const offset = blk: {
679 const offset = @intCast(u32, emit.code.items.len);
680 // bl
681 try emit.writeInstruction(Instruction.bl(0));
682 break :blk offset;
683 };
684685 // Add relocation to the decl.
685686 const atom = macho_file.getAtomForSymbol(.{ .sym_index = relocation.atom_index, .file = null }).?;
686687 const target = macho_file.getGlobalByIndex(relocation.sym_index);
......@@ -692,8 +693,20 @@ fn mirCallExtern(emit: *Emit, inst: Mir.Inst.Index) !void {
692693 .pcrel = true,
693694 .length = 2,
694695 });
696 } else if (emit.bin_file.cast(link.File.Coff)) |coff_file| {
697 // Add relocation to the decl.
698 const atom = coff_file.getAtomForSymbol(.{ .sym_index = relocation.atom_index, .file = null }).?;
699 const target = coff_file.getGlobalByIndex(relocation.sym_index);
700 try atom.addRelocation(coff_file, .{
701 .@"type" = .branch_26,
702 .target = target,
703 .offset = offset,
704 .addend = 0,
705 .pcrel = true,
706 .length = 2,
707 });
695708 } else {
696 return emit.fail("Implement call_extern for linking backends != MachO", .{});
709 return emit.fail("Implement call_extern for linking backends != {{ COFF, MachO }}", .{});
697710 }
698711}
699712
......@@ -926,6 +939,40 @@ fn mirLoadMemoryPie(emit: *Emit, inst: Mir.Inst.Index) !void {
926939 else => unreachable,
927940 },
928941 });
942 } else if (emit.bin_file.cast(link.File.Coff)) |coff_file| {
943 const atom = coff_file.getAtomForSymbol(.{ .sym_index = data.atom_index, .file = null }).?;
944 try atom.addRelocation(coff_file, .{
945 .target = .{ .sym_index = data.sym_index, .file = null },
946 .offset = offset,
947 .addend = 0,
948 .pcrel = true,
949 .length = 2,
950 .@"type" = switch (tag) {
951 .load_memory_got,
952 .load_memory_ptr_got,
953 => .got_page,
954 .load_memory_direct,
955 .load_memory_ptr_direct,
956 => .page,
957 else => unreachable,
958 },
959 });
960 try atom.addRelocation(coff_file, .{
961 .target = .{ .sym_index = data.sym_index, .file = null },
962 .offset = offset + 4,
963 .addend = 0,
964 .pcrel = false,
965 .length = 2,
966 .@"type" = switch (tag) {
967 .load_memory_got,
968 .load_memory_ptr_got,
969 => .got_pageoff,
970 .load_memory_direct,
971 .load_memory_ptr_direct,
972 => .pageoff,
973 else => unreachable,
974 },
975 });
929976 } else {
930977 return emit.fail("TODO implement load_memory for PIE GOT indirection on this platform", .{});
931978 }
src/link/Coff.zig+28-2
......@@ -125,9 +125,17 @@ const Entry = struct {
125125
126126pub const Reloc = struct {
127127 @"type": enum {
128 // x86, x86_64
128129 got,
129130 direct,
130131 import,
132
133 // aarch64
134 branch_26,
135 got_page,
136 got_pageoff,
137 page,
138 pageoff,
131139 },
132140 target: SymbolWithLoc,
133141 offset: u32,
......@@ -139,8 +147,17 @@ pub const Reloc = struct {
139147 /// Returns an Atom which is the target node of this relocation edge (if any).
140148 fn getTargetAtom(self: Reloc, coff_file: *Coff) ?*Atom {
141149 switch (self.@"type") {
142 .got => return coff_file.getGotAtomForSymbol(self.target),
143 .direct => return coff_file.getAtomForSymbol(self.target),
150 .got,
151 .got_page,
152 .got_pageoff,
153 => return coff_file.getGotAtomForSymbol(self.target),
154
155 .direct,
156 .branch_26,
157 .page,
158 .pageoff,
159 => return coff_file.getAtomForSymbol(self.target),
160
144161 .import => return coff_file.getImportAtomForSymbol(self.target),
145162 }
146163 }
......@@ -878,6 +895,15 @@ fn resolveRelocs(self: *Coff, atom: *Atom) !void {
878895 file_offset + reloc.offset,
879896 });
880897
898 switch (reloc.@"type") {
899 .branch_26 => @panic("TODO branch26"),
900 .got_page => @panic("TODO got_page"),
901 .got_pageoff => @panic("TODO got_pageoff"),
902 .page => @panic("TODO page"),
903 .pageoff => @panic("TODO pageoff"),
904 else => {},
905 }
906
881907 reloc.dirty = false;
882908
883909 if (reloc.pcrel) {