This commit allows `-mstack-protector-guard=global` for `s390x`. It also adds a new arch-specific option `-mstack-protector-guard-record`, analogous to `-mrecord-mcount`, which will cause `clang` to emit a `__stack_protector_loc` section containing all the locations in the output binary that load the stack guard address, for the purposes of later rewriting of those loads by the kernel. This new option only works together with the `global` stack protector. In order to minimize exposure of the stack guard, both the storing of the stack guard onto the stack, and the later comparison of that value against the reference value, are handled via direct mem-to-mem instructions, those being `mvc` and `clc`. This is achieved by introducing two new pseudo instructions, `MOVE_STACK_GUARD` and `COMPARE_STACK_GUARD`, which are inserted by the DAGCombiner after SelectionDAG construction. These pseudos stick around throughout the entire backend pipeline, and are lowered only in the AsmPrinter. This commit also adds tests for both kinds of stack protectors (tls and global), for the proper insertion of the pseudos, the proper emission of the, `__stack_protector_loc` section, as well as the option compatibility checks for the new options.
24 lines
1.2 KiB
LLVM
24 lines
1.2 KiB
LLVM
; RUN: llc -stop-after=systemz-isel -mtriple=s390x-ibm-linux < %s -o - | FileCheck -check-prefix=CHECK-DAGCOMBINE %s
|
|
; RUN: llc -stop-after=finalize-isel -mtriple=s390x-ibm-linux < %s -o - | FileCheck -check-prefix=CHECK-CUSTOMINSERT %s
|
|
; CHECK-DAGCOMBINE: bb.0.entry:
|
|
; CHECK-DAGCOMBINE: MOV_STACKGUARD_DAG %stack.0.StackGuardSlot, 0
|
|
; CHECK-DAGCOMBINE: CMP_STACKGUARD_DAG %stack.0.StackGuardSlot, 0, implicit-def $cc
|
|
; CHECK-CUSTOMINSERT: bb.0.entry
|
|
; CHECK-CUSTOMINSERT: early-clobber %6:addr64bit = MOV_STACKGUARD %stack.0.StackGuardSlot, 0
|
|
; CHECK_CUSTOMINSERT: bb.3.entry
|
|
; CHECK-CUSTOMINSERT: early-clobber %10:addr64bit = CMP_STACKGUARD %stack.0.StackGuardSlot, 0, implicit-def $cc
|
|
|
|
define dso_local signext i32 @stack_guard_pseudo_check(i32 %argc, ptr %argv) #0 {
|
|
entry:
|
|
%Buffer = alloca [8 x i8], align 1
|
|
call void @llvm.memset.p0.i64(ptr align 1 %Buffer, i8 0, i64 8, i1 false)
|
|
%arraydecay = getelementptr inbounds [8 x i8], ptr %Buffer, i64 0, i64 0
|
|
%call = call ptr @strcpy(ptr noundef %arraydecay, ptr noundef %argv)
|
|
ret i32 0
|
|
}
|
|
|
|
declare void @llvm.memset.p0.i64(ptr writeonly captures(none), i8, i64, i1 immarg)
|
|
declare ptr @strcpy(ptr noundef, ptr noundef)
|
|
|
|
attributes #0 = { ssp }
|