Skip to content
This repository was archived by the owner on Mar 28, 2020. It is now read-only.

Commit 8bebbdc

Browse files
committed
[X86] Don't randomly encode %rip where illegal
Differential Revision: https://reviews.llvm.org/D25112 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@283326 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 71beb00 commit 8bebbdc

File tree

4 files changed

+40
-4
lines changed

4 files changed

+40
-4
lines changed

lib/Target/X86/AsmParser/X86AsmParser.cpp

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -840,6 +840,11 @@ static bool CheckBaseRegAndIndexReg(unsigned BaseReg, unsigned IndexReg,
840840
// If we have both a base register and an index register make sure they are
841841
// both 64-bit or 32-bit registers.
842842
// To support VSIB, IndexReg can be 128-bit or 256-bit registers.
843+
844+
if ((BaseReg == X86::RIP && IndexReg != 0) || (IndexReg == X86::RIP)) {
845+
ErrMsg = "invalid base+index expression";
846+
return true;
847+
}
843848
if (BaseReg != 0 && IndexReg != 0) {
844849
if (X86MCRegisterClasses[X86::GR64RegClassID].contains(BaseReg) &&
845850
(X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg) ||
@@ -1781,10 +1786,12 @@ std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOperand() {
17811786
!ParseRegister(RegNo, Start, End)) {
17821787
// If this is a segment register followed by a ':', then this is the start
17831788
// of a segment override, otherwise this is a normal register reference.
1784-
// In case it is a normal register and there is ptr in the operand this
1789+
// In case it is a normal register and there is ptr in the operand this
17851790
// is an error
1786-
if (getLexer().isNot(AsmToken::Colon)){
1787-
if (PtrInOperand){
1791+
if (RegNo == X86::RIP)
1792+
return ErrorOperand(Start, "rip can only be used as a base register");
1793+
if (getLexer().isNot(AsmToken::Colon)) {
1794+
if (PtrInOperand) {
17881795
return ErrorOperand(Start, "expected memory operand after "
17891796
"'ptr', found register operand instead");
17901797
}
@@ -1865,6 +1872,11 @@ std::unique_ptr<X86Operand> X86AsmParser::ParseATTOperand() {
18651872
SMRange(Start, End));
18661873
return nullptr;
18671874
}
1875+
if (RegNo == X86::RIP) {
1876+
Error(Start, "%rip can only be used as a base register",
1877+
SMRange(Start, End));
1878+
return nullptr;
1879+
}
18681880

18691881
// If this is a segment register followed by a ':', then this is the start
18701882
// of a memory reference, otherwise this is a normal register reference.
@@ -2044,7 +2056,16 @@ std::unique_ptr<X86Operand> X86AsmParser::ParseMemOperand(unsigned SegReg,
20442056
// like "1(%eax,,1)", the assembler doesn't. Use "eiz" or "riz" for this.
20452057
if (getLexer().is(AsmToken::Percent)) {
20462058
SMLoc L;
2047-
if (ParseRegister(IndexReg, L, L)) return nullptr;
2059+
if (ParseRegister(IndexReg, L, L))
2060+
return nullptr;
2061+
if (BaseReg == X86::RIP) {
2062+
Error(IndexLoc, "%rip as base register can not have an index register");
2063+
return nullptr;
2064+
}
2065+
if (IndexReg == X86::RIP) {
2066+
Error(IndexLoc, "%rip is not allowed as an index register");
2067+
return nullptr;
2068+
}
20482069

20492070
if (getLexer().isNot(AsmToken::RParen)) {
20502071
// Parse the scale amount:

lib/Target/X86/X86RegisterInfo.td

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,8 @@ def GR32 : RegisterClass<"X86", [i32], 32,
345345
// GR64 - 64-bit GPRs. This oddly includes RIP, which isn't accurate, since
346346
// RIP isn't really a register and it can't be used anywhere except in an
347347
// address, but it doesn't cause trouble.
348+
// FIXME: it *does* cause trouble - CheckBaseRegAndIndexReg() has extra
349+
// tests because of the inclusion of RIP in this register class.
348350
def GR64 : RegisterClass<"X86", [i64], 64,
349351
(add RAX, RCX, RDX, RSI, RDI, R8, R9, R10, R11,
350352
RBX, R14, R15, R12, R13, RBP, RSP, RIP)>;

test/MC/X86/intel-syntax-error.s

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,8 @@ mov eax, DWORD PTR arr[ebp + 1 + (2 * 5) - 3 + 1<<1]
2424
mov eax, DWORD PTR arr[esi*4]
2525
//CHECK: error: cannot use more than one symbol in memory operand
2626
mov eax, DWORD PTR arr[i]
27+
//CHECK: error: rip can only be used as a base register
28+
.code64
29+
mov rax, rip
30+
//CHECK: error: invalid base+index expression
31+
mov rbx, [rax+rip]

test/MC/X86/x86_errors.s

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,3 +74,11 @@ movl %edx, %cr8
7474

7575
// 32: error: register %dr8 is only available in 64-bit mode
7676
movl %edx, %dr8
77+
78+
// 32: error: register %rip is only available in 64-bit mode
79+
// 64: error: %rip can only be used as a base register
80+
mov %rip, %rax
81+
82+
// 32: error: register %rax is only available in 64-bit mode
83+
// 64: error: %rip is not allowed as an index register
84+
mov (%rax,%rip), %rbx

0 commit comments

Comments
 (0)