| ... | ... | @@ -384,7 +384,10 @@ pub fn scanRelocsRequiresCode(self: Atom, elf_file: *Elf) bool { |
| 384 | 384 | const cpu_arch = elf_file.getTarget().cpu.arch; |
| 385 | 385 | for (self.relocs(elf_file)) |rel| { |
| 386 | 386 | switch (cpu_arch) { |
| 387 | | .x86_64 => if (rel.r_type() == elf.R_X86_64_GOTTPOFF) return true, |
| 387 | .x86_64 => { |
| 388 | const r_type: elf.R_X86_64 = @enumFromInt(rel.r_type()); |
| 389 | if (r_type == .R_X86_64_GOTTPOFF) return true; |
| 390 | }, |
| 388 | 391 | else => {}, |
| 389 | 392 | } |
| 390 | 393 | } |
| ... | ... | @@ -836,8 +839,9 @@ const x86_64 = struct { |
| 836 | 839 | var i: usize = 0; |
| 837 | 840 | while (i < rels.len) : (i += 1) { |
| 838 | 841 | const rel = rels[i]; |
| 842 | const r_type: elf.R_X86_64 = @enumFromInt(rel.r_type()); |
| 839 | 843 | |
| 840 | | if (rel.r_type() == elf.R_X86_64_NONE) continue; |
| 844 | if (r_type == .R_X86_64_NONE) continue; |
| 841 | 845 | |
| 842 | 846 | const r_offset = std.math.cast(usize, rel.r_offset) orelse return error.Overflow; |
| 843 | 847 | |
| ... | ... | @@ -869,41 +873,41 @@ const x86_64 = struct { |
| 869 | 873 | |
| 870 | 874 | // While traversing relocations, mark symbols that require special handling such as |
| 871 | 875 | // pointer indirection via GOT, or a stub trampoline via PLT. |
| 872 | | switch (rel.r_type()) { |
| 873 | | elf.R_X86_64_64 => { |
| 876 | switch (r_type) { |
| 877 | .R_X86_64_64 => { |
| 874 | 878 | try atom.scanReloc(symbol, rel, dynAbsRelocAction(symbol, elf_file), elf_file); |
| 875 | 879 | }, |
| 876 | 880 | |
| 877 | | elf.R_X86_64_32, |
| 878 | | elf.R_X86_64_32S, |
| 881 | .R_X86_64_32, |
| 882 | .R_X86_64_32S, |
| 879 | 883 | => { |
| 880 | 884 | try atom.scanReloc(symbol, rel, dynAbsRelocAction(symbol, elf_file), elf_file); |
| 881 | 885 | }, |
| 882 | 886 | |
| 883 | | elf.R_X86_64_GOT32, |
| 884 | | elf.R_X86_64_GOTPC32, |
| 885 | | elf.R_X86_64_GOTPC64, |
| 886 | | elf.R_X86_64_GOTPCREL, |
| 887 | | elf.R_X86_64_GOTPCREL64, |
| 888 | | elf.R_X86_64_GOTPCRELX, |
| 889 | | elf.R_X86_64_REX_GOTPCRELX, |
| 887 | .R_X86_64_GOT32, |
| 888 | .R_X86_64_GOTPC32, |
| 889 | .R_X86_64_GOTPC64, |
| 890 | .R_X86_64_GOTPCREL, |
| 891 | .R_X86_64_GOTPCREL64, |
| 892 | .R_X86_64_GOTPCRELX, |
| 893 | .R_X86_64_REX_GOTPCRELX, |
| 890 | 894 | => { |
| 891 | 895 | symbol.flags.needs_got = true; |
| 892 | 896 | }, |
| 893 | 897 | |
| 894 | | elf.R_X86_64_PLT32, |
| 895 | | elf.R_X86_64_PLTOFF64, |
| 898 | .R_X86_64_PLT32, |
| 899 | .R_X86_64_PLTOFF64, |
| 896 | 900 | => { |
| 897 | 901 | if (symbol.flags.import) { |
| 898 | 902 | symbol.flags.needs_plt = true; |
| 899 | 903 | } |
| 900 | 904 | }, |
| 901 | 905 | |
| 902 | | elf.R_X86_64_PC32 => { |
| 906 | .R_X86_64_PC32 => { |
| 903 | 907 | try atom.scanReloc(symbol, rel, pcRelocAction(symbol, elf_file), elf_file); |
| 904 | 908 | }, |
| 905 | 909 | |
| 906 | | elf.R_X86_64_TLSGD => { |
| 910 | .R_X86_64_TLSGD => { |
| 907 | 911 | // TODO verify followed by appropriate relocation such as PLT32 __tls_get_addr |
| 908 | 912 | |
| 909 | 913 | if (is_static or (!symbol.flags.import and !is_dyn_lib)) { |
| ... | ... | @@ -918,7 +922,7 @@ const x86_64 = struct { |
| 918 | 922 | } |
| 919 | 923 | }, |
| 920 | 924 | |
| 921 | | elf.R_X86_64_TLSLD => { |
| 925 | .R_X86_64_TLSLD => { |
| 922 | 926 | // TODO verify followed by appropriate relocation such as PLT32 __tls_get_addr |
| 923 | 927 | |
| 924 | 928 | if (is_static or !is_dyn_lib) { |
| ... | ... | @@ -930,7 +934,7 @@ const x86_64 = struct { |
| 930 | 934 | } |
| 931 | 935 | }, |
| 932 | 936 | |
| 933 | | elf.R_X86_64_GOTTPOFF => { |
| 937 | .R_X86_64_GOTTPOFF => { |
| 934 | 938 | const should_relax = blk: { |
| 935 | 939 | if (is_dyn_lib or symbol.flags.import) break :blk false; |
| 936 | 940 | if (!x86_64.canRelaxGotTpOff(code.?[r_offset - 3 ..])) break :blk false; |
| ... | ... | @@ -941,35 +945,37 @@ const x86_64 = struct { |
| 941 | 945 | } |
| 942 | 946 | }, |
| 943 | 947 | |
| 944 | | elf.R_X86_64_GOTPC32_TLSDESC => { |
| 948 | .R_X86_64_GOTPC32_TLSDESC => { |
| 945 | 949 | const should_relax = is_static or (!is_dyn_lib and !symbol.flags.import); |
| 946 | 950 | if (!should_relax) { |
| 947 | 951 | symbol.flags.needs_tlsdesc = true; |
| 948 | 952 | } |
| 949 | 953 | }, |
| 950 | 954 | |
| 951 | | elf.R_X86_64_TPOFF32, |
| 952 | | elf.R_X86_64_TPOFF64, |
| 955 | .R_X86_64_TPOFF32, |
| 956 | .R_X86_64_TPOFF64, |
| 953 | 957 | => { |
| 954 | 958 | if (is_dyn_lib) try atom.reportPicError(symbol, rel, elf_file); |
| 955 | 959 | }, |
| 956 | 960 | |
| 957 | | elf.R_X86_64_GOTOFF64, |
| 958 | | elf.R_X86_64_DTPOFF32, |
| 959 | | elf.R_X86_64_DTPOFF64, |
| 960 | | elf.R_X86_64_SIZE32, |
| 961 | | elf.R_X86_64_SIZE64, |
| 962 | | elf.R_X86_64_TLSDESC_CALL, |
| 961 | .R_X86_64_GOTOFF64, |
| 962 | .R_X86_64_DTPOFF32, |
| 963 | .R_X86_64_DTPOFF64, |
| 964 | .R_X86_64_SIZE32, |
| 965 | .R_X86_64_SIZE64, |
| 966 | .R_X86_64_TLSDESC_CALL, |
| 963 | 967 | => {}, |
| 964 | 968 | |
| 965 | | // Zig custom relocations |
| 966 | | Elf.R_X86_64_ZIG_GOT32, |
| 967 | | Elf.R_X86_64_ZIG_GOTPCREL, |
| 968 | | => { |
| 969 | | assert(symbol.flags.has_zig_got); |
| 970 | | }, |
| 969 | else => |x| switch (@intFromEnum(x)) { |
| 970 | // Zig custom relocations |
| 971 | Elf.R_X86_64_ZIG_GOT32, |
| 972 | Elf.R_X86_64_ZIG_GOTPCREL, |
| 973 | => { |
| 974 | assert(symbol.flags.has_zig_got); |
| 975 | }, |
| 971 | 976 | |
| 972 | | else => try atom.reportUnhandledRelocError(rel, elf_file), |
| 977 | else => try atom.reportUnhandledRelocError(rel, elf_file), |
| 978 | }, |
| 973 | 979 | } |
| 974 | 980 | } |
| 975 | 981 | } |
| ... | ... | @@ -983,8 +989,8 @@ const x86_64 = struct { |
| 983 | 989 | var i: usize = 0; |
| 984 | 990 | while (i < rels.len) : (i += 1) { |
| 985 | 991 | const rel = rels[i]; |
| 986 | | const r_type = rel.r_type(); |
| 987 | | if (r_type == elf.R_X86_64_NONE) continue; |
| 992 | const r_type: elf.R_X86_64 = @enumFromInt(rel.r_type()); |
| 993 | if (r_type == .R_X86_64_NONE) continue; |
| 988 | 994 | |
| 989 | 995 | const target = switch (file_ptr) { |
| 990 | 996 | .zig_object => |x| elf_file.symbol(x.symbol(rel.r_sym())), |
| ... | ... | @@ -1022,7 +1028,7 @@ const x86_64 = struct { |
| 1022 | 1028 | const DTP = @as(i64, @intCast(elf_file.dtpAddress())); |
| 1023 | 1029 | |
| 1024 | 1030 | relocs_log.debug(" {s}: {x}: [{x} => {x}] G({x}) ZG({x}) ({s})", .{ |
| 1025 | | relocation.fmtRelocType(r_type, .x86_64), |
| 1031 | @tagName(r_type), |
| 1026 | 1032 | r_offset, |
| 1027 | 1033 | P, |
| 1028 | 1034 | S + A, |
| ... | ... | @@ -1033,10 +1039,10 @@ const x86_64 = struct { |
| 1033 | 1039 | |
| 1034 | 1040 | try stream.seekTo(r_offset); |
| 1035 | 1041 | |
| 1036 | | switch (rel.r_type()) { |
| 1037 | | elf.R_X86_64_NONE => unreachable, |
| 1042 | switch (r_type) { |
| 1043 | .R_X86_64_NONE => unreachable, |
| 1038 | 1044 | |
| 1039 | | elf.R_X86_64_64 => { |
| 1045 | .R_X86_64_64 => { |
| 1040 | 1046 | try atom.resolveDynAbsReloc( |
| 1041 | 1047 | target, |
| 1042 | 1048 | rel, |
| ... | ... | @@ -1046,15 +1052,15 @@ const x86_64 = struct { |
| 1046 | 1052 | ); |
| 1047 | 1053 | }, |
| 1048 | 1054 | |
| 1049 | | elf.R_X86_64_PLT32, |
| 1050 | | elf.R_X86_64_PC32, |
| 1055 | .R_X86_64_PLT32, |
| 1056 | .R_X86_64_PC32, |
| 1051 | 1057 | => try cwriter.writeInt(i32, @as(i32, @intCast(S + A - P)), .little), |
| 1052 | 1058 | |
| 1053 | | elf.R_X86_64_GOTPCREL => try cwriter.writeInt(i32, @as(i32, @intCast(G + GOT + A - P)), .little), |
| 1054 | | elf.R_X86_64_GOTPC32 => try cwriter.writeInt(i32, @as(i32, @intCast(GOT + A - P)), .little), |
| 1055 | | elf.R_X86_64_GOTPC64 => try cwriter.writeInt(i64, GOT + A - P, .little), |
| 1059 | .R_X86_64_GOTPCREL => try cwriter.writeInt(i32, @as(i32, @intCast(G + GOT + A - P)), .little), |
| 1060 | .R_X86_64_GOTPC32 => try cwriter.writeInt(i32, @as(i32, @intCast(GOT + A - P)), .little), |
| 1061 | .R_X86_64_GOTPC64 => try cwriter.writeInt(i64, GOT + A - P, .little), |
| 1056 | 1062 | |
| 1057 | | elf.R_X86_64_GOTPCRELX => { |
| 1063 | .R_X86_64_GOTPCRELX => { |
| 1058 | 1064 | if (!target.flags.import and !target.isIFunc(elf_file) and !target.isAbs(elf_file)) blk: { |
| 1059 | 1065 | x86_64.relaxGotpcrelx(code[r_offset - 2 ..]) catch break :blk; |
| 1060 | 1066 | try cwriter.writeInt(i32, @as(i32, @intCast(S + A - P)), .little); |
| ... | ... | @@ -1063,7 +1069,7 @@ const x86_64 = struct { |
| 1063 | 1069 | try cwriter.writeInt(i32, @as(i32, @intCast(G + GOT + A - P)), .little); |
| 1064 | 1070 | }, |
| 1065 | 1071 | |
| 1066 | | elf.R_X86_64_REX_GOTPCRELX => { |
| 1072 | .R_X86_64_REX_GOTPCRELX => { |
| 1067 | 1073 | if (!target.flags.import and !target.isIFunc(elf_file) and !target.isAbs(elf_file)) blk: { |
| 1068 | 1074 | x86_64.relaxRexGotpcrelx(code[r_offset - 3 ..]) catch break :blk; |
| 1069 | 1075 | try cwriter.writeInt(i32, @as(i32, @intCast(S + A - P)), .little); |
| ... | ... | @@ -1072,16 +1078,16 @@ const x86_64 = struct { |
| 1072 | 1078 | try cwriter.writeInt(i32, @as(i32, @intCast(G + GOT + A - P)), .little); |
| 1073 | 1079 | }, |
| 1074 | 1080 | |
| 1075 | | elf.R_X86_64_32 => try cwriter.writeInt(u32, @as(u32, @truncate(@as(u64, @intCast(S + A)))), .little), |
| 1076 | | elf.R_X86_64_32S => try cwriter.writeInt(i32, @as(i32, @truncate(S + A)), .little), |
| 1081 | .R_X86_64_32 => try cwriter.writeInt(u32, @as(u32, @truncate(@as(u64, @intCast(S + A)))), .little), |
| 1082 | .R_X86_64_32S => try cwriter.writeInt(i32, @as(i32, @truncate(S + A)), .little), |
| 1077 | 1083 | |
| 1078 | | elf.R_X86_64_TPOFF32 => try cwriter.writeInt(i32, @as(i32, @truncate(S + A - TP)), .little), |
| 1079 | | elf.R_X86_64_TPOFF64 => try cwriter.writeInt(i64, S + A - TP, .little), |
| 1084 | .R_X86_64_TPOFF32 => try cwriter.writeInt(i32, @as(i32, @truncate(S + A - TP)), .little), |
| 1085 | .R_X86_64_TPOFF64 => try cwriter.writeInt(i64, S + A - TP, .little), |
| 1080 | 1086 | |
| 1081 | | elf.R_X86_64_DTPOFF32 => try cwriter.writeInt(i32, @as(i32, @truncate(S + A - DTP)), .little), |
| 1082 | | elf.R_X86_64_DTPOFF64 => try cwriter.writeInt(i64, S + A - DTP, .little), |
| 1087 | .R_X86_64_DTPOFF32 => try cwriter.writeInt(i32, @as(i32, @truncate(S + A - DTP)), .little), |
| 1088 | .R_X86_64_DTPOFF64 => try cwriter.writeInt(i64, S + A - DTP, .little), |
| 1083 | 1089 | |
| 1084 | | elf.R_X86_64_TLSGD => { |
| 1090 | .R_X86_64_TLSGD => { |
| 1085 | 1091 | if (target.flags.has_tlsgd) { |
| 1086 | 1092 | const S_ = @as(i64, @intCast(target.tlsGdAddress(elf_file))); |
| 1087 | 1093 | try cwriter.writeInt(i32, @as(i32, @intCast(S_ + A - P)), .little); |
| ... | ... | @@ -1101,7 +1107,7 @@ const x86_64 = struct { |
| 1101 | 1107 | } |
| 1102 | 1108 | }, |
| 1103 | 1109 | |
| 1104 | | elf.R_X86_64_TLSLD => { |
| 1110 | .R_X86_64_TLSLD => { |
| 1105 | 1111 | if (elf_file.got.tlsld_index) |entry_index| { |
| 1106 | 1112 | const tlsld_entry = elf_file.got.entries.items[entry_index]; |
| 1107 | 1113 | const S_ = @as(i64, @intCast(tlsld_entry.address(elf_file))); |
| ... | ... | @@ -1118,7 +1124,7 @@ const x86_64 = struct { |
| 1118 | 1124 | } |
| 1119 | 1125 | }, |
| 1120 | 1126 | |
| 1121 | | elf.R_X86_64_GOTPC32_TLSDESC => { |
| 1127 | .R_X86_64_GOTPC32_TLSDESC => { |
| 1122 | 1128 | if (target.flags.has_tlsdesc) { |
| 1123 | 1129 | const S_ = @as(i64, @intCast(target.tlsDescAddress(elf_file))); |
| 1124 | 1130 | try cwriter.writeInt(i32, @as(i32, @intCast(S_ + A - P)), .little); |
| ... | ... | @@ -1128,12 +1134,12 @@ const x86_64 = struct { |
| 1128 | 1134 | } |
| 1129 | 1135 | }, |
| 1130 | 1136 | |
| 1131 | | elf.R_X86_64_TLSDESC_CALL => if (!target.flags.has_tlsdesc) { |
| 1137 | .R_X86_64_TLSDESC_CALL => if (!target.flags.has_tlsdesc) { |
| 1132 | 1138 | // call -> nop |
| 1133 | 1139 | try cwriter.writeAll(&.{ 0x66, 0x90 }); |
| 1134 | 1140 | }, |
| 1135 | 1141 | |
| 1136 | | elf.R_X86_64_GOTTPOFF => { |
| 1142 | .R_X86_64_GOTTPOFF => { |
| 1137 | 1143 | if (target.flags.has_gottp) { |
| 1138 | 1144 | const S_ = @as(i64, @intCast(target.gotTpAddress(elf_file))); |
| 1139 | 1145 | try cwriter.writeInt(i32, @as(i32, @intCast(S_ + A - P)), .little); |
| ... | ... | @@ -1143,13 +1149,15 @@ const x86_64 = struct { |
| 1143 | 1149 | } |
| 1144 | 1150 | }, |
| 1145 | 1151 | |
| 1146 | | elf.R_X86_64_GOT32 => try cwriter.writeInt(i32, @as(i32, @intCast(G + GOT + A)), .little), |
| 1152 | .R_X86_64_GOT32 => try cwriter.writeInt(i32, @as(i32, @intCast(G + GOT + A)), .little), |
| 1147 | 1153 | |
| 1148 | | // Zig custom relocations |
| 1149 | | Elf.R_X86_64_ZIG_GOT32 => try cwriter.writeInt(u32, @as(u32, @intCast(ZIG_GOT + A)), .little), |
| 1150 | | Elf.R_X86_64_ZIG_GOTPCREL => try cwriter.writeInt(i32, @as(i32, @intCast(ZIG_GOT + A - P)), .little), |
| 1154 | else => |x| switch (@intFromEnum(x)) { |
| 1155 | // Zig custom relocations |
| 1156 | Elf.R_X86_64_ZIG_GOT32 => try cwriter.writeInt(u32, @as(u32, @intCast(ZIG_GOT + A)), .little), |
| 1157 | Elf.R_X86_64_ZIG_GOTPCREL => try cwriter.writeInt(i32, @as(i32, @intCast(ZIG_GOT + A - P)), .little), |
| 1151 | 1158 | |
| 1152 | | else => {}, |
| 1159 | else => {}, |
| 1160 | }, |
| 1153 | 1161 | } |
| 1154 | 1162 | } |
| 1155 | 1163 | } |
| ... | ... | @@ -1163,8 +1171,8 @@ const x86_64 = struct { |
| 1163 | 1171 | var i: usize = 0; |
| 1164 | 1172 | while (i < rels.len) : (i += 1) { |
| 1165 | 1173 | const rel = rels[i]; |
| 1166 | | const r_type = rel.r_type(); |
| 1167 | | if (r_type == elf.R_X86_64_NONE) continue; |
| 1174 | const r_type: elf.R_X86_64 = @enumFromInt(rel.r_type()); |
| 1175 | if (r_type == .R_X86_64_NONE) continue; |
| 1168 | 1176 | |
| 1169 | 1177 | const r_offset = std.math.cast(usize, rel.r_offset) orelse return error.Overflow; |
| 1170 | 1178 | |
| ... | ... | @@ -1211,7 +1219,7 @@ const x86_64 = struct { |
| 1211 | 1219 | const DTP = @as(i64, @intCast(elf_file.dtpAddress())); |
| 1212 | 1220 | |
| 1213 | 1221 | relocs_log.debug(" {s}: {x}: [{x} => {x}] ({s})", .{ |
| 1214 | | relocation.fmtRelocType(r_type, .x86_64), |
| 1222 | @tagName(r_type), |
| 1215 | 1223 | rel.r_offset, |
| 1216 | 1224 | P, |
| 1217 | 1225 | S + A, |
| ... | ... | @@ -1221,21 +1229,21 @@ const x86_64 = struct { |
| 1221 | 1229 | try stream.seekTo(r_offset); |
| 1222 | 1230 | |
| 1223 | 1231 | switch (r_type) { |
| 1224 | | elf.R_X86_64_NONE => unreachable, |
| 1225 | | elf.R_X86_64_8 => try cwriter.writeInt(u8, @as(u8, @bitCast(@as(i8, @intCast(S + A)))), .little), |
| 1226 | | elf.R_X86_64_16 => try cwriter.writeInt(u16, @as(u16, @bitCast(@as(i16, @intCast(S + A)))), .little), |
| 1227 | | elf.R_X86_64_32 => try cwriter.writeInt(u32, @as(u32, @bitCast(@as(i32, @intCast(S + A)))), .little), |
| 1228 | | elf.R_X86_64_32S => try cwriter.writeInt(i32, @as(i32, @intCast(S + A)), .little), |
| 1229 | | elf.R_X86_64_64 => try cwriter.writeInt(i64, S + A, .little), |
| 1230 | | elf.R_X86_64_DTPOFF32 => try cwriter.writeInt(i32, @as(i32, @intCast(S + A - DTP)), .little), |
| 1231 | | elf.R_X86_64_DTPOFF64 => try cwriter.writeInt(i64, S + A - DTP, .little), |
| 1232 | | elf.R_X86_64_GOTOFF64 => try cwriter.writeInt(i64, S + A - GOT, .little), |
| 1233 | | elf.R_X86_64_GOTPC64 => try cwriter.writeInt(i64, GOT + A, .little), |
| 1234 | | elf.R_X86_64_SIZE32 => { |
| 1232 | .R_X86_64_NONE => unreachable, |
| 1233 | .R_X86_64_8 => try cwriter.writeInt(u8, @as(u8, @bitCast(@as(i8, @intCast(S + A)))), .little), |
| 1234 | .R_X86_64_16 => try cwriter.writeInt(u16, @as(u16, @bitCast(@as(i16, @intCast(S + A)))), .little), |
| 1235 | .R_X86_64_32 => try cwriter.writeInt(u32, @as(u32, @bitCast(@as(i32, @intCast(S + A)))), .little), |
| 1236 | .R_X86_64_32S => try cwriter.writeInt(i32, @as(i32, @intCast(S + A)), .little), |
| 1237 | .R_X86_64_64 => try cwriter.writeInt(i64, S + A, .little), |
| 1238 | .R_X86_64_DTPOFF32 => try cwriter.writeInt(i32, @as(i32, @intCast(S + A - DTP)), .little), |
| 1239 | .R_X86_64_DTPOFF64 => try cwriter.writeInt(i64, S + A - DTP, .little), |
| 1240 | .R_X86_64_GOTOFF64 => try cwriter.writeInt(i64, S + A - GOT, .little), |
| 1241 | .R_X86_64_GOTPC64 => try cwriter.writeInt(i64, GOT + A, .little), |
| 1242 | .R_X86_64_SIZE32 => { |
| 1235 | 1243 | const size = @as(i64, @intCast(target.elfSym(elf_file).st_size)); |
| 1236 | 1244 | try cwriter.writeInt(u32, @as(u32, @bitCast(@as(i32, @intCast(size + A)))), .little); |
| 1237 | 1245 | }, |
| 1238 | | elf.R_X86_64_SIZE64 => { |
| 1246 | .R_X86_64_SIZE64 => { |
| 1239 | 1247 | const size = @as(i64, @intCast(target.elfSym(elf_file).st_size)); |
| 1240 | 1248 | try cwriter.writeInt(i64, @as(i64, @intCast(size + A)), .little); |
| 1241 | 1249 | }, |
| ... | ... | @@ -1283,9 +1291,11 @@ const x86_64 = struct { |
| 1283 | 1291 | ) !void { |
| 1284 | 1292 | assert(rels.len == 2); |
| 1285 | 1293 | const writer = stream.writer(); |
| 1286 | | switch (rels[1].r_type()) { |
| 1287 | | elf.R_X86_64_PC32, |
| 1288 | | elf.R_X86_64_PLT32, |
| 1294 | const rel_0: elf.R_X86_64 = @enumFromInt(rels[0].r_type()); |
| 1295 | const rel_1: elf.R_X86_64 = @enumFromInt(rels[1].r_type()); |
| 1296 | switch (rel_1) { |
| 1297 | .R_X86_64_PC32, |
| 1298 | .R_X86_64_PLT32, |
| 1289 | 1299 | => { |
| 1290 | 1300 | var insts = [_]u8{ |
| 1291 | 1301 | 0x64, 0x48, 0x8b, 0x04, 0x25, 0, 0, 0, 0, // movq %fs:0,%rax |
| ... | ... | @@ -1298,9 +1308,9 @@ const x86_64 = struct { |
| 1298 | 1308 | |
| 1299 | 1309 | else => { |
| 1300 | 1310 | var err = try elf_file.addErrorWithNotes(1); |
| 1301 | | try err.addMsg(elf_file, "fatal linker error: rewrite {} when followed by {}", .{ |
| 1302 | | relocation.fmtRelocType(rels[0].r_type(), .x86_64), |
| 1303 | | relocation.fmtRelocType(rels[1].r_type(), .x86_64), |
| 1311 | try err.addMsg(elf_file, "fatal linker error: rewrite {s} when followed by {s}", .{ |
| 1312 | @tagName(rel_0), |
| 1313 | @tagName(rel_1), |
| 1304 | 1314 | }); |
| 1305 | 1315 | try err.addNote(elf_file, "in {}:{s} at offset 0x{x}", .{ |
| 1306 | 1316 | self.file(elf_file).?.fmtPath(), |
| ... | ... | @@ -1320,9 +1330,11 @@ const x86_64 = struct { |
| 1320 | 1330 | ) !void { |
| 1321 | 1331 | assert(rels.len == 2); |
| 1322 | 1332 | const writer = stream.writer(); |
| 1323 | | switch (rels[1].r_type()) { |
| 1324 | | elf.R_X86_64_PC32, |
| 1325 | | elf.R_X86_64_PLT32, |
| 1333 | const rel_0: elf.R_X86_64 = @enumFromInt(rels[0].r_type()); |
| 1334 | const rel_1: elf.R_X86_64 = @enumFromInt(rels[1].r_type()); |
| 1335 | switch (rel_1) { |
| 1336 | .R_X86_64_PC32, |
| 1337 | .R_X86_64_PLT32, |
| 1326 | 1338 | => { |
| 1327 | 1339 | var insts = [_]u8{ |
| 1328 | 1340 | 0x31, 0xc0, // xor %eax, %eax |
| ... | ... | @@ -1334,8 +1346,8 @@ const x86_64 = struct { |
| 1334 | 1346 | try writer.writeAll(&insts); |
| 1335 | 1347 | }, |
| 1336 | 1348 | |
| 1337 | | elf.R_X86_64_GOTPCREL, |
| 1338 | | elf.R_X86_64_GOTPCRELX, |
| 1349 | .R_X86_64_GOTPCREL, |
| 1350 | .R_X86_64_GOTPCRELX, |
| 1339 | 1351 | => { |
| 1340 | 1352 | var insts = [_]u8{ |
| 1341 | 1353 | 0x31, 0xc0, // xor %eax, %eax |
| ... | ... | @@ -1350,9 +1362,9 @@ const x86_64 = struct { |
| 1350 | 1362 | |
| 1351 | 1363 | else => { |
| 1352 | 1364 | var err = try elf_file.addErrorWithNotes(1); |
| 1353 | | try err.addMsg(elf_file, "fatal linker error: rewrite {} when followed by {}", .{ |
| 1354 | | relocation.fmtRelocType(rels[0].r_type(), .x86_64), |
| 1355 | | relocation.fmtRelocType(rels[1].r_type(), .x86_64), |
| 1365 | try err.addMsg(elf_file, "fatal linker error: rewrite {s} when followed by {s}", .{ |
| 1366 | @tagName(rel_0), |
| 1367 | @tagName(rel_1), |
| 1356 | 1368 | }); |
| 1357 | 1369 | try err.addNote(elf_file, "in {}:{s} at offset 0x{x}", .{ |
| 1358 | 1370 | self.file(elf_file).?.fmtPath(), |
| ... | ... | @@ -1419,11 +1431,13 @@ const x86_64 = struct { |
| 1419 | 1431 | ) !void { |
| 1420 | 1432 | assert(rels.len == 2); |
| 1421 | 1433 | const writer = stream.writer(); |
| 1422 | | switch (rels[1].r_type()) { |
| 1423 | | elf.R_X86_64_PC32, |
| 1424 | | elf.R_X86_64_PLT32, |
| 1425 | | elf.R_X86_64_GOTPCREL, |
| 1426 | | elf.R_X86_64_GOTPCRELX, |
| 1434 | const rel_0: elf.R_X86_64 = @enumFromInt(rels[0].r_type()); |
| 1435 | const rel_1: elf.R_X86_64 = @enumFromInt(rels[1].r_type()); |
| 1436 | switch (rel_1) { |
| 1437 | .R_X86_64_PC32, |
| 1438 | .R_X86_64_PLT32, |
| 1439 | .R_X86_64_GOTPCREL, |
| 1440 | .R_X86_64_GOTPCRELX, |
| 1427 | 1441 | => { |
| 1428 | 1442 | var insts = [_]u8{ |
| 1429 | 1443 | 0x64, 0x48, 0x8b, 0x04, 0x25, 0, 0, 0, 0, // movq %fs:0,%rax |
| ... | ... | @@ -1432,17 +1446,14 @@ const x86_64 = struct { |
| 1432 | 1446 | std.mem.writeInt(i32, insts[12..][0..4], value, .little); |
| 1433 | 1447 | try stream.seekBy(-4); |
| 1434 | 1448 | try writer.writeAll(&insts); |
| 1435 | | relocs_log.debug(" relaxing {} and {}", .{ |
| 1436 | | relocation.fmtRelocType(rels[0].r_type(), .x86_64), |
| 1437 | | relocation.fmtRelocType(rels[1].r_type(), .x86_64), |
| 1438 | | }); |
| 1449 | relocs_log.debug(" relaxing {s} and {s}", .{ @tagName(rel_0), @tagName(rel_1) }); |
| 1439 | 1450 | }, |
| 1440 | 1451 | |
| 1441 | 1452 | else => { |
| 1442 | 1453 | var err = try elf_file.addErrorWithNotes(1); |
| 1443 | | try err.addMsg(elf_file, "fatal linker error: rewrite {} when followed by {}", .{ |
| 1444 | | relocation.fmtRelocType(rels[0].r_type(), .x86_64), |
| 1445 | | relocation.fmtRelocType(rels[1].r_type(), .x86_64), |
| 1454 | try err.addMsg(elf_file, "fatal linker error: rewrite {s} when followed by {s}", .{ |
| 1455 | @tagName(rel_0), |
| 1456 | @tagName(rel_1), |
| 1446 | 1457 | }); |
| 1447 | 1458 | try err.addNote(elf_file, "in {}:{s} at offset 0x{x}", .{ |
| 1448 | 1459 | self.file(elf_file).?.fmtPath(), |