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 {...@@ -674,13 +674,14 @@ fn mirCallExtern(emit: *Emit, inst: Mir.Inst.Index) !void {
674 assert(emit.mir.instructions.items(.tag)[inst] == .call_extern);674 assert(emit.mir.instructions.items(.tag)[inst] == .call_extern);
675 const relocation = emit.mir.instructions.items(.data)[inst].relocation;675 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
677 if (emit.bin_file.cast(link.File.MachO)) |macho_file| {684 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 };
684 // Add relocation to the decl.685 // Add relocation to the decl.
685 const atom = macho_file.getAtomForSymbol(.{ .sym_index = relocation.atom_index, .file = null }).?;686 const atom = macho_file.getAtomForSymbol(.{ .sym_index = relocation.atom_index, .file = null }).?;
686 const target = macho_file.getGlobalByIndex(relocation.sym_index);687 const target = macho_file.getGlobalByIndex(relocation.sym_index);
...@@ -692,8 +693,20 @@ fn mirCallExtern(emit: *Emit, inst: Mir.Inst.Index) !void {...@@ -692,8 +693,20 @@ fn mirCallExtern(emit: *Emit, inst: Mir.Inst.Index) !void {
692 .pcrel = true,693 .pcrel = true,
693 .length = 2,694 .length = 2,
694 });695 });
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 });
695 } else {708 } else {
696 return emit.fail("Implement call_extern for linking backends != MachO", .{});709 return emit.fail("Implement call_extern for linking backends != {{ COFF, MachO }}", .{});
697 }710 }
698}711}
699712
...@@ -926,6 +939,40 @@ fn mirLoadMemoryPie(emit: *Emit, inst: Mir.Inst.Index) !void {...@@ -926,6 +939,40 @@ fn mirLoadMemoryPie(emit: *Emit, inst: Mir.Inst.Index) !void {
926 else => unreachable,939 else => unreachable,
927 },940 },
928 });941 });
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 });
929 } else {976 } else {
930 return emit.fail("TODO implement load_memory for PIE GOT indirection on this platform", .{});977 return emit.fail("TODO implement load_memory for PIE GOT indirection on this platform", .{});
931 }978 }
src/link/Coff.zig+28-2
...@@ -125,9 +125,17 @@ const Entry = struct {...@@ -125,9 +125,17 @@ const Entry = struct {
125125
126pub const Reloc = struct {126pub const Reloc = struct {
127 @"type": enum {127 @"type": enum {
128 // x86, x86_64
128 got,129 got,
129 direct,130 direct,
130 import,131 import,
132
133 // aarch64
134 branch_26,
135 got_page,
136 got_pageoff,
137 page,
138 pageoff,
131 },139 },
132 target: SymbolWithLoc,140 target: SymbolWithLoc,
133 offset: u32,141 offset: u32,
...@@ -139,8 +147,17 @@ pub const Reloc = struct {...@@ -139,8 +147,17 @@ pub const Reloc = struct {
139 /// Returns an Atom which is the target node of this relocation edge (if any).147 /// Returns an Atom which is the target node of this relocation edge (if any).
140 fn getTargetAtom(self: Reloc, coff_file: *Coff) ?*Atom {148 fn getTargetAtom(self: Reloc, coff_file: *Coff) ?*Atom {
141 switch (self.@"type") {149 switch (self.@"type") {
142 .got => return coff_file.getGotAtomForSymbol(self.target),150 .got,
143 .direct => return coff_file.getAtomForSymbol(self.target),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
144 .import => return coff_file.getImportAtomForSymbol(self.target),161 .import => return coff_file.getImportAtomForSymbol(self.target),
145 }162 }
146 }163 }
...@@ -878,6 +895,15 @@ fn resolveRelocs(self: *Coff, atom: *Atom) !void {...@@ -878,6 +895,15 @@ fn resolveRelocs(self: *Coff, atom: *Atom) !void {
878 file_offset + reloc.offset,895 file_offset + reloc.offset,
879 });896 });
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
881 reloc.dirty = false;907 reloc.dirty = false;
882908
883 if (reloc.pcrel) {909 if (reloc.pcrel) {