authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-11-04 13:55:15+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-11-05 10:15:00+01:00
logd80203b55d0550f94824ee2c108af259a666357c
tree4f47835a50373eaae75bea5db128e25889d51449
parent53a9661c1a0e03c629725d898c43ae1f5b1e4eff

coff: clean up relocation handling between x86 and arm64


1 files changed, 36 insertions(+), 29 deletions(-)

src/link/Coff.zig+36-29
......@@ -127,8 +127,6 @@ pub const Reloc = struct {
127127 @"type": enum {
128128 // x86, x86_64
129129 got,
130 direct,
131 import,
132130
133131 // aarch64
134132 branch_26,
......@@ -136,6 +134,10 @@ pub const Reloc = struct {
136134 got_pageoff,
137135 page,
138136 pageoff,
137
138 // common
139 import,
140 direct, // as unsigned, TODO split into signed for x86
139141 },
140142 target: SymbolWithLoc,
141143 offset: u32,
......@@ -895,40 +897,45 @@ fn resolveRelocs(self: *Coff, atom: *Atom) !void {
895897 file_offset + reloc.offset,
896898 });
897899
900 reloc.dirty = false;
901
898902 switch (reloc.@"type") {
899903 .branch_26 => @panic("TODO branch26"),
900904 .got_page => @panic("TODO got_page"),
901905 .got_pageoff => @panic("TODO got_pageoff"),
902906 .page => @panic("TODO page"),
903907 .pageoff => @panic("TODO pageoff"),
904 else => {},
905 }
906
907 reloc.dirty = false;
908908
909 if (reloc.pcrel) {
910 const source_vaddr = source_sym.value + reloc.offset;
911 const disp =
912 @intCast(i32, target_vaddr_with_addend) - @intCast(i32, source_vaddr) - 4;
913 try self.base.file.?.pwriteAll(mem.asBytes(&disp), file_offset + reloc.offset);
914 continue;
915 }
916
917 switch (self.ptr_width) {
918 .p32 => try self.base.file.?.pwriteAll(
919 mem.asBytes(&@intCast(u32, target_vaddr_with_addend + default_image_base_exe)),
920 file_offset + reloc.offset,
921 ),
922 .p64 => switch (reloc.length) {
923 2 => try self.base.file.?.pwriteAll(
924 mem.asBytes(&@truncate(u32, target_vaddr_with_addend + default_image_base_exe)),
925 file_offset + reloc.offset,
926 ),
927 3 => try self.base.file.?.pwriteAll(
928 mem.asBytes(&(target_vaddr_with_addend + default_image_base_exe)),
929 file_offset + reloc.offset,
930 ),
931 else => unreachable,
909 .got, .import => {
910 assert(reloc.pcrel);
911 const source_vaddr = source_sym.value + reloc.offset;
912 const disp =
913 @intCast(i32, target_vaddr_with_addend) - @intCast(i32, source_vaddr) - 4;
914 try self.base.file.?.pwriteAll(mem.asBytes(&disp), file_offset + reloc.offset);
915 },
916 .direct => {
917 if (reloc.pcrel) {
918 const source_vaddr = source_sym.value + reloc.offset;
919 const disp =
920 @intCast(i32, target_vaddr_with_addend) - @intCast(i32, source_vaddr) - 4;
921 try self.base.file.?.pwriteAll(mem.asBytes(&disp), file_offset + reloc.offset);
922 } else switch (self.ptr_width) {
923 .p32 => try self.base.file.?.pwriteAll(
924 mem.asBytes(&@intCast(u32, target_vaddr_with_addend + default_image_base_exe)),
925 file_offset + reloc.offset,
926 ),
927 .p64 => switch (reloc.length) {
928 2 => try self.base.file.?.pwriteAll(
929 mem.asBytes(&@truncate(u32, target_vaddr_with_addend + default_image_base_exe)),
930 file_offset + reloc.offset,
931 ),
932 3 => try self.base.file.?.pwriteAll(
933 mem.asBytes(&(target_vaddr_with_addend + default_image_base_exe)),
934 file_offset + reloc.offset,
935 ),
936 else => unreachable,
937 },
938 }
932939 },
933940 }
934941 }