@@ -25,6 +25,7 @@ import (
2525 "internal/saferio"
2626 "internal/zstd"
2727 "io"
28+ "math"
2829 "os"
2930 "strings"
3031 "unsafe"
@@ -830,17 +831,9 @@ func (f *File) applyRelocationsAMD64(dst []byte, rels []byte) error {
830831
831832 switch t {
832833 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 )
838835 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 )
844837 }
845838 }
846839
@@ -872,12 +865,7 @@ func (f *File) applyRelocations386(dst []byte, rels []byte) error {
872865 sym := & symbols [symNo - 1 ]
873866
874867 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 )
881869 }
882870 }
883871
@@ -910,12 +898,7 @@ func (f *File) applyRelocationsARM(dst []byte, rels []byte) error {
910898
911899 switch t {
912900 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 )
919902 }
920903 }
921904
@@ -955,17 +938,9 @@ func (f *File) applyRelocationsARM64(dst []byte, rels []byte) error {
955938
956939 switch t {
957940 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 )
963942 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 )
969944 }
970945 }
971946
@@ -1001,11 +976,7 @@ func (f *File) applyRelocationsPPC(dst []byte, rels []byte) error {
1001976
1002977 switch t {
1003978 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 )
1009980 }
1010981 }
1011982
@@ -1041,17 +1012,9 @@ func (f *File) applyRelocationsPPC64(dst []byte, rels []byte) error {
10411012
10421013 switch t {
10431014 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 )
10491016 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 )
10551018 }
10561019 }
10571020
@@ -1084,12 +1047,7 @@ func (f *File) applyRelocationsMIPS(dst []byte, rels []byte) error {
10841047
10851048 switch t {
10861049 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 )
10931051 }
10941052 }
10951053
@@ -1132,17 +1090,9 @@ func (f *File) applyRelocationsMIPS64(dst []byte, rels []byte) error {
11321090
11331091 switch t {
11341092 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 )
11401094 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 )
11461096 }
11471097 }
11481098
@@ -1180,17 +1130,9 @@ func (f *File) applyRelocationsLOONG64(dst []byte, rels []byte) error {
11801130
11811131 switch t {
11821132 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 )
11881134 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 )
11941136 }
11951137 }
11961138
@@ -1226,17 +1168,9 @@ func (f *File) applyRelocationsRISCV64(dst []byte, rels []byte) error {
12261168
12271169 switch t {
12281170 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 )
12341172 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 )
12401174 }
12411175 }
12421176
@@ -1272,17 +1206,9 @@ func (f *File) applyRelocationss390x(dst []byte, rels []byte) error {
12721206
12731207 switch t {
12741208 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 )
12801210 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 )
12861212 }
12871213 }
12881214
@@ -1318,17 +1244,10 @@ func (f *File) applyRelocationsSPARC64(dst []byte, rels []byte) error {
13181244
13191245 switch t {
13201246 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+
13261249 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 )
13321251 }
13331252 }
13341253
@@ -1903,3 +1822,38 @@ type nobitsSectionReader struct{}
19031822func (* nobitsSectionReader ) ReadAt (p []byte , off int64 ) (n int , err error ) {
19041823 return 0 , errors .New ("unexpected read from SHT_NOBITS section" )
19051824}
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