@@ -901,6 +901,7 @@ RelExpr X86_64::adjustGotPcExpr(RelType type, int64_t addend,
901
901
static void relaxGotNoPic (uint8_t *loc, uint64_t val, uint8_t op,
902
902
uint8_t modRm) {
903
903
const uint8_t rex = loc[-3 ];
904
+ const bool isRex2 = loc[-4 ] == 0xd5 ;
904
905
// Convert "test %reg, foo@GOTPCREL(%rip)" to "test $foo, %reg".
905
906
if (op == 0x85 ) {
906
907
// See "TEST-Logical Compare" (4-428 Vol. 2B),
@@ -925,7 +926,7 @@ static void relaxGotNoPic(uint8_t *loc, uint64_t val, uint8_t op,
925
926
// See "TEST-Logical Compare" (4-428 Vol. 2B).
926
927
loc[-2 ] = 0xf7 ;
927
928
928
- // Move R bit to the B bit in REX byte.
929
+ // Move R bit to the B bit in REX/REX2 byte.
929
930
// REX byte is encoded as 0100WRXB, where
930
931
// 0100 is 4bit fixed pattern.
931
932
// REX.W When 1, a 64-bit operand size is used. Otherwise, when 0, the
@@ -936,7 +937,18 @@ static void relaxGotNoPic(uint8_t *loc, uint64_t val, uint8_t op,
936
937
// REX.B This 1-bit value is an extension to the MODRM.rm field or the
937
938
// SIB.base field.
938
939
// See "2.2.1.2 More on REX Prefix Fields " (2-8 Vol. 2A).
939
- loc[-3 ] = (rex & ~0x4 ) | (rex & 0x4 ) >> 2 ;
940
+ //
941
+ // REX2 prefix is encoded as 0xd5|M|R2|X2|B2|WRXB, where
942
+ // 0xd5 is 1byte fixed pattern.
943
+ // REX2's [W,R,X,B] have the same meanings as REX's.
944
+ // REX2.M encodes the map id.
945
+ // R2/X2/B2 provides the fifth and most siginicant bits of the R/X/B
946
+ // register identifiers, each of which can now address all 32 GPRs.
947
+ // TODO: Add the section number here after APX SPEC is merged into SDM.
948
+ if (isRex2)
949
+ loc[-3 ] = (rex & ~0x44 ) | (rex & 0x44 ) >> 2 ;
950
+ else
951
+ loc[-3 ] = (rex & ~0x4 ) | (rex & 0x4 ) >> 2 ;
940
952
write32le (loc, val);
941
953
return ;
942
954
}
@@ -957,7 +969,10 @@ static void relaxGotNoPic(uint8_t *loc, uint64_t val, uint8_t op,
957
969
// "INSTRUCTION SET REFERENCE, N-Z" (Vol. 2B 4-1) for
958
970
// descriptions about each operation.
959
971
loc[-2 ] = 0x81 ;
960
- loc[-3 ] = (rex & ~0x4 ) | (rex & 0x4 ) >> 2 ;
972
+ if (isRex2)
973
+ loc[-3 ] = (rex & ~0x44 ) | (rex & 0x44 ) >> 2 ;
974
+ else
975
+ loc[-3 ] = (rex & ~0x4 ) | (rex & 0x4 ) >> 2 ;
961
976
write32le (loc, val);
962
977
}
963
978
0 commit comments