[asan] Preserve flags in asm instrumentation.
authorEvgeniy Stepanov <eugeni.stepanov@gmail.com>
Thu, 8 May 2014 09:55:24 +0000 (09:55 +0000)
committerEvgeniy Stepanov <eugeni.stepanov@gmail.com>
Thu, 8 May 2014 09:55:24 +0000 (09:55 +0000)
Patch by Yuri Gorshenin.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@208296 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/X86/AsmParser/X86AsmInstrumentation.cpp
test/Instrumentation/AddressSanitizer/X86/asm_mov.ll
test/Instrumentation/AddressSanitizer/X86/asm_mov.s
test/Instrumentation/AddressSanitizer/X86/asm_swap_intel.s

index 95e4ccccb9d20a84728c58bab77890a46d5b1b5e..303bbf249b51bb269bfebe92340d1eaf9ecc662e 100644 (file)
@@ -177,13 +177,26 @@ public:
                                         MCStreamer &Out) override;
 };
 
-void X86AddressSanitizer64::InstrumentMemOperandImpl(
-    X86Operand *Op, unsigned AccessSize, bool IsWrite, MCContext &Ctx,
-    MCStreamer &Out) {
+void X86AddressSanitizer64::InstrumentMemOperandImpl(X86Operand *Op,
+                                                     unsigned AccessSize,
+                                                     bool IsWrite,
+                                                     MCContext &Ctx,
+                                                     MCStreamer &Out) {
   // FIXME: emit .cfi directives for correct stack unwinding.
-  // Set %rsp below current red zone (128 bytes wide)
-  EmitInstruction(Out, MCInstBuilder(X86::SUB64ri32).addReg(X86::RSP)
-                           .addReg(X86::RSP).addImm(128));
+
+  // Set %rsp below current red zone (128 bytes wide) using LEA instruction to
+  // preserve flags.
+  {
+    MCInst Inst;
+    Inst.setOpcode(X86::LEA64r);
+    Inst.addOperand(MCOperand::CreateReg(X86::RSP));
+
+    const MCExpr *Disp = MCConstantExpr::Create(-128, Ctx);
+    X86Operand *Op =
+        X86Operand::CreateMem(0, Disp, X86::RSP, 0, 1, SMLoc(), SMLoc());
+    Op->addMemOperands(Inst, 5);
+    EmitInstruction(Out, Inst);
+  }
   EmitInstruction(Out, MCInstBuilder(X86::PUSH64r).addReg(X86::RDI));
   {
     MCInst Inst;
@@ -200,8 +213,19 @@ void X86AddressSanitizer64::InstrumentMemOperandImpl(
     EmitInstruction(Out, MCInstBuilder(X86::CALL64pcrel32).addExpr(FuncExpr));
   }
   EmitInstruction(Out, MCInstBuilder(X86::POP64r).addReg(X86::RDI));
-  EmitInstruction(Out, MCInstBuilder(X86::ADD64ri32).addReg(X86::RSP)
-                           .addReg(X86::RSP).addImm(128));
+
+  // Restore old %rsp value.
+  {
+    MCInst Inst;
+    Inst.setOpcode(X86::LEA64r);
+    Inst.addOperand(MCOperand::CreateReg(X86::RSP));
+
+    const MCExpr *Disp = MCConstantExpr::Create(128, Ctx);
+    X86Operand *Op =
+        X86Operand::CreateMem(0, Disp, X86::RSP, 0, 1, SMLoc(), SMLoc());
+    Op->addMemOperands(Inst, 5);
+    EmitInstruction(Out, Inst);
+  }
 }
 
 } // End anonymous namespace
index 94265c2cc74436d073a1cd44605345ac33171d6a..030af7e0ea79f6d112d9c20fcd01d5942653f9b6 100644 (file)
@@ -4,19 +4,19 @@ target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f3
 target triple = "x86_64-unknown-linux-gnu"
 
 ; CHECK-LABEL: mov1b
-; CHECK: subq $128, %rsp
+; CHECK: leaq -128(%rsp), %rsp
 ; CHECK-NEXT: pushq %rdi
 ; CHECK-NEXT: leaq {{.*}}, %rdi
 ; CHECK-NEXT: callq __sanitizer_sanitize_load1@PLT
 ; CHECK-NEXT: popq %rdi
-; CHECK-NEXT: addq $128, %rsp
+; CHECK-NEXT: leaq 128(%rsp), %rsp
 
-; CHECK: subq $128, %rsp
+; CHECK: leaq -128(%rsp), %rsp
 ; CHECK-NEXT: pushq %rdi
 ; CHECK-NEXT: leaq {{.*}}, %rdi
 ; CHECK-NEXT: callq __sanitizer_sanitize_store1@PLT
 ; CHECK-NEXT: popq %rdi
-; CHECK-NEXT: addq $128, %rsp
+; CHECK-NEXT: leaq 128(%rsp), %rsp
 
 ; CHECK: movb {{.*}}, {{.*}}
 define void @mov1b(i8* %dst, i8* %src) #0 {
@@ -26,19 +26,19 @@ entry:
 }
 
 ; CHECK-LABEL: mov2b
-; CHECK: subq $128, %rsp
+; CHECK: leaq -128(%rsp), %rsp
 ; CHECK-NEXT: pushq %rdi
 ; CHECK-NEXT: leaq {{.*}}, %rdi
 ; CHECK-NEXT: callq __sanitizer_sanitize_load2@PLT
 ; CHECK-NEXT: popq %rdi
-; CHECK-NEXT: addq $128, %rsp
+; CHECK-NEXT: leaq 128(%rsp), %rsp
 
-; CHECK: subq $128, %rsp
+; CHECK: leaq -128(%rsp), %rsp
 ; CHECK-NEXT: pushq %rdi
 ; CHECK-NEXT: leaq {{.*}}, %rdi
 ; CHECK-NEXT: callq __sanitizer_sanitize_store2@PLT
 ; CHECK-NEXT: popq %rdi
-; CHECK-NEXT: addq $128, %rsp
+; CHECK-NEXT: leaq 128(%rsp), %rsp
 
 ; CHECK: movw {{.*}}, {{.*}}
 define void @mov2b(i16* %dst, i16* %src) #0 {
@@ -48,19 +48,19 @@ entry:
 }
 
 ; CHECK-LABEL: mov4b
-; CHECK: subq $128, %rsp
+; CHECK: leaq -128(%rsp), %rsp
 ; CHECK-NEXT: pushq %rdi
 ; CHECK-NEXT: leaq {{.*}}, %rdi
 ; CHECK-NEXT: callq __sanitizer_sanitize_load4@PLT
 ; CHECK-NEXT: popq %rdi
-; CHECK-NEXT: addq $128, %rsp
+; CHECK-NEXT: leaq 128(%rsp), %rsp
 
-; CHECK: subq $128, %rsp
+; CHECK: leaq -128(%rsp), %rsp
 ; CHECK-NEXT: pushq %rdi
 ; CHECK-NEXT: leaq {{.*}}, %rdi
 ; CHECK-NEXT: callq __sanitizer_sanitize_store4@PLT
 ; CHECK-NEXT: popq %rdi
-; CHECK-NEXT: addq $128, %rsp
+; CHECK-NEXT: leaq 128(%rsp), %rsp
 
 ; CHECK: movl {{.*}}, {{.*}}
 define void @mov4b(i32* %dst, i32* %src) #0 {
@@ -70,19 +70,19 @@ entry:
 }
 
 ; CHECK-LABEL: mov8b
-; CHECK: subq $128, %rsp
+; CHECK: leaq -128(%rsp), %rsp
 ; CHECK-NEXT: pushq %rdi
 ; CHECK-NEXT: leaq {{.*}}, %rdi
 ; CHECK-NEXT: callq __sanitizer_sanitize_load8@PLT
 ; CHECK-NEXT: popq %rdi
-; CHECK-NEXT: addq $128, %rsp
+; CHECK-NEXT: leaq 128(%rsp), %rsp
 
-; CHECK: subq $128, %rsp
+; CHECK: leaq -128(%rsp), %rsp
 ; CHECK-NEXT: pushq %rdi
 ; CHECK-NEXT: leaq {{.*}}, %rdi
 ; CHECK-NEXT: callq __sanitizer_sanitize_store8@PLT
 ; CHECK-NEXT: popq %rdi
-; CHECK-NEXT: addq $128, %rsp
+; CHECK-NEXT: leaq 128(%rsp), %rsp
 
 ; CHECK: movq {{.*}}, {{.*}}
 define void @mov8b(i64* %dst, i64* %src) #0 {
@@ -92,19 +92,19 @@ entry:
 }
 
 ; CHECK-LABEL: mov16b
-; CHECK: subq $128, %rsp
+; CHECK: leaq -128(%rsp), %rsp
 ; CHECK-NEXT: pushq %rdi
 ; CHECK-NEXT: leaq {{.*}}, %rdi
 ; CHECK-NEXT: callq __sanitizer_sanitize_load16@PLT
 ; CHECK-NEXT: popq %rdi
-; CHECK-NEXT: addq $128, %rsp
+; CHECK-NEXT: leaq 128(%rsp), %rsp
 
-; CHECK: subq $128, %rsp
+; CHECK: leaq -128(%rsp), %rsp
 ; CHECK-NEXT: pushq %rdi
 ; CHECK-NEXT: leaq {{.*}}, %rdi
 ; CHECK-NEXT: callq __sanitizer_sanitize_store16@PLT
 ; CHECK-NEXT: popq %rdi
-; CHECK-NEXT: addq $128, %rsp
+; CHECK-NEXT: leaq 128(%rsp), %rsp
 
 ; CHECK: movaps {{.*}}, {{.*}}
 define void @mov16b(<2 x i64>* %dst, <2 x i64>* %src) #0 {
index a12c6cc5c18fe1b5f4d7148232e9980a71c0fad0..df217c0f594d19911d158dd15344561e4fabed90 100644 (file)
@@ -6,21 +6,21 @@
        .type   mov1b,@function
 # CHECK-LABEL: mov1b:
 #
-# CHECK: subq $128, %rsp
+# CHECK: leaq -128(%rsp), %rsp
 # CHECK-NEXT: pushq %rdi
 # CHECK-NEXT: leaq (%rsi), %rdi
 # CHECK-NEXT: callq __sanitizer_sanitize_load1@PLT
 # CHECK-NEXT: popq %rdi
-# CHECK-NEXT: addq $128, %rsp
+# CHECK-NEXT: leaq 128(%rsp), %rsp
 #
 # CHECK-NEXT: movb (%rsi), %al
 #
-# CHECK-NEXT: subq $128, %rsp
+# CHECK-NEXT: leaq -128(%rsp), %rsp
 # CHECK-NEXT: pushq %rdi
 # CHECK-NEXT: leaq (%rdi), %rdi
 # CHECK-NEXT: callq __sanitizer_sanitize_store1@PLT
 # CHECK-NEXT: popq %rdi
-# CHECK-NEXT: addq $128, %rsp
+# CHECK-NEXT: leaq 128(%rsp), %rsp
 #
 # CHECK-NEXT: movb %al, (%rdi)
 mov1b:                                  # @mov1b
@@ -41,21 +41,21 @@ mov1b:                                  # @mov1b
        .type   mov16b,@function
 # CHECK-LABEL: mov16b:
 #
-# CHECK: subq $128, %rsp
+# CHECK: leaq -128(%rsp), %rsp
 # CHECK-NEXT: pushq %rdi
 # CHECK-NEXT: leaq (%rsi), %rdi
 # CHECK-NEXT: callq __sanitizer_sanitize_load16@PLT
 # CHECK-NEXT: popq %rdi
-# CHECK-NEXT: addq $128, %rsp
+# CHECK-NEXT: leaq 128(%rsp), %rsp
 #
 # CHECK-NEXT: movaps (%rsi), %xmm0
 #
-# CHECK-NEXT: subq $128, %rsp
+# CHECK-NEXT: leaq -128(%rsp), %rsp
 # CHECK-NEXT: pushq %rdi
 # CHECK-NEXT: leaq (%rdi), %rdi
 # CHECK-NEXT: callq __sanitizer_sanitize_store16@PLT
 # CHECK-NEXT: popq %rdi
-# CHECK-NEXT: addq $128, %rsp
+# CHECK-NEXT: leaq 128(%rsp), %rsp
 #
 # CHECK-NEXT: movaps %xmm0, (%rdi)
 mov16b:                                 # @mov16b
index b56224ce0d80c8d0591ae37fe2b4903d0738e358..8a6a8d5a740fb8713c50cd125c0c783b15d04c4f 100644 (file)
@@ -6,39 +6,39 @@
        .type   swap,@function
 # CHECK-LABEL: swap:
 #
-# CHECK: subq $128, %rsp
+# CHECK: leaq -128(%rsp), %rsp
 # CHECK-NEXT: pushq %rdi
 # CHECK-NEXT: leaq (%rcx), %rdi
 # CHECK-NEXT: callq __sanitizer_sanitize_load8@PLT
 # CHECK-NEXT: popq %rdi
-# CHECK-NEXT: addq $128, %rsp
+# CHECK-NEXT: leaq 128(%rsp), %rsp
 #
 # CHECK-NEXT: movq (%rcx), %rax
 #
-# CHECK-NEXT: subq $128, %rsp
+# CHECK-NEXT: leaq -128(%rsp), %rsp
 # CHECK-NEXT: pushq %rdi
 # CHECK-NEXT: leaq (%rdx), %rdi
 # CHECK-NEXT: callq __sanitizer_sanitize_load8@PLT
 # CHECK-NEXT: popq %rdi
-# CHECK-NEXT: addq $128, %rsp
+# CHECK-NEXT: leaq 128(%rsp), %rsp
 #
 # CHECK-NEXT: movq (%rdx), %rbx
 #
-# CHECK: subq $128, %rsp
+# CHECK: leaq -128(%rsp), %rsp
 # CHECK-NEXT: pushq %rdi
 # CHECK-NEXT: leaq (%rcx), %rdi
 # CHECK-NEXT: callq __sanitizer_sanitize_store8@PLT
 # CHECK-NEXT: popq %rdi
-# CHECK-NEXT: addq $128, %rsp
+# CHECK-NEXT: leaq 128(%rsp), %rsp
 #
 # CHECK-NEXT: movq %rbx, (%rcx)
 #
-# CHECK-NEXT: subq $128, %rsp
+# CHECK-NEXT: leaq -128(%rsp), %rsp
 # CHECK-NEXT: pushq %rdi
 # CHECK-NEXT: leaq (%rdx), %rdi
 # CHECK-NEXT: callq __sanitizer_sanitize_store8@PLT
 # CHECK-NEXT: popq %rdi
-# CHECK-NEXT: addq $128, %rsp
+# CHECK-NEXT: leaq 128(%rsp), %rsp
 #
 # CHECK-NEXT: movq %rax, (%rdx)
 swap:                                   # @swap