================
@@ -0,0 +1,190 @@
+; Test the stack protector under XPLINK on z/OS
+;
+; RUN: llc < %s -mtriple=s390x-ibm-zos -mcpu=z13 | FileCheck 
--check-prefixes=CHECK %s
+
+; Test stack protector for non-XPLEAF.
+
+; Small stack frame.
+; CHECK-LABEL: func0
+; CHECK:                    * DSA Size [[#%#x,DSA_SIZE:]]
+; CHECK:                    aghi  4,-[[#%u,mul(div(DSA_SIZE,32),32)]]
+; CHECK:                    llgt  [[REG1:[0-9]+]],1208
+; CHECK:                    mvc   
[[#%u,2040+mul(div(DSA_SIZE,32),32)]](8,4),152([[REG1]])
+; ...
+; CHECK:                    llgt  [[REG3:[0-9]+]],1208
+; CHECK:                    clc   
[[#%u,2040+mul(div(DSA_SIZE,32),32)]](8,4),152([[REG3]])
+; CHECK:                    jlh   [[FAIL_LABEL:L#BB[0-9_]+]]
+; success block
+; CHECK:                    aghi  4,[[#%u,mul(div(DSA_SIZE,32),32)]]
+; CHECK:                    b     2(7)
+; failure block
+; CHECK:                    [[FAIL_LABEL]] DS 0H
+; invoke __stack_chk_fail
+; CHECK:                    lg    6,[[#CHK_FAIL_OFF:]]({{[0-9]+}})
+; CHECK:                    lg    5,[[#CHK_FAIL_OFF-8]]({{[0-9]+}})
+; CHECK:                    basr  7,6
+; CHECK-NEXT:               bcr   0,0
+
+define void @func0() sspreq {
+  call i64 (i64) @fun(i64 10)
+  ret void
+}
+
+; Large stack frame.
+; Larger than 1M in XPLINK64.
+; CHECK-LABEL: func1
+; CHECK:                    * DSA Size [[#%#x,DSA_SIZE:]]
+; CHECK:                    stmg  6,{{[0-9]+}},2064(4)
+; CHECK:                    llilh 
[[REG_CANARY_OFF_HIGH:[0-9]+]],[[#%u,CANARY_OFF_HIGH:div(DSA_SIZE,65536)]]
+; CHECK:                    la    
[[REG_CANARY_OFF_HIGH]],0([[REG_CANARY_OFF_HIGH]],4)
+; CHECK:                    llgt  [[REG1:[0-9]+]],1208
+; CHECK:                    mvc   
[[#%u,2040+mul(div(DSA_SIZE,32),32)-mul(CANARY_OFF_HIGH,65536)]](8,[[REG_CANARY_OFF_HIGH]]),152([[REG1]])
+; ...
+; CHECK:                    llilh 
[[REG_CANARY_OFF_HIGH_2:[0-9]+]],[[#%u,CANARY_OFF_HIGH_2:div(DSA_SIZE,65536)]]
+; CHECK:                    la    
[[REG_CANARY_OFF_HIGH_2]],0([[REG_CANARY_OFF_HIGH_2]],4)
+; CHECK:                    llgt  [[REG3:[0-9]+]],1208
+; CHECK:                    clc   
[[#%u,2040+mul(div(DSA_SIZE,32),32)-mul(CANARY_OFF_HIGH_2,65536)]](8,[[REG_CANARY_OFF_HIGH_2]]),152([[REG3]])
+; CHECK:                    jlh   [[FAIL_LABEL:L#BB[0-9_]+]]
+; success block
+; CHECK:                    agfi  4,[[#%u,mul(div(DSA_SIZE,32),32)]]
+; CHECK:                    b     2(7)
+; failure block
+; CHECK:                    [[FAIL_LABEL]] DS 0H
+; invoke __stack_chk_fail
+; CHECK:                    lg    6,[[#CHK_FAIL_OFF:]]({{[0-9]+}})
+; CHECK:                    lg    5,[[#CHK_FAIL_OFF-8]]({{[0-9]+}})
+; CHECK:                    basr  7,6
+; CHECK-NEXT:               bcr   0,0
+
+define void @func1() sspreq {
+  %arr = alloca [131072 x i64], align 8
+  call i64 (ptr) @fun1(ptr %arr)
+  ret void
+}
+
+; Test converting XPLeaf functions to non-leaf functions if they need stack 
protection
+
+; TODO: Currently any function that needs to store data on the stack is
+; converted to a non-leaf function, so XPLeaf functions never write to the
+; stack, and thus there is no way for them to cause stack corruption.
+;
+; Eventually we'll start taking advantage of the 2048 bytes of space between R4
+; and the caller's stack frame to eliminate the need to convert some functions
+; that would have been XPLeaf functions. At which point, it will be possible 
for
+; an XPLeaf function to corrupt the stack.
+;
+; Since stack protection protects against corruption of the caller's stack
+; frame and not corruption of the callee's stack frame, it doesn't matter that
+; XPLeaf functions don't have a stack frame of their own - that's not what we'd
+; be protecting anyways.
+;
+; Thus, we'll have to choose what to do with functions that need stack 
protection
+; but could remain as XPLeaf functions by using those 2048 bytes of space.
+; We have 3 options:
+; 1. Convert them to non-leaf functions and continue protecting them as before.
+; 2. Keep them as XPLeaf functions, but give up on stack protecting them
+; 3. Keep them as XPLeaf functions, and try to stack protect them without 
making
+;    any function calls in the failure case. This would probably involve
+;    delaying the invocation of __stack_chk_fail/__CEL4SFCR until we return to
+;    the caller.
+;
+; If we choose option 1, leave this test as is and remove this TODO.
+; If we choose option 2, make sure we don't try to stack protect these 
functions.
+; If we choose option 3, this test needs to be replaced, but what we replace it
+; with will depend on how we implement the failure case.
----------------
uweigand wrote:

This is a good comment, but it would be better visible in the *code* (at the 
point where we currently make the decision to convert a function to non-leaf), 
rather than just in a test case.

https://github.com/llvm/llvm-project/pull/206045
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to