MaskRay wrote:

@uweigand 

Thanks for the analysis. `bot = alloca(i);` is a dynamic alloca that cannot be 
optimized out.
It triggers `FunctionStackPoisoner::createDynamicAllocasInitStorage`, which 
creates an alloca of 32-byte alignment.
In x86-64, aarch64, riscv, and others, the alloca translates to a `StackObject` 
of 32-byte alignment.
When `char array[len]` is not instrumented (due to StackSafetyAnalysis), only 
16-byte alignment is guaranteed, but it ends up being 32-byte aligned due to 
the frame layout.

On s390x, it seems that all `StackObject`s are just 4-byte or 8-byte aligned. 
Therefore, the first `char array[len]`, if not instrumented, is not 32-byte 
aligned.

I think the following patch should fix the failure on s390x.
Note: `char array[i]` in the loop is not instrumented due to the 
`isAllocaPromotable(&AI)` optimization (which I want to get rid of in #77221).
Whether `char array[i]` gets instrumented or not does not make the result 
different, but instrumenting it may make the test more intesting.
(Without the VLA `alloca(i)` returns a different address in each iteration).

```diff
--- i/compiler-rt/test/asan/TestCases/alloca_loop_unpoisoning.cpp
+++ w/compiler-rt/test/asan/TestCases/alloca_loop_unpoisoning.cpp
@@ -4,3 +4,2 @@
 // REQUIRES: stable-runtime
-// UNSUPPORTED: target=s390{{.*}}

@@ -28,2 +27,3 @@ __attribute__((noinline)) void foo(int len) {
   char array[len];
+  if (len) array[0] = 0;
   assert(!(reinterpret_cast<uintptr_t>(array) & 31L));
@@ -32,2 +32,3 @@ __attribute__((noinline)) void foo(int len) {
     char array[i];
+    if (i) array[0] = 0;
     bot = alloca(i);
```


https://github.com/llvm/llvm-project/pull/77210
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to