@@ -25,6 +25,7 @@ import (
25
25
"internal/saferio"
26
26
"internal/zstd"
27
27
"io"
28
+ "math"
28
29
"os"
29
30
"strings"
30
31
"unsafe"
@@ -830,17 +831,9 @@ func (f *File) applyRelocationsAMD64(dst []byte, rels []byte) error {
830
831
831
832
switch t {
832
833
case R_X86_64_64 :
833
- if rela .Off + 8 >= uint64 (len (dst )) || rela .Addend < 0 {
834
- continue
835
- }
836
- val64 := sym .Value + uint64 (rela .Addend )
837
- f .ByteOrder .PutUint64 (dst [rela .Off :rela .Off + 8 ], val64 )
834
+ putUint (f .ByteOrder , dst , rela .Off , 8 , sym .Value , rela .Addend , false )
838
835
case R_X86_64_32 :
839
- if rela .Off + 4 >= uint64 (len (dst )) || rela .Addend < 0 {
840
- continue
841
- }
842
- val32 := uint32 (sym .Value ) + uint32 (rela .Addend )
843
- f .ByteOrder .PutUint32 (dst [rela .Off :rela .Off + 4 ], val32 )
836
+ putUint (f .ByteOrder , dst , rela .Off , 4 , sym .Value , rela .Addend , false )
844
837
}
845
838
}
846
839
@@ -872,12 +865,7 @@ func (f *File) applyRelocations386(dst []byte, rels []byte) error {
872
865
sym := & symbols [symNo - 1 ]
873
866
874
867
if t == R_386_32 {
875
- if rel .Off + 4 >= uint32 (len (dst )) {
876
- continue
877
- }
878
- val := f .ByteOrder .Uint32 (dst [rel .Off : rel .Off + 4 ])
879
- val += uint32 (sym .Value )
880
- f .ByteOrder .PutUint32 (dst [rel .Off :rel .Off + 4 ], val )
868
+ putUint (f .ByteOrder , dst , uint64 (rel .Off ), 4 , sym .Value , 0 , true )
881
869
}
882
870
}
883
871
@@ -910,12 +898,7 @@ func (f *File) applyRelocationsARM(dst []byte, rels []byte) error {
910
898
911
899
switch t {
912
900
case R_ARM_ABS32 :
913
- if rel .Off + 4 >= uint32 (len (dst )) {
914
- continue
915
- }
916
- val := f .ByteOrder .Uint32 (dst [rel .Off : rel .Off + 4 ])
917
- val += uint32 (sym .Value )
918
- f .ByteOrder .PutUint32 (dst [rel .Off :rel .Off + 4 ], val )
901
+ putUint (f .ByteOrder , dst , uint64 (rel .Off ), 4 , sym .Value , 0 , true )
919
902
}
920
903
}
921
904
@@ -955,17 +938,9 @@ func (f *File) applyRelocationsARM64(dst []byte, rels []byte) error {
955
938
956
939
switch t {
957
940
case R_AARCH64_ABS64 :
958
- if rela .Off + 8 >= uint64 (len (dst )) || rela .Addend < 0 {
959
- continue
960
- }
961
- val64 := sym .Value + uint64 (rela .Addend )
962
- f .ByteOrder .PutUint64 (dst [rela .Off :rela .Off + 8 ], val64 )
941
+ putUint (f .ByteOrder , dst , rela .Off , 8 , sym .Value , rela .Addend , false )
963
942
case R_AARCH64_ABS32 :
964
- if rela .Off + 4 >= uint64 (len (dst )) || rela .Addend < 0 {
965
- continue
966
- }
967
- val32 := uint32 (sym .Value ) + uint32 (rela .Addend )
968
- f .ByteOrder .PutUint32 (dst [rela .Off :rela .Off + 4 ], val32 )
943
+ putUint (f .ByteOrder , dst , rela .Off , 4 , sym .Value , rela .Addend , false )
969
944
}
970
945
}
971
946
@@ -1001,11 +976,7 @@ func (f *File) applyRelocationsPPC(dst []byte, rels []byte) error {
1001
976
1002
977
switch t {
1003
978
case R_PPC_ADDR32 :
1004
- if rela .Off + 4 >= uint32 (len (dst )) || rela .Addend < 0 {
1005
- continue
1006
- }
1007
- val32 := uint32 (sym .Value ) + uint32 (rela .Addend )
1008
- f .ByteOrder .PutUint32 (dst [rela .Off :rela .Off + 4 ], val32 )
979
+ putUint (f .ByteOrder , dst , uint64 (rela .Off ), 4 , sym .Value , 0 , false )
1009
980
}
1010
981
}
1011
982
@@ -1041,17 +1012,9 @@ func (f *File) applyRelocationsPPC64(dst []byte, rels []byte) error {
1041
1012
1042
1013
switch t {
1043
1014
case R_PPC64_ADDR64 :
1044
- if rela .Off + 8 >= uint64 (len (dst )) || rela .Addend < 0 {
1045
- continue
1046
- }
1047
- val64 := sym .Value + uint64 (rela .Addend )
1048
- f .ByteOrder .PutUint64 (dst [rela .Off :rela .Off + 8 ], val64 )
1015
+ putUint (f .ByteOrder , dst , rela .Off , 8 , sym .Value , rela .Addend , false )
1049
1016
case R_PPC64_ADDR32 :
1050
- if rela .Off + 4 >= uint64 (len (dst )) || rela .Addend < 0 {
1051
- continue
1052
- }
1053
- val32 := uint32 (sym .Value ) + uint32 (rela .Addend )
1054
- f .ByteOrder .PutUint32 (dst [rela .Off :rela .Off + 4 ], val32 )
1017
+ putUint (f .ByteOrder , dst , rela .Off , 4 , sym .Value , rela .Addend , false )
1055
1018
}
1056
1019
}
1057
1020
@@ -1084,12 +1047,7 @@ func (f *File) applyRelocationsMIPS(dst []byte, rels []byte) error {
1084
1047
1085
1048
switch t {
1086
1049
case R_MIPS_32 :
1087
- if rel .Off + 4 >= uint32 (len (dst )) {
1088
- continue
1089
- }
1090
- val := f .ByteOrder .Uint32 (dst [rel .Off : rel .Off + 4 ])
1091
- val += uint32 (sym .Value )
1092
- f .ByteOrder .PutUint32 (dst [rel .Off :rel .Off + 4 ], val )
1050
+ putUint (f .ByteOrder , dst , uint64 (rel .Off ), 4 , sym .Value , 0 , true )
1093
1051
}
1094
1052
}
1095
1053
@@ -1132,17 +1090,9 @@ func (f *File) applyRelocationsMIPS64(dst []byte, rels []byte) error {
1132
1090
1133
1091
switch t {
1134
1092
case R_MIPS_64 :
1135
- if rela .Off + 8 >= uint64 (len (dst )) || rela .Addend < 0 {
1136
- continue
1137
- }
1138
- val64 := sym .Value + uint64 (rela .Addend )
1139
- f .ByteOrder .PutUint64 (dst [rela .Off :rela .Off + 8 ], val64 )
1093
+ putUint (f .ByteOrder , dst , rela .Off , 8 , sym .Value , rela .Addend , false )
1140
1094
case R_MIPS_32 :
1141
- if rela .Off + 4 >= uint64 (len (dst )) || rela .Addend < 0 {
1142
- continue
1143
- }
1144
- val32 := uint32 (sym .Value ) + uint32 (rela .Addend )
1145
- f .ByteOrder .PutUint32 (dst [rela .Off :rela .Off + 4 ], val32 )
1095
+ putUint (f .ByteOrder , dst , rela .Off , 4 , sym .Value , rela .Addend , false )
1146
1096
}
1147
1097
}
1148
1098
@@ -1180,17 +1130,9 @@ func (f *File) applyRelocationsLOONG64(dst []byte, rels []byte) error {
1180
1130
1181
1131
switch t {
1182
1132
case R_LARCH_64 :
1183
- if rela .Off + 8 >= uint64 (len (dst )) || rela .Addend < 0 {
1184
- continue
1185
- }
1186
- val64 := sym .Value + uint64 (rela .Addend )
1187
- f .ByteOrder .PutUint64 (dst [rela .Off :rela .Off + 8 ], val64 )
1133
+ putUint (f .ByteOrder , dst , rela .Off , 8 , sym .Value , rela .Addend , false )
1188
1134
case R_LARCH_32 :
1189
- if rela .Off + 4 >= uint64 (len (dst )) || rela .Addend < 0 {
1190
- continue
1191
- }
1192
- val32 := uint32 (sym .Value ) + uint32 (rela .Addend )
1193
- f .ByteOrder .PutUint32 (dst [rela .Off :rela .Off + 4 ], val32 )
1135
+ putUint (f .ByteOrder , dst , rela .Off , 4 , sym .Value , rela .Addend , false )
1194
1136
}
1195
1137
}
1196
1138
@@ -1226,17 +1168,9 @@ func (f *File) applyRelocationsRISCV64(dst []byte, rels []byte) error {
1226
1168
1227
1169
switch t {
1228
1170
case R_RISCV_64 :
1229
- if rela .Off + 8 >= uint64 (len (dst )) || rela .Addend < 0 {
1230
- continue
1231
- }
1232
- val64 := sym .Value + uint64 (rela .Addend )
1233
- f .ByteOrder .PutUint64 (dst [rela .Off :rela .Off + 8 ], val64 )
1171
+ putUint (f .ByteOrder , dst , rela .Off , 8 , sym .Value , rela .Addend , false )
1234
1172
case R_RISCV_32 :
1235
- if rela .Off + 4 >= uint64 (len (dst )) || rela .Addend < 0 {
1236
- continue
1237
- }
1238
- val32 := uint32 (sym .Value ) + uint32 (rela .Addend )
1239
- f .ByteOrder .PutUint32 (dst [rela .Off :rela .Off + 4 ], val32 )
1173
+ putUint (f .ByteOrder , dst , rela .Off , 4 , sym .Value , rela .Addend , false )
1240
1174
}
1241
1175
}
1242
1176
@@ -1272,17 +1206,9 @@ func (f *File) applyRelocationss390x(dst []byte, rels []byte) error {
1272
1206
1273
1207
switch t {
1274
1208
case R_390_64 :
1275
- if rela .Off + 8 >= uint64 (len (dst )) || rela .Addend < 0 {
1276
- continue
1277
- }
1278
- val64 := sym .Value + uint64 (rela .Addend )
1279
- f .ByteOrder .PutUint64 (dst [rela .Off :rela .Off + 8 ], val64 )
1209
+ putUint (f .ByteOrder , dst , rela .Off , 8 , sym .Value , rela .Addend , false )
1280
1210
case R_390_32 :
1281
- if rela .Off + 4 >= uint64 (len (dst )) || rela .Addend < 0 {
1282
- continue
1283
- }
1284
- val32 := uint32 (sym .Value ) + uint32 (rela .Addend )
1285
- f .ByteOrder .PutUint32 (dst [rela .Off :rela .Off + 4 ], val32 )
1211
+ putUint (f .ByteOrder , dst , rela .Off , 4 , sym .Value , rela .Addend , false )
1286
1212
}
1287
1213
}
1288
1214
@@ -1318,17 +1244,10 @@ func (f *File) applyRelocationsSPARC64(dst []byte, rels []byte) error {
1318
1244
1319
1245
switch t {
1320
1246
case R_SPARC_64 , R_SPARC_UA64 :
1321
- if rela .Off + 8 >= uint64 (len (dst )) || rela .Addend < 0 {
1322
- continue
1323
- }
1324
- val64 := sym .Value + uint64 (rela .Addend )
1325
- f .ByteOrder .PutUint64 (dst [rela .Off :rela .Off + 8 ], val64 )
1247
+ putUint (f .ByteOrder , dst , rela .Off , 8 , sym .Value , rela .Addend , false )
1248
+
1326
1249
case R_SPARC_32 , R_SPARC_UA32 :
1327
- if rela .Off + 4 >= uint64 (len (dst )) || rela .Addend < 0 {
1328
- continue
1329
- }
1330
- val32 := uint32 (sym .Value ) + uint32 (rela .Addend )
1331
- f .ByteOrder .PutUint32 (dst [rela .Off :rela .Off + 4 ], val32 )
1250
+ putUint (f .ByteOrder , dst , rela .Off , 4 , sym .Value , rela .Addend , false )
1332
1251
}
1333
1252
}
1334
1253
@@ -1903,3 +1822,38 @@ type nobitsSectionReader struct{}
1903
1822
func (* nobitsSectionReader ) ReadAt (p []byte , off int64 ) (n int , err error ) {
1904
1823
return 0 , errors .New ("unexpected read from SHT_NOBITS section" )
1905
1824
}
1825
+
1826
+ // putUint writes a relocation to slice
1827
+ // at offset start of length length (4 or 8 bytes),
1828
+ // adding sym+addend to the existing value if readUint is true,
1829
+ // or just writing sym+addend if readUint is false.
1830
+ // If the write would extend beyond the end of slice, putUint does nothing.
1831
+ // If the addend is negative, putUint does nothing.
1832
+ // If the addition would overflow, putUint does nothing.
1833
+ func putUint (byteOrder binary.ByteOrder , slice []byte , start , length , sym uint64 , addend int64 , readUint bool ) {
1834
+ if start + length > uint64 (len (slice )) || math .MaxUint64 - start < length {
1835
+ return
1836
+ }
1837
+ if addend < 0 {
1838
+ return
1839
+ }
1840
+
1841
+ s := slice [start : start + length ]
1842
+
1843
+ switch length {
1844
+ case 4 :
1845
+ ae := uint32 (addend )
1846
+ if readUint {
1847
+ ae += byteOrder .Uint32 (s )
1848
+ }
1849
+ byteOrder .PutUint32 (s , uint32 (sym )+ ae )
1850
+ case 8 :
1851
+ ae := uint64 (addend )
1852
+ if readUint {
1853
+ ae += byteOrder .Uint64 (s )
1854
+ }
1855
+ byteOrder .PutUint64 (s , sym + ae )
1856
+ default :
1857
+ panic ("can't happen" )
1858
+ }
1859
+ }
0 commit comments