| ... | ... | @@ -127,8 +127,6 @@ pub const Reloc = struct { |
| 127 | 127 | @"type": enum { |
| 128 | 128 | // x86, x86_64 |
| 129 | 129 | got, |
| 130 | | direct, |
| 131 | | import, |
| 132 | 130 | |
| 133 | 131 | // aarch64 |
| 134 | 132 | branch_26, |
| ... | ... | @@ -136,6 +134,10 @@ pub const Reloc = struct { |
| 136 | 134 | got_pageoff, |
| 137 | 135 | page, |
| 138 | 136 | pageoff, |
| 137 | |
| 138 | // common |
| 139 | import, |
| 140 | direct, // as unsigned, TODO split into signed for x86 |
| 139 | 141 | }, |
| 140 | 142 | target: SymbolWithLoc, |
| 141 | 143 | offset: u32, |
| ... | ... | @@ -895,40 +897,45 @@ fn resolveRelocs(self: *Coff, atom: *Atom) !void { |
| 895 | 897 | file_offset + reloc.offset, |
| 896 | 898 | }); |
| 897 | 899 | |
| 900 | reloc.dirty = false; |
| 901 | |
| 898 | 902 | switch (reloc.@"type") { |
| 899 | 903 | .branch_26 => @panic("TODO branch26"), |
| 900 | 904 | .got_page => @panic("TODO got_page"), |
| 901 | 905 | .got_pageoff => @panic("TODO got_pageoff"), |
| 902 | 906 | .page => @panic("TODO page"), |
| 903 | 907 | .pageoff => @panic("TODO pageoff"), |
| 904 | | else => {}, |
| 905 | | } |
| 906 | | |
| 907 | | reloc.dirty = false; |
| 908 | 908 | |
| 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 | } |
| 932 | 939 | }, |
| 933 | 940 | } |
| 934 | 941 | } |