Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[X86AsmParser] Check displacement overflow #75747

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3062,6 +3062,35 @@ bool X86AsmParser::ParseMemOperand(unsigned SegReg, const MCExpr *Disp,
ErrMsg))
return Error(BaseLoc, ErrMsg);

// If the displacement is a constant, check overflows. For 64-bit addressing,
// gas requires isInt<32> and otherwise reports an error. For others, gas
// reports a warning and allows a wider range. E.g. gas allows
// [-0xffffffff,0xffffffff] for 32-bit addressing (e.g. Linux kernel uses
// `leal -__PAGE_OFFSET(%ecx),%esp` where __PAGE_OFFSET is 0xc0000000).
if (BaseReg || IndexReg) {
if (auto CE = dyn_cast<MCConstantExpr>(Disp)) {
auto Imm = CE->getValue();
bool Is64 = X86MCRegisterClasses[X86::GR64RegClassID].contains(BaseReg) ||
X86MCRegisterClasses[X86::GR64RegClassID].contains(IndexReg);
bool Is16 = X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg);
if (Is64) {
if (!isInt<32>(Imm))
return Error(BaseLoc, "displacement " + Twine(Imm) +
" is not within [-2147483648, 2147483647]");
} else if (!Is16) {
if (!isUInt<32>(Imm < 0 ? -uint64_t(Imm) : uint64_t(Imm))) {
MaskRay marked this conversation as resolved.
Show resolved Hide resolved
Warning(BaseLoc, "displacement " + Twine(Imm) +
" shortened to 32-bit signed " +
Twine(static_cast<int32_t>(Imm)));
}
} else if (!isUInt<16>(Imm < 0 ? -uint64_t(Imm) : uint64_t(Imm))) {
Warning(BaseLoc, "displacement " + Twine(Imm) +
" shortened to 16-bit signed " +
Twine(static_cast<int16_t>(Imm)));
}
}
}

if (SegReg || BaseReg || IndexReg)
Operands.push_back(X86Operand::CreateMem(getPointerWidth(), SegReg, Disp,
BaseReg, IndexReg, Scale, StartLoc,
Expand Down
38 changes: 38 additions & 0 deletions llvm/test/MC/X86/displacement-overflow.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# RUN: not llvm-mc -triple=x86_64 %s 2>&1 | FileCheck %s --check-prefixes=CHECK,64 --implicit-check-not=error: --implicit-check-not=warning:
# RUN: llvm-mc -triple=i686 --defsym A16=1 %s 2>&1 | FileCheck %s --check-prefixes=CHECK,32 --implicit-check-not=error: --implicit-check-not=warning:

.ifndef A16
movq 0x80000000-1(%rip), %rax
leaq -0x80000000(%rip), %rax

# 64: [[#@LINE+1]]:17: error: displacement 2147483648 is not within [-2147483648, 2147483647]
movq 0x80000000(%rip), %rax

# 64: [[#@LINE+1]]:18: error: displacement -2147483649 is not within [-2147483648, 2147483647]
leaq -0x80000001(%rip), %rax
.endif

movl 0xffffffff(%eax), %eax
leal -0xffffffff(%eax), %eax

# CHECK: [[#@LINE+1]]:19: warning: displacement 4294967296 shortened to 32-bit signed 0
movl 0xffffffff+1(%eax), %eax

# CHECK: [[#@LINE+1]]:20: warning: displacement -4294967296 shortened to 32-bit signed 0
leal -0xffffffff-1(%eax), %eax
# CHECK: [[#@LINE+1]]:20: warning: displacement -4294967297 shortened to 32-bit signed -1
leal -0xffffffff-2(%eax), %eax

{disp8} leal 0x100(%ebx), %eax
{disp8} leal -0x100(%ebx), %eax
MaskRay marked this conversation as resolved.
Show resolved Hide resolved

.ifdef A16
.code16
movw $0, 0xffff(%bp)
movw $0, -0xffff(%si)

# 32: [[#@LINE+1]]:19: warning: displacement 65536 shortened to 16-bit signed 0
movw $0, 0xffff+1(%bp)
# 32: [[#@LINE+1]]:20: warning: displacement -65536 shortened to 16-bit signed 0
movw $0, -0xffff-1(%si)
.endif
52 changes: 26 additions & 26 deletions llvm/test/MC/X86/x86-64.s
Original file line number Diff line number Diff line change
Expand Up @@ -346,11 +346,11 @@ fnstsw %ax

// rdar://8431880
// CHECK: rclb %bl
// CHECK: rcll 3735928559(%ebx,%ecx,8)
// CHECK: rcll 2125315823(%ebx,%ecx,8)
// CHECK: rcrl %ecx
// CHECK: rcrl 305419896
rcl %bl
rcll 0xdeadbeef(%ebx,%ecx,8)
rcll 0x7eadbeef(%ebx,%ecx,8)
rcr %ecx
rcrl 0x12345678

Expand Down Expand Up @@ -573,9 +573,9 @@ leaq 8(%rax), %rsi
// CHECK: encoding: [0x48,0x8d,0x70,0x08]


cvttpd2dq 0xdeadbeef(%ebx,%ecx,8),%xmm5
// CHECK: cvttpd2dq 3735928559(%ebx,%ecx,8), %xmm5
// CHECK: encoding: [0x67,0x66,0x0f,0xe6,0xac,0xcb,0xef,0xbe,0xad,0xde]
cvttpd2dq 0x7eadbeef(%ebx,%ecx,8),%xmm5
// CHECK: cvttpd2dq 2125315823(%ebx,%ecx,8), %xmm5
// CHECK: encoding: [0x67,0x66,0x0f,0xe6,0xac,0xcb,0xef,0xbe,0xad,0x7e]

// rdar://8490728 - llvm-mc rejects 'movmskpd'
movmskpd %xmm6, %rax
Expand Down Expand Up @@ -906,8 +906,8 @@ xchgl %ecx, 368(%rax)
// CHECK: xchgl %ecx, 368(%rax)

// rdar://8407548
xchg 0xdeadbeef(%rbx,%rcx,8),%bl
// CHECK: xchgb %bl, 3735928559(%rbx,%rcx,8)
xchg 0x7fffffff(%rbx,%rcx,8),%bl
// CHECK: xchgb %bl, 2147483647(%rbx,%rcx,8)



Expand Down Expand Up @@ -1112,31 +1112,31 @@ mov %gs, (%rsi) // CHECK: movw %gs, (%rsi) # encoding: [0x8c,0x2e]
//CHECK: divb %bl
//CHECK: divw %bx
//CHECK: divl %ecx
//CHECK: divl 3735928559(%ebx,%ecx,8)
//CHECK: divl 2125315823(%ebx,%ecx,8)
//CHECK: divl 69
//CHECK: divl 32493
//CHECK: divl 3133065982
//CHECK: divl 305419896
//CHECK: idivb %bl
//CHECK: idivw %bx
//CHECK: idivl %ecx
//CHECK: idivl 3735928559(%ebx,%ecx,8)
//CHECK: idivl 2125315823(%ebx,%ecx,8)
//CHECK: idivl 69
//CHECK: idivl 32493
//CHECK: idivl 3133065982
//CHECK: idivl 305419896
div %bl,%al
div %bx,%ax
div %ecx,%eax
div 0xdeadbeef(%ebx,%ecx,8),%eax
div 0x7eadbeef(%ebx,%ecx,8),%eax
div 0x45,%eax
div 0x7eed,%eax
div 0xbabecafe,%eax
div 0x12345678,%eax
idiv %bl,%al
idiv %bx,%ax
idiv %ecx,%eax
idiv 0xdeadbeef(%ebx,%ecx,8),%eax
idiv 0x7eadbeef(%ebx,%ecx,8),%eax
idiv 0x45,%eax
idiv 0x7eed,%eax
idiv 0xbabecafe,%eax
Expand Down Expand Up @@ -1510,9 +1510,9 @@ vmovd %xmm0, %eax
vmovd %xmm0, %rax
vmovq %xmm0, %rax

// CHECK: seto 3735928559(%r10,%r9,8)
// CHECK: encoding: [0x43,0x0f,0x90,0x84,0xca,0xef,0xbe,0xad,0xde]
seto 0xdeadbeef(%r10,%r9,8)
// CHECK: seto 2125315823(%r10,%r9,8)
// CHECK: encoding: [0x43,0x0f,0x90,0x84,0xca,0xef,0xbe,0xad,0x7e]
seto 0x7eadbeef(%r10,%r9,8)

// CHECK: monitorx
// CHECK: encoding: [0x0f,0x01,0xfa]
Expand Down Expand Up @@ -1550,9 +1550,9 @@ vmovq %xmm0, %rax
// CHECK: encoding: [0x47,0x89,0x3c,0x3f]
movl %r15d, (%r15,%r15)

// CHECK: nopq 3735928559(%rbx,%rcx,8)
// CHECK: encoding: [0x48,0x0f,0x1f,0x84,0xcb,0xef,0xbe,0xad,0xde]
nopq 0xdeadbeef(%rbx,%rcx,8)
// CHECK: nopq 2125315823(%rbx,%rcx,8)
// CHECK: encoding: [0x48,0x0f,0x1f,0x84,0xcb,0xef,0xbe,0xad,0x7e]
nopq 0x7eadbeef(%rbx,%rcx,8)

// CHECK: nopq %rax
// CHECK: encoding: [0x48,0x0f,0x1f,0xc0]
Expand All @@ -1562,17 +1562,17 @@ nopq %rax
// CHECK: encoding: [0xf3,0x0f,0xc7,0xf8]
rdpid %rax

// CHECK: ptwritel 3735928559(%rbx,%rcx,8)
// CHECK: encoding: [0xf3,0x0f,0xae,0xa4,0xcb,0xef,0xbe,0xad,0xde]
ptwritel 0xdeadbeef(%rbx,%rcx,8)
// CHECK: ptwritel 2125315823(%rbx,%rcx,8)
// CHECK: encoding: [0xf3,0x0f,0xae,0xa4,0xcb,0xef,0xbe,0xad,0x7e]
ptwritel 0x7eadbeef(%rbx,%rcx,8)

// CHECK: ptwritel %eax
// CHECK: encoding: [0xf3,0x0f,0xae,0xe0]
ptwritel %eax

// CHECK: ptwriteq 3735928559(%rbx,%rcx,8)
// CHECK: encoding: [0xf3,0x48,0x0f,0xae,0xa4,0xcb,0xef,0xbe,0xad,0xde]
ptwriteq 0xdeadbeef(%rbx,%rcx,8)
// CHECK: ptwriteq 2125315823(%rbx,%rcx,8)
// CHECK: encoding: [0xf3,0x48,0x0f,0xae,0xa4,0xcb,0xef,0xbe,0xad,0x7e]
ptwriteq 0x7eadbeef(%rbx,%rcx,8)

// CHECK: ptwriteq %rax
// CHECK: encoding: [0xf3,0x48,0x0f,0xae,0xe0]
Expand All @@ -1586,9 +1586,9 @@ wbnoinvd
// CHECK: encoding: [0x0f,0x1c,0x40,0x04]
cldemote 4(%rax)

// CHECK: cldemote 3735928559(%rbx,%rcx,8)
// CHECK: encoding: [0x0f,0x1c,0x84,0xcb,0xef,0xbe,0xad,0xde]
cldemote 0xdeadbeef(%rbx,%rcx,8)
// CHECK: cldemote 2125315823(%rbx,%rcx,8)
// CHECK: encoding: [0x0f,0x1c,0x84,0xcb,0xef,0xbe,0xad,0x7e]
cldemote 0x7eadbeef(%rbx,%rcx,8)

// CHECK: umonitor %r13
// CHECK: encoding: [0xf3,0x41,0x0f,0xae,0xf5]
Expand Down
6 changes: 3 additions & 3 deletions llvm/test/MC/X86/x86_64-asm-match.s
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,9 @@
// CHECK: Opcode result: complete match, selecting this opcode
// CHECK: AsmMatcher: found 2 encodings with mnemonic 'crc32l'
// CHECK: Trying to match opcode CRC32r32r32
// CHECK: Matching formal operand class MCK_GR32 against actual operand at index 1 (Memory: ModeSize=64,BaseReg=rbx,IndexReg=rcx,Scale=8,Disp=3735928559,SegReg=gs): Opcode result: multiple operand mismatches, ignoring this opcode
// CHECK: Matching formal operand class MCK_GR32 against actual operand at index 1 (Memory: ModeSize=64,BaseReg=rbx,IndexReg=rcx,Scale=8,Disp=2125315823,SegReg=gs): Opcode result: multiple operand mismatches, ignoring this opcode
// CHECK: Trying to match opcode CRC32r32m32
// CHECK: Matching formal operand class MCK_Mem32 against actual operand at index 1 (Memory: ModeSize=64,BaseReg=rbx,IndexReg=rcx,Scale=8,Disp=3735928559,SegReg=gs): match success using generic matcher
// CHECK: Matching formal operand class MCK_Mem32 against actual operand at index 1 (Memory: ModeSize=64,BaseReg=rbx,IndexReg=rcx,Scale=8,Disp=2125315823,SegReg=gs): match success using generic matcher
// CHECK: Matching formal operand class MCK_GR32 against actual operand at index 2 (Reg:ecx): match success using generic matcher
// CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 3: actual operand index out of range
// CHECK: Opcode result: complete match, selecting this opcode
Expand Down Expand Up @@ -62,7 +62,7 @@
pshufb CPI1_0(%rip), %xmm1
sha1rnds4 $1, %xmm1, %xmm2
pinsrw $3, %ecx, %xmm5
crc32l %gs:0xdeadbeef(%rbx,%rcx,8),%ecx
crc32l %gs:0x7eadbeef(%rbx,%rcx,8),%ecx
maskmovdqu %xmm0, %xmm1
vmaskmovdqu %xmm0, %xmm1

Expand Down
6 changes: 3 additions & 3 deletions llvm/test/MC/X86/x86_64-encoding.s
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@ movq %gs:(%rdi), %rax
// CHECK: encoding: [0xf2,0x0f,0x38,0xf1,0x43,0x04]
crc32l 4(%rbx), %eax

// CHECK: crc32l 3735928559(%rbx,%rcx,8), %ecx
// CHECK: encoding: [0xf2,0x0f,0x38,0xf1,0x8c,0xcb,0xef,0xbe,0xad,0xde]
crc32l 0xdeadbeef(%rbx,%rcx,8),%ecx
// CHECK: crc32l 2125315823(%rbx,%rcx,8), %ecx
// CHECK: encoding: [0xf2,0x0f,0x38,0xf1,0x8c,0xcb,0xef,0xbe,0xad,0x7e]
crc32l 0x7eadbeef(%rbx,%rcx,8),%ecx

// CHECK: crc32l 69, %ecx
// CHECK: encoding: [0xf2,0x0f,0x38,0xf1,0x0c,0x25,0x45,0x00,0x00,0x00]
Expand Down
Loading