1; RUN: opt -safe-stack -S -mtriple=i386-pc-linux-gnu < %s -o - | FileCheck %s 2; RUN: opt -safe-stack -S -mtriple=x86_64-pc-linux-gnu < %s -o - | FileCheck %s 3 4; array [4 x i8] 5; Requires protector. 6 7; CHECK: @__safestack_unsafe_stack_ptr = external thread_local(initialexec) global ptr 8 9define void @foo(ptr %a) nounwind uwtable safestack { 10entry: 11 ; CHECK: %[[USP:.*]] = load ptr, ptr @__safestack_unsafe_stack_ptr 12 13 ; CHECK: %[[USST:.*]] = getelementptr i8, ptr %[[USP]], i32 -16 14 15 ; CHECK: store ptr %[[USST]], ptr @__safestack_unsafe_stack_ptr 16 17 %a.addr = alloca ptr, align 8 18 %buf = alloca [4 x i8], align 1 19 20 ; CHECK: %[[AADDR:.*]] = alloca ptr, align 8 21 ; CHECK: store ptr {{.*}}, ptr %[[AADDR]], align 8 22 store ptr %a, ptr %a.addr, align 8 23 24 ; CHECK: %[[A2:.*]] = load ptr, ptr %[[AADDR]], align 8 25 ; CHECK: %[[BUFPTR:.*]] = getelementptr i8, ptr %[[USP]], i32 -4 26 %a2 = load ptr, ptr %a.addr, align 8 27 28 ; CHECK: call ptr @strcpy(ptr %[[BUFPTR]], ptr %[[A2]]) 29 %call = call ptr @strcpy(ptr %buf, ptr %a2) 30 31 ; CHECK: store ptr %[[USP]], ptr @__safestack_unsafe_stack_ptr 32 ret void 33} 34 35; Load from an array at a fixed offset, no overflow. 36define i8 @StaticArrayFixedSafe() nounwind uwtable safestack { 37entry: 38 ; CHECK-LABEL: define i8 @StaticArrayFixedSafe( 39 ; CHECK-NOT: __safestack_unsafe_stack_ptr 40 ; CHECK: ret i8 41 %buf = alloca i8, i32 4, align 1 42 %gep = getelementptr inbounds i8, ptr %buf, i32 2 43 %x = load i8, ptr %gep, align 1 44 ret i8 %x 45} 46 47; Load from an array at a fixed offset with overflow. 48define i8 @StaticArrayFixedUnsafe() nounwind uwtable safestack { 49entry: 50 ; CHECK-LABEL: define i8 @StaticArrayFixedUnsafe( 51 ; CHECK: __safestack_unsafe_stack_ptr 52 ; CHECK: ret i8 53 %buf = alloca i8, i32 4, align 1 54 %gep = getelementptr inbounds i8, ptr %buf, i32 5 55 %x = load i8, ptr %gep, align 1 56 ret i8 %x 57} 58 59; Load from an array at an unknown offset. 60define i8 @StaticArrayVariableUnsafe(i32 %ofs) nounwind uwtable safestack { 61entry: 62 ; CHECK-LABEL: define i8 @StaticArrayVariableUnsafe( 63 ; CHECK: __safestack_unsafe_stack_ptr 64 ; CHECK: ret i8 65 %buf = alloca i8, i32 4, align 1 66 %gep = getelementptr inbounds i8, ptr %buf, i32 %ofs 67 %x = load i8, ptr %gep, align 1 68 ret i8 %x 69} 70 71; Load from an array of an unknown size. 72define i8 @DynamicArrayUnsafe(i32 %sz) nounwind uwtable safestack { 73entry: 74 ; CHECK-LABEL: define i8 @DynamicArrayUnsafe( 75 ; CHECK: __safestack_unsafe_stack_ptr 76 ; CHECK: ret i8 77 %buf = alloca i8, i32 %sz, align 1 78 %gep = getelementptr inbounds i8, ptr %buf, i32 2 79 %x = load i8, ptr %gep, align 1 80 ret i8 %x 81} 82 83declare ptr @strcpy(ptr, ptr) 84